2

假设我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% 的行有一个重复的 key 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 ]

非常慢,我想知道如何改进这一点。任何帮助表示赞赏。

4

1 回答 1

2

通过放入c密钥并使用.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]

ADDED 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):

在此处输入图像描述

于 2013-05-27T12:02:56.720 回答