Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass string to facet_grid : ggplot2

Tags:

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') 
like image 821
Tyler Rinker Avatar asked Feb 05 '14 20:02

Tyler Rinker


2 Answers

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') 

enter image description here

like image 66
Josh O'Brien Avatar answered Sep 20 '22 15:09

Josh O'Brien


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.

like image 38
Moody_Mudskipper Avatar answered Sep 20 '22 15:09

Moody_Mudskipper