我是data.table的新手,但我已经设法将数600万行的数据集中的计算从数千秒(使用* ply循环)减少到1.7秒。基本上我需要在组和开始的组中类列中具有最低值的行。我正在使用
DT[, list(class=min(class)), by=list(group, start)]
但是为了做到这一点,我创建了DT,只有来自data.frame的这3列有更多列。因此,要将我的结果与原始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
...
我想要的结果只是对应于minimium class 值的 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)]
我获取了所有行,而不仅仅是 class 最小的行。
额外问题
我可以使用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
...
答案 0 :(得分: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