Reputation: 7725
How can I turn this ggplot()
call into a function? I can't figure out how to get R to recognize the column names I want to pass to the function. I've come across several similar sounding questions, but I've not had success adapting ideas. See here for substitute()
.
# setup
library(dplyr)
library(ggplot2)
set.seed(205)
dat = data.frame(t=rep(1:2, each=10),
pairs=rep(1:10,2),
value=rnorm(20))
# working example
ggplot(dat %>% group_by(pairs) %>%
mutate(slope = (value[t==2] - value[t==1])/(2-1)),
aes(t, value, group=pairs, colour=slope > 0)) +
geom_point() +
geom_line() +
stat_summary(fun.y=mean,geom="line",lwd=2,aes(group=1))
# attempt at turning into a function
plotFun <- function(df, groupBy, dv, time) {
groupBy2 <- substitute(groupBy)
dv2 <- substitute(dv)
time2 <- substitute(time)
ggplot(df %>% group_by(groupBy2) %>%
mutate(slope = (dv2[time2==2] - dv2[time2==1])/(2-1)),
aes(time2, dv2, group=groupBy2, colour=slope > 0)) +
geom_point() +
geom_line() +
stat_summary(fun.y=mean,geom="line",lwd=2,aes(group=1))
}
# error time
plotFun(dat, pairs, value, t)
Update
I took @joran's advice to look at this answer, and here's what I came up with:
library(dplyr)
library(ggplot2)
library(lazyeval)
plotFun <- function(df, groupBy, dv, time) {
ggplot(df %>% group_by_(groupBy) %>%
mutate_(slope = interp(~(dv2[time2==2] - dv2[time2==1])/(2-1),
dv2=as.name(dv),
time2=as.name(time))),
aes(time, dv, group=groupBy, colour=slope > 0)) +
geom_point() +
geom_line() +
stat_summary(fun.y=mean,geom="line",lwd=2,aes(group=1))
}
plotFun(dat, "pairs", "value", "t")
The code runs but the plot is not correct:
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
Upvotes: 2
Views: 433
Reputation: 7725
Here's the working solution informed by all of the commenters:
# setup
library(dplyr)
library(ggplot2)
library(lazyeval)
set.seed(205)
dat = data.frame(t=rep(1:2, each=10),
pairs=rep(1:10,2),
value=rnorm(20))
# function
plotFun <- function(df, groupBy, dv, time) {
ggplot(df %>% group_by_(groupBy) %>%
mutate_(slope = interp(~(dv2[time2==2] - dv2[time2==1])/(2-1),
dv2=as.name(dv),
time2=as.name(time))),
aes_string(time, dv, group = groupBy,
colour = 'slope > 0')) +
geom_point() +
geom_line() +
stat_summary(fun.y=mean,geom="line",lwd=2,aes(group=1))
}
# plot
plotFun(dat, "pairs", "value", "t")
Upvotes: 2