对S4方法参数的延迟评估 [英] Lazy evaluation for S4 method arguments

查看:153
本文介绍了对S4方法参数的延迟评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个包含 data.table 的S4类,并试图实现 [该对象(如此处所述)它也子集 data.table 。例如(定义 i 子集):

I'm implementing an S4 class that contains a data.table, and attempting to implement [ subsetting of the object (as described here) such that it also subsets the data.table. For example (defining just i subsetting):

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 本身:

At this point, subsetting with a numeric vector (s[1:2]) works as desired (it subsets the data.table in the slot). However, I'd like to add the ability to subset using an expression. This works for the data.table itself:

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

但不适用于S4 [方法:

But not for the S4 [ method:

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


b $ b

问题似乎是,S4方法的签名中的参数不使用R的传统延迟评估来评估 - 参见此处


通用函数的签名将在调用函数时评估
,而不是使用$ b的传统延迟评估规则。因此,重要的是
从签名中排除任何参数需要象征性地处理
(例如函数替换的第一个参数)。

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).

因为 i j 实现这种子集>包含在通用的签名中。是否有任何方法可以立即计算 i 参数?

This explains why it doesn't work, but not how one can implement this kind of subsetting, since i and j are included in the signature of the generic. Is there any way to have the i argument not be evaluated immediately?

推荐答案

你可能没有运气在这一个。从 R开发人员说明

You may be out of luck on this one. From the R developer notes,

出现在泛型的签名中的参数将在通用函数
被调用时立即被求值;因此,需要利用延迟评估的任何参数不能在
中的签名。这些通常是字面上处理的参数,通常通过substitute()函数。
例如,如果想要将substitute()本身转换为一个泛型,第一个参数expr,
不会在签名中,因为它不能被评估,而是作为一个字面量。 / p>

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 在其源代码)。您的S3对象仍然可以创建和操作下面的S4对象,以维持半静态打字功能。

I would follow the example from the data.table package writers and use an S3 object (see line 304 of R/data.table.R in their source code). Your S3 object can still create and manipulate an S4 object underneath to maintain the semi-static typing feature.

我们不能获得非常聪明的:

We can't get extraordinarily clever:

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

定义S3和S4方法将调度S3方法,这使得它看起来像我们应该能够绕过S4调用并手动调度它,但不幸的是参数评估仍然发生!您可以通过借用 plyr ::。来获得关闭,这将给你类似的语法:

Defining both an S3 and S4 method will dispatch the S3 method, which makes it seem like we should be able to route around the S4 call and dispatch it manually, but unfortunately the argument evaluation still occurs! You can get close by borrowing plyr::., which would give you syntax like:

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

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

Not ideal, but closer than anything else.

这篇关于对S4方法参数的延迟评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆