我正在尝试使用quosures来存储对我正在操作的对象的引用。 do.call
打破了这个想法,提前评估了参数,因此生成的 quosure
存储了在 empty_env()
中评估的对象的新副本,而不是对对象的实际调用。
rlang::exec()
给出相同的结果,因为它依赖于 do.call
。 rlang::eval_tidy(call2(..))
方法似乎是一个解决方案,以及基于它的 rlang::invoke()
。
问题是:
R 中存储对对象/对象调用的引用的所需方式是什么,而不是将其显式存储在列表中。
混合使用do.call
和rlang
是否可以,因为它会导致不必要的计算和复制?
为什么 invoke
被软弃用,但比 exec
更符合 rlang 的理念?
require(rlang)
#> Loading required package: rlang
quoting_fun <- function(x) {
x_enq <- enquo(x) # enquote
x + length(x) # do something
x_enq
}
obj <- 1:10L
quoting_fun(obj) # ok
#> <quosure>
#> expr: ^obj
#> env: global
do.call(quoting_fun, list(obj)) # not ok
#> <quosure>
#> expr: ^<int: 1L, 2L, 3L, 4L, 5L, ...>
#> env: empty
exec(quoting_fun, obj)
#> <quosure>
#> expr: ^<int: 1L, 2L, 3L, 4L, 5L, ...>
#> env: empty
rlang::invoke(quoting_fun, list(obj))
#> <quosure>
#> expr: ^1
#> env: 000000001C8DDFD8
eval_tidy(call2(quoting_fun, quo(obj)))
#> <quosure>
#> expr: ^obj
#> env: global
由 reprex package 创建于 2019-02-08 (v0.2.0)。
最佳答案
引用论点:
do.call(quoting_fun, list(quote(obj)))
#<quosure>
#expr: ^obj
#env: global
评估发生在list
中,而不是在do.call
中。
关于r - do.call 强制在 rlang 的整洁评估之前评估参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54593806/