我希望能够在 S4 对象上应用“子集”(括号)[
方法,让我们将其称为 foo
,这样当它是称为 setMethod("[", 'foo', ...
) 它将在其保存在特定槽中的 data.table 上应用 [
运算符。
示例:
foo <- setClass("foo", slots = c(myDT = "data.table"),
prototype = prototype( myDT = NULL ))
# quickly make a foo class with a DT in the myDT slot
myfoo <- new("foo", myDT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9))
# sneak peek
myfoo
An object of class "foo"
Slot "myDT":
x y v
1: b 1 1
2: b 3 2
3: b 6 3
4: a 1 4
5: a 3 5
6: a 6 6
7: c 1 7
8: c 3 8
9: c 6 9
棘手的部分
# I want to be able to do eg
myfoo[1:3, 2:3]
y v
1: 1 1
2: 3 2
3: 6 3
并让它给我与执行相同的结果:
myfoo@myDT[1:3, 2:3]
y v
1: 1 1
2: 3 2
3: 6 3
到目前为止(我猜测)它将/应该是类似的事情
setMethod(f = "[", signature = signature(x = "foo"),
definition = function(x, ...) {
`[`(<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="730b335d1e0a3727" rel="noreferrer noopener nofollow">[email protected]</a>, ...)
# OR maybe
# x <- x@myDT
# callNextMethod(x, ...)
}
)
但是无论我用它调用 myfoo[i,j]
,它总是只会返回整个 data.table。
如果可以实现的话,有什么想法吗?到目前为止,我通常会遇到有关 j
不符合要求的错误。
如果我能够以某种方式“回收”data.table
中可用的内容,我希望避免必须为此插槽完全实现某种形式的影子索引;
当然,其他 data.table
函数的额外好处也可能适用于这种方式?
但对于开始“传递”指数来说将是一个好的开始。
PS:如果您想知道为什么不直接执行 myfoo@myDT
- 现实生活中的 foo
类有多个槽,其中只有一个(data.table
one) 是“值得”被索引的,所以我想“捷径”一点地应用程序。
最佳答案
这是一个迟来的、不那么老套的答案:
library(data.table)
setClass("Foo", slots = c(dt = "data.table"), prototype = list(dt = data.table()))
setMethod("[", signature(x = "Foo", i = "ANY", j = "ANY", drop = "ANY"),
function(x, i, j, ..., drop = TRUE) {
if (missing(j))
callGeneric(x@dt, i, , ..., with = TRUE)
else callGeneric(x@dt, i, j, ..., with = FALSE)
})
foo <- new("Foo", dt = data.table(x = letters[1:6], y = 1:6, z = rnorm(6L)))
identical(foo[1:3, 2:3], foo@dt[1:3, 2:3]) # TRUE
由于 this 中概述的原因,此方法仍然不支持 [.data.table
的主要功能。问题,即在发生多重分派(dispatch)(S4 的功能,而不是 S3 的功能)之前,除了 x
之外,还必须评估 i
和 j
。因此:
foo@dt[y >= 3L]
## x y z
## 1: c 3 0.02991911
## 2: d 4 -0.36919712
## 3: e 5 -0.03291414
## 4: f 6 -1.02399695
foo[y >= 3L]
## Error in `[.data.table`(x@dt, i, , with = TRUE, ...) :
## i is not found in calling scope and it is not a column name either. When the first argument inside DT[...] is a single symbol (e.g. DT[var]), data.table looks for var in calling scope.
您仍然可以使用环境中的变量作为索引向量:
ii <- 3:6
foo[ii]
## x y z
## 1: c 3 0.02991911
## 2: d 4 -0.36919712
## 3: e 5 -0.03291414
## 4: f 6 -1.02399695
无论如何,我同意一些评论,建议在 S3 中实现围绕 data.table
构建的类通常会更好。
关于r - 如何将 S4 对象的 setMethod `[` 应用于插槽中的 data.table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73169345/