如何从 eval_tidy 评估的代码访问 .data 环境

How to access .data environment from code evaluated by eval_tidy

我想使用 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)))
}

完成此操作的基本 R 方法是:

fn_base <- function(expr) {
    expr <- substitute(expr)
    eval(expr, envir = mtcars, enclos = parent.frame())
}

但我想使用 eval_tidy 来获得其他好处,例如 .data 代词。 According to the rlang documentationenexprsubstitute 的 rlang 方式。让我们同时尝试 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。 (用户应该能够提供以 ... 作为参数的任意函数。)

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