do.call在rlang的整洁评估之前强制进行参数评估

时间:2019-02-08 13:48:39

标签: r tidyverse rlang do.call tidyeval

我正在尝试使用quores来存储对正在操作的对象的引用。 do.call打破了主意,提早评估了参数,因此生成的quosure存储了在empty_env()中评估的对象的新副本,而不是实际的对象调用。

rlang::exec()给出相同的结果,因为它依赖于do.callrlang::eval_tidy(call2(..))方法似乎也是一种解决方案,并且基于rlang::invoke()

问题是:

R在存储对对象/对象调用的引用而不是将其显式存储在列表中时需要什么方式?

混合使用do.callrlang是否可以,因为这会导致不必要的计算和复制?

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(v0.2.0)于2019-02-08创建。

1 个答案:

答案 0 :(得分:1)

引用参数:

do.call(quoting_fun, list(quote(obj)))
#<quosure>
#expr: ^obj
#env:  global

评估发生在list中,而不发生在do.call中。