为什么data.table在分组后丢失.SD中的类定义?

Cor*_*one 9 r class data.table

我试图将自己的类附加到a numeric,以改变输出format.这工作正常,但在我做了一个组后by,该类恢复为数字.

示例:为我的类定义新的格式函数:

format.myclass <- function(x, ...){
  paste("!!", x, "!!", sep = "")
}
Run Code Online (Sandbox Code Playgroud)

然后做一个小的data.table并将其中一列更改为myclass:

> DT <- data.table(L = rep(letters[1:3],3), N = 1:9)
> setattr(DT$N, "class", "myclass")
> DT
   L     N
1: a !!1!!
2: b !!2!!
3: c !!3!!
4: a !!4!!
5: b !!5!!
6: c !!6!!
7: a !!7!!
8: b !!8!!
9: c !!9!!
Run Code Online (Sandbox Code Playgroud)

现在执行group by,N列恢复为整数:

> DT[, .SD, by = L]
   L N
1: a 1
2: a 4
3: a 7
4: b 2
5: b 5
6: b 8
7: c 3
8: c 6
9: c 9

> DT[, sapply(.SD, class), by = L]
   L      V1
1: a integer
2: b integer
3: c integer
Run Code Online (Sandbox Code Playgroud)

知道为什么吗?

Spa*_*man 8

因为只要R子集一个向量,它就会抛弃该类.为什么?好吧,因为它是一个屁股,这就是原因.你需要写一个"[" - 子集方法.

> DT[,N]
[1] 1 2 3 4 5 6 7 8 9
attr(,"class")
[1] "myclass"
> DT[1:2,N]
[1] 1 2
Run Code Online (Sandbox Code Playgroud)

看看矢量的子集如何删除了这个类?那就是问题所在.data.table正在向你的向量执行此操作.写一个"["方法(只复制Date使用的那个):

"[.myclass"= function (x, ..., drop = TRUE){
    cl <- oldClass(x)
    class(x) <- NULL
    val <- NextMethod("[")
    class(val) <- cl
    val
}

> DT[1:2,N]
[1] 1 2
attr(,"class")
[1] "myclass"
Run Code Online (Sandbox Code Playgroud)

现在它有一些课程.这也修复了你的最后一行与sapply:

> DT[, sapply(.SD, class), by = L]
   L      V1
1: a myclass
2: b myclass
Run Code Online (Sandbox Code Playgroud)

  • +1也是.我会发誓`.SD`保留列属性,但显然没有.会解决这个问题,除非有任何不利因素吗?(我知道不会有任何性能下降,所以我的意思是其他). (3认同)
  • 我真的不知道为什么这不是默认行为.或者在不同的别名下,CRAN上有多少副本"[.Date".真正的解决方案是从"Date"继承子类并获得免费的jj/j的子集函数 (2认同)