r - 改进 data.table 的聚合

标签 r data.table

假设我的 data.table 看起来像这样:

dt <- data.table(
  a   = c( "A", "B", "C", "C" ),
  b   = c( "U", "V", "W", "X" ),
  c   = c( 0.1, 0.2, 0.3, 0.4 ),
  min = c( 0,   1,   2,   3 ),
  max = c( 11,  12,  13,  14 ),
  val = c( 100, 200, 300, 400 ),
  key = "a"
)

我的实际 data.table 有更多的列和多达几百万行。大约 10% 的行有重复的键 a。我想将这些行与如下所示的函数聚合:

comb <- function( x ){
  k <- which.max( x[ ,c ]  )
  list( b = x[ k, b ], c = x[ k, c ], min = min( x[ , min ] ), max = max( x[ , max ] ), val = sum( x[ ,val ] ) )
}

但是,调用

dt <- dt[ , comb(.SD), by = a ]

非常慢,我想知道如何改进它。如有任何帮助,我们将不胜感激。

最佳答案

通过将 c 放入 key 中并使用 .N 来获取我们可以避免 which.max 的最大值(未经测试):

setkey(dt, a, c)
dt[, c(.SD[.N], min = min[1], val = sum(val)), by = a][, -c(4, 6)]

添加:或此变体:

dt[, c(.SD[.N, c(1:2, 4)], min = min[1], val = sum(val)), by = a]

添加2:我们只使用了.SD,因为您表示您有很多列,但如果您愿意将它们写出来,那么上面的内容可以写成:

dt[, list(b = b[.N], c = c[.N], min = min[1], max = max[.N], val = sum(val)), by = a]

添加 3:又一个变体:

dt[, c("min", "val") := list(min[1], sum(val)), by = a][, .SD[.N], by = a]

基准

对四种解决方案进行微基准测试得出以下箱线图 (n = 10):

enter image description here

关于r - 改进 data.table 的聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16770328/

相关文章:

R - readRDS() 和 load() 无法提供与原始数据相同的 data.tables

r - 如何替换多个值中的值?

r - 如何将输入和输出沉入R中的文本文件中?

r - 有没有一种比较两个数据帧的有效方法

r - R中的autoplot函数和plot函数有什么区别

r - 通过列的精确匹配合并数据框

r - 如何使用 R 中的递归创建长度为 n 的所有 2^n 二进制序列的矩阵?

r - dplyr::slice in data.table

r - 重新启动的组计数器(使用 R data.table)

r - data.table 删除关键行并汇总