我想用来评估一个接受命名空间rlang::eval_tidy()
的函数。...
mtcars
这是一个我想评估的示例函数,它是从 assertr 借来的。
has_all_names <- function(...){
check_this <- list(...)
parent <- parent.frame()
all(vapply(check_this,
function(x) exists(x, where = parent, inherits = FALSE),
logical(1)))
}
完成此操作的 base-R 方法是:
fn_base <- function(expr) {
expr <- substitute(expr)
eval(expr, envir = mtcars, enclos = parent.frame())
}
但我想使用eval_tidy
其他好处,比如.data
代词。根据 rlang 文档,enexpr
是 rlang 的方式substitute
。让我们同时尝试substitute
和enexpr
。
fn_rlang_substi <- function(expr) {
expr <- substitute(expr)
rlang::eval_tidy(expr, mtcars, parent.frame())
}
fn_rlang_enexpr <- function(expr) {
expr <- rlang::enexpr(expr)
rlang::eval_tidy(expr, mtcars, parent.frame())
}
fn_base(has_all_names("cyl", "mpg")) # TRUE
fn_rlang_substi(has_all_names("cyl", "mpg")) # FALSE
fn_rlang_enexpr(has_all_names("cyl", "mpg")) # FALSE
这是怎么回事?有什么eval_tidy
不同?
我知道 rlang 具有要处理的功能...
,但在解决这个问题时,我不想修改has_all_names
. (用户应该能够提供...
作为参数的任意函数。)