I am trying to create a customized function that uses ggplot facet_wrap, in which the user can optionally provide labels. I've wrapped the facet_grid argument in an if/else clause depending on whether or not the user provides labels, and the function runs successfully. However, it only works if this clause is the final call in the ggplot sequence; if I add anything else after it (e.g. specifying the theme), it breaks. Obviously I can reorder the function to leave the facet_wrap call at the end, but I suspect this means I'm doing something incorrectly.
Here is a reproducible example:
library(dplyr)
library(ggplot2)
# sample data
data(msleep)
filtered<- msleep %>% filter(conservation %in% c('en', 'vu', 'domesticated'))
# readable labels
fancy_labels_cons <- c('domesticated' = 'Domesticated', 'en' = 'Endangered', 'vu' = 'Vulnerable')
fancy_labels_vore <- c('carni' = 'Carnivore', 'herbi'='Herbivore', 'omni'='Omnivore', 'insecti'='Insectivore')
# function: works as long as if/else clause is the final argument
myfunc_workingversion <- function(df, x, y, facetx, facety, labs=NULL) {
ggplot(df, aes({{x}}, {{y}})) +
geom_point() +
if(!is.null(labs)) {
facet_grid(vars({{facetx}}), vars({{facety}}),
labeller = as_labeller(labs))
} else {
facet_grid(vars({{facetx}}), vars({{facety}}))
}
}
#function: no longer works when an additional ggplot argument is added at the end
myfunc2 <- function(df, x, y, facetx, facety, labs=NULL) {
ggplot(df, aes({{x}}, {{y}})) +
geom_point() +
if(!is.null(labs)) {
facet_grid(vars({{facetx}}), vars({{facety}}),
labeller = as_labeller(labs))
} else {
facet_grid(vars({{facetx}}), vars({{facety}}))
} +
theme_minimal()
}
#run function - this works
myfunc2(
filtered,
x=sleep_total,
y=awake,
facetx=conservation,
facety=vore,
labs=c('domesticated' = 'Domesticated', 'en' = 'Endangered',
'vu' = 'Vulnerable', 'carni' = 'Carnivore', 'herbi'='Herbivore',
'omni'='Omnivore', 'insecti'='Insectivore'))
#run function - this doesn't work
myfunc2(
filtered,
x=sleep_total,
y=awake,
facetx=conservation,
facety=vore
)
Note that both versions of the functions work if labs are provided; however, the second version breaks if labs are not provided. I suspect I'm doing something wrong with the "+". I'm also interested in learning if there's a more optimized or readable way of setting up the optional input here.
ggplotout of it entirely,1 + if(TRUE) {1} else {1} + 1gives 2, not 3, which suggests that there is a fundamental syntax issue.1 + {if(TRUE) {1} else {1}} + 1does work, so you can probably fix your mid-statement conditional by wrapping the entire thing in brackets, from before theifto after the close of theelse{}.NULL(instead of usingmissing()) is all over modern packages, including manytidyversefunctions (example). Hadley writes that he feels this makes it more clear which arguments are required.