改善data.table的汇总

问题描述 投票:2回答:1

假设我有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 ]

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

r data.table
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]

添加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):

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS81ckx6Wi5wbmcifQ==” alt =“在此处输入图像描述”>“ >>

© www.soinside.com 2019 - 2024. All rights reserved.