Search code examples
rggplot2parameter-passingfacetfacet-wrap

Conditional facet specification with ggplot2


I am making several plots, which for flexibility I am planning to wrap in functions, and as part of that I would like to specify faceting for those plots according to some condition.

Specifically, I have a list of grouping_vars (per-specified elsewhere) that I use to perform several other manipulations on the data. I'd like to have my plotting functions be able to automatically use a facet_wrap if there's only one grouping_var, or if there are two or more variables specified in grouping_var, use the first two for facet_grid.

So for instance, if the basic plot is something like

mtcars %>% ggplot() + geom_point(aes(x = hp, y = mpg))

If I specify grouping_vars <- c("cyl"), I'd like to get, in effect,

mtcars %>% ggplot() + 
    geom_point(aes(x = hp, y = mpg)) +
    facet_wrap(~cyl)

Whereas if I specify grouping_vars <- c("cyl", "carb") I'd like to get

mtcars %>% ggplot() + 
    geom_point(aes(x = hp, y = mpg)) +
    facet_grid(vars(cyl), vars(carb))

Based on some other answers I've tried doing this:

mtcars %>% ggplot() + 
    geom_point(aes(x = hp, y = mpg)) +
    {if(length(grouping_vars==1)) facet_wrap(grouping_vars[[1]])} +
    {if(length(grouping_vars>=2)) facet_grid(vars(grouping_vars[[1]]), vars(grouping_vars[[2]]))}

but it doesn't seem to work. Among other things, if there's only one element in grouping_vars, it gives me Error in grouping_vars[[2]] : subscript out of bounds.

Is there a way to conditionally specify faceting like this?


Solution

  • Following the advice in the vignette here, we should be able to use vars() with the .data pronoun as follows:

    library(ggplot2)
    
    plot_mtcars <- function(grouping_vars = NULL) {
      p <- ggplot(mtcars) +
        geom_point(aes(x = hp, y = mpg))
      
      if (length(grouping_vars) == 1) {
    
        p <- p + facet_wrap(vars(.data[[grouping_vars]]))
    
      } else if (length(grouping_vars) == 2) {
    
        p <- p + facet_grid(vars(.data[[grouping_vars[1]]]), 
                            vars(.data[[grouping_vars[2]]]))
    
      }
      p
    }
    
    plot_mtcars("cyl")
    

    plot_mtcars(c("cyl", "vs"))
    

    Created on 2023-03-14 by the reprex package (v2.0.0)