2

我想用来评估一个接受命名空间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。让我们同时尝试substituteenexpr

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. (用户应该能够提供...作为参数的任意函数。)

4

1 回答 1

0

您需要inherits = TRUE在您的存在检查,因为eval_tidy()安装屏蔽数据上一级。

于 2018-03-06T01:57:31.487 回答