使用可选的构面图参数编写自定义 ggplot 函数

问题描述 投票:0回答:1

我正在尝试创建一个使用 ggplot facet_wrap 的自定义函数,用户可以选择在其中提供标签。我根据用户是否提供标签将 facet_grid 参数包装在 if/else 子句中,并且该函数成功运行。但是,只有当该子句是 ggplot 序列中的最终调用时,它才有效;如果我在它后面添加任何其他内容(例如指定主题),它就会崩溃。显然我可以重新排序函数以将facet_wrap调用留在最后,但我怀疑这意味着我做错了一些事情。

这是一个可重现的示例:

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
)

请注意,如果提供实验室,这两个版本的函数都可以工作;但是,如果不提供实验室,第二个版本就会中断。我怀疑我在“+”上做错了什么。我也有兴趣了解是否有更优化或可读的方式来设置此处的可选输入。

r ggplot2 optional-parameters facet-grid
1个回答
0
投票

您遇到解析问题。 if/else 语法需要 iftrue/ifelse 块的表达式。

{}
并不是真正必需的,并且不决定块的扩展。你所拥有的被解释为

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()}
}

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()
}

要得到你想要的,请将 if 块用大括号括起来

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()
}
© www.soinside.com 2019 - 2024. All rights reserved.