R:基本 R 函数的整洁评估?

Posted

技术标签:

【中文标题】R:基本 R 函数的整洁评估?【英文标题】:R: Tidy eval for base R functions? 【发布时间】:2019-09-17 16:51:38 【问题描述】:

我之前问过一个相关的问题,但我认为这以一种更有趣的方式构建了它。

如果一个基本 R 函数是通用的,并且有一个或多个使用“标准”非标准评估的参数,那么提供一种“整洁”的方法是否可行,如果是这样,是否明智?可用于这些论点的评估技术?我的形象是一些概念上标准的包装器,可以使用元编程技术为每个单独的功能量身定制。它仅适用于对当前具有非标准评估的参数的评估,并且可能仅适用于那些对引用类型进行非标准评估的参数,以便所有当前方法在通过 NextMethod() 进行参数匹配和构造后仍然可用,或者任何其他方法等效于 S4、S6 等。

我问的原因是,我一直在缓慢而痛苦地把对 tidy eval 逐渐增加的理解塞进我的脑海,如果我认为这些强大的方法最终会成为非标准评估的标准,我会很高兴,因为反对永远维护多个古怪的非标准评估方法队列。

当然,我仍然必须记住,不同的非标准评估方法将被原语使用,而这些原语本身并不是某些通用的方法。 (我认为我说得对,虽然泛型函数可以有原始方法,但原始函数不能,或者至少不是,泛型。是吗?)我已经接受了。

【问题讨论】:

【参考方案1】:

我做了一些测试试图找出答案, 而且我认为这会非常不一致。

首先,如果您阅读InternalMethods 的文档,您将看到以下内容:

以下原始函数和内部函数是通用的,即您可以为它们编写方法

所以你可以拥有通用的原始函数。

这是我的一些测试,尽管我怀疑它们是否详尽。

library(rlang)

setClass("Foo", list(x="numeric"))
foo <- new("Foo", x=0)

首先我尝试定义一个$ 方法,它已经为列表和数据框使用引号:

setMethod("$", signature(x="Foo"), function(x, name) 
  enquo(name)
)

foo$x
<quosure>
expr: ^"x"
env:  empty

由于某种原因,我们定义的泛型自动将name 更改为字符, 但也许你可以简单地使用sym 然后继续。

然后我想看看包含省略号的泛型会发生什么:

setMethod("predict", signature(object="Foo"), function(object, ...) 
  enquos(...)
)

predict(foo, bar, baz=bak)
<list_of<quosure>>

[[1]]
<quosure>
expr: ^bar
env:  global

$baz
<quosure>
expr: ^bak
env:  global

没有惊喜(?)

然后我尝试定义[,它有几个形式参数和...

setMethod("[", signature(x="Foo"), function(x, i, j, ..., drop=TRUE) 
  enquos(i, j, ...)
)

foo[bar, , baz, bak]
<list_of<quosure>>

[[1]]
<quosure>
expr: ^bar
env:  global

[[2]]
<quosure>
expr: ^
env:  empty

[[3]]
<quosure>
expr: ^baz
env:  global

[[4]]
<quosure>
expr: ^bak
env:  global

似乎按预期工作,虽然我不确定如何处理空的 quosure, 它的行为并不像缺少参数:

f <- function(x) 
  print(missing(x))
  ff <- function(xx)  missing(xx) 
  eval_tidy(ff(!!enquo(x)))


f()
[1] TRUE
[1] FALSE

最后我尝试在[ 方法中添加一个形式参数:

setMethod("[", signature(x="Foo"), function(x, i, j, k, ..., drop=TRUE) 
  enquos(i, j, k, ...)
)

foo[bar, , baz, bak]
<list_of<quosure>>

[[1]]
<quosure>
expr: ^i
env:  000001FCA36865F0

[[2]]
<quosure>
expr: ^j
env:  000001FCA36865F0

[[3]]
<quosure>
expr: ^baz
env:  global

[[4]]
<quosure>
expr: ^bak
env:  global

而且我不知道这种行为是错误还是功能或其他什么。

【讨论】:

以上是关于R:基本 R 函数的整洁评估?的主要内容,如果未能解决你的问题,请参考以下文章

r 添加自定义评估函数度量(matthew相关系数)以评估插入符号模型

分析 R 代码时如何验证函数评估的次数

R中的预先评估导致错误消息

如何将变量传递给已经在 R 的参数中实现非标准评估的函数?

依赖于 R 中非标准评估的函数的包装器

评估具有不同长度的多个二进制测试答案的正确统计测试/ R 函数是啥?