如果A,B和C是data.table,dt中的列,我想做的是:创建一个新列(D),这是C中每个组的最小值,经过过滤后只考虑组中B为真的行。到目前为止,我所拥有的是...
dt[, D := min(A[B == TRUE]), by = C]
这行得通,我得到了我想要的结果,但是它非常慢(我的数据集有几百万行)。有更快,更优雅的方法吗?我只对使用data.table的结果感兴趣,请不要使用dplyr :)
答案 0 :(得分:1)
还有另一种方法,该方法是在过滤后为每个组计算SELECT DISTINCT `submodel` from `goods`
,然后执行 update join 。缺少的组将设置为min()
,从而避免了从整数到双精度的类型转换。
NA
# dummy data dt <- data.table(A = rep(1:3, 3), B = c(rep(c(FALSE, TRUE, TRUE), 2), rep(FALSE, 3)), C = 10L * rep(1:3, each = 3)) dt[, A := A + C] dt
A B C
1: 11 FALSE 10
2: 12 TRUE 10
3: 13 TRUE 10
4: 21 FALSE 20
5: 22 TRUE 20
6: 23 TRUE 20
7: 31 FALSE 30
8: 32 FALSE 30
9: 33 FALSE 30
# all variables are integer or logical str(dt)
Classes ‘data.table’ and 'data.frame': 9 obs. of 3 variables:
$ A: int 11 12 13 21 22 23 31 32 33
$ B: logi FALSE TRUE TRUE FALSE TRUE TRUE ...
$ C: int 10 10 10 20 20 20 30 30 30
- attr(*, ".internal.selfref")=<externalptr>
dt[dt[(B), min(A), by = C], on = "C", D := V1][]
A B C D
1: 11 FALSE 10 12
2: 12 TRUE 10 12
3: 13 TRUE 10 12
4: 21 FALSE 20 22
5: 22 TRUE 20 22
6: 23 TRUE 20 22
7: 31 FALSE 30 NA
8: 32 FALSE 30 NA
9: 33 FALSE 30 NA
# all variables are still integer or logical str(dt)
表达式
Classes ‘data.table’ and 'data.frame': 9 obs. of 4 variables:
$ A: int 11 12 13 21 22 23 31 32 33
$ B: logi FALSE TRUE TRUE FALSE TRUE TRUE ...
$ C: int 10 10 10 20 20 20 30 30 30
$ D: int 12 12 12 22 22 22 NA NA NA
- attr(*, ".internal.selfref")=<externalptr>
按组返回最小值(如果有)
dt[(B), min(A), by = C]
注意事项:我并不是说这比OP的方法要快。由于缺乏可重现的示例,我无法对其进行测试,该示例可以按问题大小进行缩放以进行基准测试。
答案 1 :(得分:0)
我最终将列A转换为数值类型(从整数),以便空组返回最小值NA,然后使用pmin.int()代替min()。事实证明,这比我原来的方法快4倍!