1

我是 data.table 的新手,但我设法将 60 万行数据集中的计算从数千秒(使用 *ply 循环)减少到 1.7 秒。基本上我需要同一的组中列中值最低的行并开始。我在用着

DT[, list(class=min(class)), by=list(group, start)]

但要做到这一点,我只使用来自具有更多列的 data.frame 中的这 3 列创建了 DT。因此,为了将我的结果与原始 data.frame 合并,我正在考虑使用 row.name,所以我使用row.name=TRUE创建了 DT,这是我所拥有的一个示例:

   group   start     class     rn
 1:  A      4943         4      1
 2:  A      5030         0      2
 3:  A      5030         4      3
 4:  A      5030         2      4
 5:  A      5083         4      5
 6:  A      5083         3      6
 7:  B      5041         0      7
 8:  B      5041         1      8
 9:  B      5083         4      9
 ...

我想要的结果只是rn对应于最小值:

   group   start     class     rn
 1:  A      4943         4      1
 2:  A      5030         0      2
 3:  A      5083         3      6
 4:  B      5041         0      7
 5:  B      5083         4      9
 ...

但如果我使用:

DT[, list(class=min(class)), by=list(group, start, rn)]

或者

DT[, list(class=min(class), rn), by=list(group, start)]

我得到了所有的行,而不仅仅是最小值的行。

额外的问题

我可以使用我的命令使用 data.table sintax 来计算组中每个类类型的案例数吗?

   group   start     class     rn    class0    class1    class2    class3    class4
 1:  A      4943         4      1         0         0         0         0         1
 2:  A      5030         0      2         1         0         1         0         1
 3:  A      5083         3      6         0         0         0         1         1
 4:  B      5041         0      7         1         1         0         0         0
 5:  B      5083         4      9         0         0         0         0         1
 ...
4

1 回答 1

2

对于您的第一个问题,您基本上是在呼吁min每个小组。这不是必需的。如果您也对列进行排序class(通过设置key),那么您可以使用mult="first"功能直接选择最小的元素。那是,

setkey(dt, group, start, class)
dt[CJ(unique(group), unique(start)), mult="first", nomatch=0]
   group start class rn
1:     A  4943     4  1
2:     A  5030     0  2
3:     A  5083     3  6
4:     B  5041     0  7
5:     B  5083     4  9

或者,如果您不想在CJ这里使用,那么您可以这样做:

setkey(dt, group, start, class)
dt[, list(class=class[1], rn=rn[1]), by=list(group, start)]

编辑2:

这是一个完整的答案:

dt.out <- dt[, c(list(class = class[1], rn=rn[1]), 
       {tt <- rep(0,5); tt[class+1] <- 1; as.list(tt)}), by=list(group, start)]
setnames(dt.out, 5:9, paste0("Class", 0:4))

   group start class rn Class0 Class1 Class2 Class3 Class4
1:     A  4943     4  1      0      0      0      0      1
2:     A  5030     0  2      1      0      1      0      1
3:     A  5083     3  6      0      0      0      1      1
4:     B  5041     0  7      1      1      0      0      0
5:     B  5083     4  9      0      0      0      0      1
于 2013-07-22T13:51:04.370 回答