I'm trying to write a function where one of the arguments is the variable by which to facet wrap.
Minimum reproducible example:
library(tidyverse)
library(ggplot2)
wobble<- matrix(1:9, 3) %>% as_tibble()
wibble_fun <- function(df, var) {
df %>%
ggplot(aes(var)) +
geom_bar() +
facet_wrap(~var)
}
wibble_fun(wobble, "V1")
The resulting error:
Error: At least one layer must contain all faceting variables: `var`.
* Plot is missing `var`
* Layer 1 is missing `
Seems like var
in facet_wrap(~var)
is interpreted as the string 'var' instead of being substituted by "V1", which is the second argument when I call the function.
Is there a way to make this work?
Here's a solution using {{...}}
around the variable within the function instead of using sym
and unqoting:
library(tidyverse)
library(ggplot2)
wobble<- matrix(1:9, 3) %>% as_tibble()
wibble_fun <- function(df, var) {
df %>%
ggplot(aes({{var}})) +
geom_bar() +
facet_wrap(vars({{var}}))
}
wibble_fun(wobble, V1)
I think an easy fix to your problem would be using [[
to pass the column var
into your function:
wibble_fun <- function(df, var) {
df %>%
ggplot(aes(df[[var]])) +
geom_bar() +
facet_wrap(~df[[var]])
}
wibble_fun(wobble, "V1")
A different way to do this makes use of Non-Standard Evaluation which, while confusing, is the "official" way to do things like this in the tidyverse
.
We use the sym
function to convert var
from a string into a symbol
, then unquote it with !!
in the aes
.
For the facet_wrap
: as marius pointed out in the comments, facet_wrap
can accept a string or symbol instead of a formula (made with ~
). You can either pass in your symbol x
or the string var
itself: you'll get the same results.
library(tidyverse)
library(ggplot2)
wobble<- matrix(1:9, 3) %>% as_tibble()
wibble_fun <- function(df, var) {
x = sym(var)
df %>%
ggplot(aes(!!x)) +
geom_bar() +
facet_wrap(x)
}
wibble_fun(wobble, "V1")
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