I want to create a plotting function where I specify the data set, and specify the plotting arguments as function arguments in similar fashion as I can within ggplot2
, i.e. where we specify the variable name without the dataset, e.g. hp
instead of mtcars$hp
.
For example:
ggfun <- function(dat, x.var, y.var){
ggp <- ggplot(data = dat,
aes(x = x.var,
y = y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = drat, y.var = hp)
Would return:
However it returns:
> ggfun(dat = mtcars, x.var = drat, y.var = hp)
Error in eval(expr, envir, enclos) : object 'drat' not found
In addition: Warning message:
In eval(expr, envir, enclos) : restarting interrupted promise evaluation
I know using aes_string
instead of aes
works, e.g.:
ggfun <- function(dat, x.var, y.var){
ggp <- ggplot(data = dat,
aes_string(x = x.var,
y = y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
But I'd prefer to avoid using string form.
Other attempts include ggfun(dat = mtcars, x.var = mtcars$drat, y.var = mtcars$hp)
, which returns the right graph but partially defeats the purpose of the exercise, and produces lables "x.var" and "y.var" instead of "drat" and "hp".
Any known and reasonably simple way around this?
With the devel version of ggplot2
, we can pass unquoted arguments, convert it to quosure
(with enquo
) and evaluate it (!!
)
ggfun <- function(dat, x.var, y.var){
x.var <- enquo(x.var)
y.var <- enquo(y.var)
ggp <- ggplot(data = dat,
aes(x = !! x.var,
y = !! y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = drat, y.var = hp)
For quoted strings, convert it to symbol with sym
(from rlang
) and do the evaluation
ggfun <- function(dat, x.var, y.var){
x.var <- rlang::sym(x.var)
y.var <- rlang::sym(y.var)
ggp <- ggplot(data = dat,
aes(x = !! x.var,
y = !! y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
If we want to pass either quoted or unquoted, the quosure is changed to character (quo_name
), then to symbol (sym
) and evaluate (!!
)
ggfun <- function(dat, x.var, y.var){
x.var <- rlang::sym(quo_name(enquo(x.var)))
y.var <- rlang::sym(quo_name(enquo(y.var)))
ggp <- ggplot(data = dat,
aes(x = !! x.var,
y = !! y.var)) +
geom_point()
return(ggp)
}
p1 <- ggfun(dat = mtcars, x.var = drat, y.var = hp)
p2 <- ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
all.equal(p1, p2)
#[1] TRUE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With