r - 如何将 S4 对象的 setMethod `[` 应用于插槽中的 data.table

标签 r indexing data.table r-s4

我希望能够在 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 之外,还必须评估 ij 。因此:

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/

相关文章:

r - 对数据框的每一行进行排序

r - 使用 group_by 连接字符串并在 r 中汇总

sql - 为什么不使用 GIN 索引?

database - 专门用于位图索引的硬件?

r - 如何在 R 中读取分隔 "::"的 .dat 文件

r - 将 R Shiny Page 导出为 PDF

html - Bootstrap 导航栏不填满整个宽度

Python - 读取 pickle 数据的索引

R data.table 范围,使用变量可靠地引用未知列名

r - 如何在 data.table 中通过参数设置名称?