9

我试图将我自己的类附加到一个numeric, 以改变输出format。这很好用,但是在我进行分组后by,该类恢复为数字。

示例:为我的班级定义一个新的格式函数:

format.myclass <- function(x, ...){
  paste("!!", x, "!!", sep = "")
}

然后做一个小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!!

现在执行 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

知道为什么吗?

4

2 回答 2

8

因为每当 R 对向量进行子集化时,它就会丢弃该类。为什么?好吧,因为它是一个arse,这就是原因。您需要编写一个“[”-subset 方法。

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

看看向量子集如何删除了类?那就是问题所在。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"

现在它有一些类。这也用 sapply 修复了你的最后一行:

> DT[, sapply(.SD, class), by = L]
   L      V1
1: a myclass
2: b myclass
于 2013-02-07T15:06:16.187 回答
3

这现在在v1.8.11 中修复,提交 1005+。来自新闻

o.SD不保留列的类现在已修复。感谢 Corone 在此处报告 SO: 为什么 data.table 在分组后会丢失 .SD 中的类定义?

于 2013-10-20T18:27:06.490 回答