代码之家  ›  专栏  ›  技术社区  ›  AdamO

聚合或聚合并与一对多变量数据合并是否更快。桌子

  •  0
  • AdamO  · 技术社区  · 8 年前

    我有一个 data.table 如下所示:

    dt <- data.table(data.frame(
      id = rep(1:3, each=5),
      age = rep(10*(2:4), each=5),
      var = rnorm(15)
    ))
    

    我想聚合 var 比如说,使用求和,但我必须在输出中保持“age”为一对多变量。

    一种方法是:

    dt <- merge(dt[, .(vsum=sum(var)), by=id], unique(dt[, c('id', 'age']), by='id')
    

    另一种方法是

    dt <- dt[, .(vsum=sum(var)), by=c('id', 'age')]
    

    我的直觉告诉我第二个案子浪费时间是因为 by= 查找的不同值 age 在内部 ids ,如果 年龄 是20个或更多变量。我的直觉说 merge 是有问题的,因为总的操作数较大,并且只有其中的一个子集是 根据= [.data.table 例子

    我可以探索像这样愚蠢的案例,但对1的一般操作特征没有感觉。当存在多对一变量(如年龄)时,如果数据密集于观测值(多行,少ID)或密集于个体(相同的N行,多ID)

    是否有任何通用、有效的方法来处理此类摘要数据集?

    1 回复  |  直到 8 年前
        1
  •  2
  •   thc    8 年前

    这完全取决于实施情况。然而,为什么不这样做呢?

    dt[, .(vsum=sum(var), age=age[1]), by="id"]
    

    编辑:下面的基准测试。

    dt <- data.table(data.frame(
      id = rep(1:10000, each=5),
      age = rep(10*(1:10000), each=5),
      var = rnorm(150000)
    ))
    
    res1 <- function() {merge(dt[, .(vsum=sum(var)), by="id"], unique(dt[, c('id', 'age')]), by='id')}
    res2 <- function() {dt[, .(vsum=sum(var)), by=c('id', 'age')]}
    res3 <- function() {dt[, .(vsum=sum(var), age=unique(age)), by="id"]}
    res4 <- function() {dt[, .(vsum=sum(var), age=age[1]), by="id"]}
    
    library(microbenchmark)
    microbenchmark(res1(),res2(), res3(), res4(), times=10)
    
    Unit: milliseconds
       expr       min        lq      mean    median        uq       max neval cld
     res1()  6.940417  7.949203  9.250408  8.791923  9.695110 13.448288    10  b 
     res2()  3.796992  3.898165  4.889812  4.507141  4.790384  9.477044    10 a  
     res3() 48.259783 52.026664 55.401017 54.986112 59.375380 60.804102    10   c
     res4()  2.646796  2.853593  3.709116  3.252362  3.391909  6.321708    10 a 
    

    因此,事实证明,与直觉相反,第二种方法相当快,最快的是第四种方法。