基于不同表的行值对表中的列值求和

时间:2017-12-27 09:43:09

标签: r dataframe data.table

我想根据不同表格 DT1 的行值对表格 DT2 中的列值进行求和,并将其存储在 DT3

library(data.table)
DT1 <- data.table(x = seq(1,100, by = 1), 
                 y = round(runif(100,50, 60)),
                 z = round(runif(100, 61, 70)))

DT2 <- data.table(a = seq(1, 1000, by = 1),
                 b = round(rnorm(1000, 10,1)),
                 c = round(rnorm(1000, 20,1)),
                 d = round(rnorm(1000, 30,1)))

初始化DT3

DT3 <- DT1[,.(x)]
DT3[,':='(e = 0,
          f = 0,
          g = 0)]

使用 for 循环来汇总值

for(i in 1:nrow(DT1)){
  DT3[i, 2:4] <- DT2[DT1[i,y]:DT1[i,z], 
                     lapply(.SD, sum),
                     .SDcols = c("b", "c", "d")]
}

这很好用。唯一的问题是它需要很多时间 随着 DT1 DT2 中行数和列数的增加。我有 DT1 ,行数超过100000。这需要我大约30分钟。有没有更快的方法来执行此操作?

2 个答案:

答案 0 :(得分:1)

你可以试试这个:

library(data.table)
DT1 <- data.table(x = seq(1,100, by = 1), 
                 y = round(runif(100,50, 60)),
                 z = round(runif(100, 61, 70)))

DT2 <- data.table(a = seq(1, 1000, by = 1),
                 b = round(rnorm(1000, 10,1)),
                 c = round(rnorm(1000, 20,1)),
                 d = round(rnorm(1000, 30,1)))

matrix(DT1[, colSums(DT2[, -"a"][as.numeric(y:z)]), 1:nrow(DT1)]$V1,
       ncol = 3, byrow = TRUE)

  #      [,1] [,2] [,3]
  # [1,]  114  223  324
  # [2,]   73  141  208
  # [3,]  112  222  323
  # [4,]  151  301  443
  # [5,]  133  263  382
  # ...

迭代DT1行并提取向量y:zas.numeric(y:z))。将此向量传递给DT2并获取colSums

答案 1 :(得分:1)

就单次迭代而言,您的代码已经很有效。您使用data.table代替dataframelapply语句也是有效的。

因此,我认为主要的优化应该集中在你如何应用sum语句。

<强> 1。避免重复计算:

检查数据table(duplicated(DT1[,c("y", "z")]))的结果。对于伪数据情况,重复30%的求和操作。如果您的数据具有如此高的重复率,我建议先计算唯一y & z的结果,然后将结果分配给主数据表。

<强> 2。并行化循环: 您的迭代是独立的,这使得循环可以并行化。检查foreach包。但请注意.combine参数/函数,因为这可能会极大地减少结果组合开销。

相关问题