In ggplot2 you can pass character arguments inside a user defined function using aes_string
. How can you do the same for facet grid which takes a formula, not aes
?
FUN <- function(data, x, y, fac1, fac2) { ggplot(data = data, aes_string(x=x, y=y)) + geom_point() + facet_grid(as.formula(substitute(fac1 ~ fac2))) } FUN(mtcars, 'hp', 'mpg', 'cyl', 'am')
reformulate()
seems to work just fine.
FUN <- function(data, x, y, fac1, fac2) { ggplot(data = data, aes_string(x=x, y=y)) + geom_point() + facet_grid(reformulate(fac2,fac1)) } FUN(mtcars, 'hp', 'mpg', 'cyl', 'am')
With rlang
magic and new ggplot2 v3.0.0
features you can do :
FUN <- function(data, x, y, fac1, fac2) { ggplot(data = data, aes(x = !!ensym(x), y = !!ensym(y))) + geom_point() + facet_grid(eval(expr(!!ensym(fac1) ~ !!ensym(fac2)))) } FUN(mtcars, 'hp', 'mpg', 'cyl', 'am')
Note that we don't use aes_string
, which is soft deprecated.
Personally in these cases I like to use a function I called glue_formula
(referencing package glue
) :
glue_formula <- function(.formula, .envir = parent.frame(), ...){ formula_chr <- gsub("\\n\\s*","",as.character(.formula)[c(2,1,3)]) args <- c(as.list(formula_chr), .sep=" ", .envir = .envir) as.formula(do.call(glue::glue, args),env = .envir) } FUN2 <- function(data, x, y, fac1, fac2) { ggplot(data = data, aes(x = !!ensym(x), y = !!ensym(y))) + geom_point() + facet_grid(glue_formula({fac1} ~ {fac2})) } FUN2(mtcars, 'hp', 'mpg', 'cyl', 'am')
It's not tidyverse approved (see interesting discussion here) but it has served me well.
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