如何从 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 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
。 (用户应该能够提供以 ...
作为参数的任意函数。)
您的存在性检查需要 inherits = TRUE
,因为 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 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
。 (用户应该能够提供以 ...
作为参数的任意函数。)
您的存在性检查需要 inherits = TRUE
,因为 eval_tidy()
将屏蔽数据安装到上一级。