Search code examples
rstringggplot2facetfacet-grid

Why passing a string in R ggplot2::facet_grid() works for rows but not for columns?


Here are some workarounds for the issue, but is there a reason why you can pass a string for rows in the ggplot2::facet_grid() but not for cols?

This works (notice the rows attribute):

f_varname <- 'drv'

ggplot( mpg, aes( displ, cty ) ) + geom_point() +

    facet_grid( rows = f_varname )

But this does not (notice the cols attribute):

f_varname <- 'drv'

ggplot( mpg, aes( displ, cty ) ) + geom_point() +

    facet_grid( cols = f_varname )

# => Error: `cols` must be `NULL` or a `vars()` specification

Instead, you have to use the vars() specification for the cols:

ggplot( mpg, aes( displ, cty ) ) + geom_point() +
    
    facet_grid( cols = vars( drv ) )

which can not handle a string:

f_varname <- 'drv'

ggplot( mpg, aes( displ, cty ) ) + geom_point() +
    
    facet_grid( cols = vars( f_varname ) )

# =>
# Error: At least one layer must contain all faceting variables: `f_varname`.
# * Plot is missing `f_varname`
# * Layer 1 is missing `f_varname`

From the linked discussion, this answer also works with the string:

f_varname <- 'drv'

ggplot( mpg, aes( displ, cty ) ) + geom_point() +
    
    facet_grid( reformulate( f_varname ) )

Solution

  • I think @Limey's explanation in the comments is the answer to your question, but if you're looking for a practical solution (outside of those you've linked) you can turn the string into a symbol (using sym()) then pass it to vars with the bang-bang operator, e.g.

    library(tidyverse)
    f_varname <- sym("cyl")
    ggplot(mpg, aes(displ, cty)) +
      geom_point() +
      facet_grid(cols = vars(!!f_varname))