R ggplot2 facet_grid with vars(): 如何处理丢失的参数?

R ggplot2 facet_grid with vars(): how to handle missing argument?

我想对 ggplot facet_grid 使用整洁的计算,但不知道如何允许缺少参数?

ggplot2 3.0.0引入函数vars()(见news),使用tidy 例如 facet_grid 中的评估。但我不清楚如何处理 missing/NULL 个参数?

在下面的代码中,我该怎么做才能不向 wrap_by 传递任何参数(即使用 p + wrap_by())而不 return 错误?

library(ggplot2)
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang
p <- ggplot(mtcars, aes(wt, disp)) + geom_point()
wrap_by <- function(...) {
  facet_wrap(vars(...), labeller = label_both)
}
p + wrap_by() #ERROR!
#> Can't subset with `[` using an object of class NULL.

用例:我想要一个函数来定义方面变量,但想让它们成为可选的。

fac_by <- function(var_fac1, var_fac2) {
  facet_grid(rows=vars(!!enquo(var_fac1)), 
             cols=vars(!!enquo(var_fac2)))
}

p+ fac_by(vs, am)
p+ fac_by(var_fac1=vs) # won't work

这里的问题是,理想情况下我会允许任一行,任一列,两者都允许(理想情况下 none 也是如此,尽管 facet_grid(NULL, NULL) 似乎不可能)

根据 facet_grid 的更新代码,一个选项是传递一个表达式

library(rlang)
library(ggplot2)
fac_by <- function(...) {
   e1 <- enexprs(...)   
   do.call(facet_grid, e1)

  }

p + fac_by(rows = vars(vs), cols = vars(am))

p + fac_by(rows = vars(vs))

p + fac_by(cols = vars(am))

你可以这样做:

fac_by <- function(var_fac1, var_fac2) {
  # retrieve the arguments from the call
  args_ <- rlang::call_args(match.call())
  # rename them (use na.omit on top of it if you have more arguments)
  names(args_) <- c(var_fac1 = "rows", var_fac2 = "cols")[names(args_)]
  # apply vars on them
  args_ <- purrr::map(args_, vars)
  # build the call
  call_ <- as.call(c(quote(facet_grid),args_))
  eval(call_)
}

p+ fac_by(vs, am)
p+ fac_by(var_fac1=vs)

虽然可以说使用 ifmissing 会更简单 :

fac_by <- function(var_fac1, var_fac2) {
  facet_grid(rows=if(missing(var_fac1)) NULL else enquos(var_fac1), 
             cols=if(missing(var_fac2)) NULL else enquos(var_fac2))
} 

p+ fac_by(vs, am)
p+ fac_by(var_fac1=vs)

请注意,您可以使用 enquos(var_fac1) 而不是 vars(!!enquo(var_fac1)