gpt4 book ai didi

r - S4 方法参数的延迟评估

转载 作者:行者123 更新时间:2023-12-01 05:13:40 26 4
gpt4 key购买 nike

我正在实现一个包含 data.table 的 S4 类,并尝试实现对象的 [ 子集(如 here 所述),这样它还子集 data.table。例如(仅定义 i 子集):

library(data.table)

.SuperDataTable <- setClass("SuperDataTable", representation(dt="data.table"))

setMethod("[", c("SuperDataTable", "ANY", "missing", "ANY"),
function(x, i, j, ..., drop=TRUE)
{
initialize(x, dt=x@dt[i])
})

d = data.table(a=1:4, b=rep(c("x", "y"), each=2))
s = new("SuperDataTable", dt=d)

此时,使用数字向量 (s[1:2]) 进行子集化可以按预期工作(它对槽中的 data.table 进行子集化)。但是,我想添加使用表达式进行子集化的功能。这适用于 data.table 本身:

s@dt[b == "x"]
# a b
# 1: 1 x
# 2: 2 x

但不适用于 S4 [ 方法:

s[b == "x"]
# Error: object 'b' not found

问题似乎是 S4 方法签名中的参数未使用 R 的传统惰性求值进行求值 - 参见 here :

All arguments in the signature of the generic function will be evaluated when the function is called, rather than using the traditional lazy evaluation rules of S. Therefore, it's important to exclude from the signature any arguments that need to be dealt with symbolically (such as the first argument to function substitute).

这解释了为什么它不起作用,但没有解释如何实现这种子集化,因为包含了 ij在泛型的签名中。有什么方法可以让 i 参数立即被评估?

最佳答案

您可能在这方面不走运。从 R developer notes 开始,

Arguments appearing in the signature of the generic will be evaluated as soon as the generic function is called; therefore, any arguments that need to take advantage of lazy evaluation must not be in the signature. These are typically arguments treated literally, often via the substitute() function. For example, if one wanted to turn substitute() itself into a generic, the first argument, expr, would not be in the signature since it must not be evaluated but rather treated as a literal.

此外,由于方法缓存,

All the arguments in the full signature are evaluated as described above, not just the active ones. Otherwise, in special circumstances the behavior of the function could change for one method when another method was cached, definitely undesirable.

我会按照 data.table 包作者的示例并使用 S3 对象(请参阅 R/data.table.R 的第 304 行,在他们的 source code 中) .您的 S3 对象仍然可以在下面创建和操作 S4 对象,以保持半静态类型化功能。

我们不能变得特别聪明:

 ‘[’ is a primitive function;  methods can be defined, but the generic function is implicit, and cannot be changed.

同时定义 S3 和 S4 方法将调度 S3 方法,这使得我们似乎应该能够绕过 S4 调用并手动调度它,但不幸的是,参数评估仍然发生!你可以通过借用 plyr::. 来接近,它会给你这样的语法:

s <- new('SuperDataTable', dt = as.data.table(iris))
s[.(Sepal.Length > 4), 2]

不理想,但比其他任何东西都更接近。

关于r - S4 方法参数的延迟评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22593102/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com