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)
虽然可以说使用 if
和 missing
会更简单 :
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)
我想对 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)
虽然可以说使用 if
和 missing
会更简单 :
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)