【发布时间】:2015-03-07 21:58:14
【问题描述】:
我有一个表,其中键被重复了多次,并且使用另一列的最大值为每个键只选择一行。
这个例子演示了我目前的解决方案:
N = 10
k = 2
DT = data.table(X = rep(1:N, each = k), Y = rnorm(k*N))
X Y
1: 1 -1.37925206
2: 1 -0.53837461
3: 2 0.26516340
4: 2 -0.04643483
5: 3 0.40331424
6: 3 0.28667275
7: 4 -0.30342327
8: 4 -2.13143267
9: 5 2.11178673
10: 5 -0.98047230
11: 6 -0.27230783
12: 6 -0.79540934
13: 7 1.54264549
14: 7 0.40079650
15: 8 -0.98474297
16: 8 0.73179201
17: 9 -0.34590491
18: 9 -0.55897393
19: 10 0.97523187
20: 10 1.16924293
> DT[, .SD[Y == max(Y)], by = X]
X Y
1: 1 -0.5383746
2: 2 0.2651634
3: 3 0.4033142
4: 4 -0.3034233
5: 5 2.1117867
6: 6 -0.2723078
7: 7 1.5426455
8: 8 0.7317920
9: 9 -0.3459049
10: 10 1.1692429
问题在于,对于较大的 data.table,这需要很长时间:
N = 10000
k = 25
DT = data.table(X = rep(1:N, each = k), Y = rnorm(k*N))
system.time(DT[, .SD[Y == max(Y)], by = X])
user system elapsed
9.69 0.00 9.69
我的实际表大约有 1 亿行...
谁能提出更有效的解决方案?
编辑 - 设置键的重要性
建议的解决方案效果很好,但您必须使用 setkey,或订购 DT 以使其工作:
请参阅代表中没有“每个”的示例:
N = 10
k = 2
DT = data.table(X = rep(1:N, k), Y = rnorm(k*N))
DT[DT[, Y == max(Y), by = X]$V1,]
X Y
1: 1 1.26925708
2: 4 -0.66625732
3: 5 0.41498548
4: 8 0.03531185
5: 9 0.30608380
6: 1 0.50308578
7: 4 0.19848227
8: 6 0.86458423
9: 8 0.69825500
10: 10 -0.38160503
【问题讨论】:
-
这是因为
.SD[..]为每个组调用[.data.table。我们知道这一点,很可能会在 1.9.8 中进行优化。 SO上有一些解决方案可以解决这个问题(通常使用.I),您可以通过搜索找到。优化后我会更新这篇文章。 -
@Arun 与
devel版本的.SD解决方案(由Khashaa 和AnandaMahto 测试)相比,cran版本给出了不同的结果/错误。我使用的是开发版。 -
@akrun,corone,如果您使用的是 1.9.4,请执行以下操作:
options(datatable.auto.index=FALSE),一切正常。这是 1.9.5 中修复的新功能中的一个错误。 -
@Corone,不确定您是否知道,但如果给定 X 的 max(Y) 重复,您的代码将返回每个唯一 X 的多行。
-
@docendodiscimus 是的,好点。在我的实际情况下,数据不会有联系(或者在示例中不太可能出现平局),但是是的,我认为每个组都需要唯一地满足“条件”。
标签: r data.table