【发布时间】:2018-08-13 19:18:23
【问题描述】:
我想使用 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 代词。 According to the rlang documentation、enexpr 是substitute 的 rlang 方式。让我们试试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。 (用户应该能够提供以... 作为参数的任意函数。)
【问题讨论】:
-
我会更改您的问题的标题,因为它与点无关。