Home > Enterprise >  Pass arbitrary number of variables into facet_grid()
Pass arbitrary number of variables into facet_grid()

Time:07-16

I'm trying to develop a function that will create a plot from just a few arguments. I need it to be flexible, so that I can input an unknown number of variables to facet the graph by. I've used all the quoting/unquoting methods I can find: {{ }}, .data[], !!!, inject, and more. I think part of the problem is that facet_grid calls it's variables within vars(), which is not cooperating with these operators. I have also tried passing the variables that I want to facet by into the function using dots, and by a named argument that takes a vector.

It seems to me that the best option here, based on this article (https://adv-r.hadley.nz/quasiquotation.html) is the unquote-splice operator. It seems to me like one of these should work, but neither does:

make_graph <- function (factor.by){
  ggplot(mpg, aes(cyl, cty))   
    geom_col()   
    facet_grid(cols = vars(!!!factor.by))
}


make_graph(factor.by = c("manufacturer", "model"))


make_graph_2 <- function (...){
  ggplot(mpg, aes(cyl, cty))   
    geom_col()   
    facet_grid(cols = vars(...))
}

make_graph_2("manufactuer", "model")

I would really appreciate any help figuring out how to make this work! I'm pretty new to programming with R, and I've been stuck on this issue for a long time. Thank you so much!

CodePudding user response:

Some options:

  1. Ellipses:

    make_graph <- function(...) {
     ggplot(mpg, aes(cyl, cty))   
        geom_col()   
        facet_grid(cols = vars(...))
    }
    make_graph(manufacturer, model)
    
  2. Programmatic formula:

    make_graph <- function(factor.by) {
     ggplot(mpg, aes(cyl, cty))   
        geom_col()   
        facet_grid(rows = as.formula(paste0(". ~ ", paste(factor.by, collapse = " "))))
    }
    make_graph(factor.by = c("manufacturer", "model"))
    
  3. Using ensyms (thank you @stefan!), for a variadic function:

    make_graph <- function(...) {
     ggplot(mpg, aes(cyl, cty))   
        geom_col()   
        facet_grid(cols = vars(!!!rlang::ensyms(...)))
    }
    make_graph("manufacturer", "model")
    
  4. Using syms for a single-argument function:

    make_graph <- function(factor.by) {
     ggplot(mpg, aes(cyl, cty))   
        geom_col()   
        facet_grid(cols = vars(!!!rlang::syms(factor.by)))
    }
    make_graph(c("manufacturer", "model"))
    
  • Related