Estou tentando criar uma função personalizada que usa ggplot facet_wrap, na qual o usuário pode opcionalmente fornecer rótulos. Encapsulei o argumento facet_grid em uma cláusula if/else dependendo se o usuário fornece ou não rótulos, e a função é executada com sucesso. No entanto, ela só funciona se essa cláusula for a chamada final na sequência ggplot; se eu adicionar qualquer outra coisa depois dela (por exemplo, especificando o tema), ela quebra. Obviamente, posso reordenar a função para deixar a chamada facet_wrap no final, mas suspeito que isso significa que estou fazendo algo incorretamente.
Aqui está um exemplo reproduzível:
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 que ambas as versões das funções funcionam se os laboratórios forem fornecidos; no entanto, a segunda versão quebra se os laboratórios não forem fornecidos. Suspeito que estou fazendo algo errado com o "+". Também estou interessado em saber se há uma maneira mais otimizada ou legível de configurar a entrada opcional aqui.
Você tem um problema de análise. A sintaxe if/else espera expressões para o bloco iftrue/ifelse. Elas
{}
não são realmente necessárias e não determinam as expansões dos blocos. O que você tem está sendo interpretado comoou
E o problema é
facet_grid(vars({{facetx}}), vars({{facety}})) + theme_minimal()
que não é uma expressão válida por si só.Para obter o que deseja, envolva o bloco if entre chaves
um pouco mais fácil de ler seria: