我想根据不同表格 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分钟。有没有更快的方法来执行此操作?
答案 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:z
(as.numeric(y:z)
)。将此向量传递给DT2
并获取colSums
。
答案 1 :(得分:1)
就单次迭代而言,您的代码已经很有效。您使用data.table
代替dataframe
,lapply
语句也是有效的。
因此,我认为主要的优化应该集中在你如何应用sum语句。
<强> 1。避免重复计算:
检查数据table(duplicated(DT1[,c("y", "z")]))
的结果。对于伪数据情况,重复30%的求和操作。如果您的数据具有如此高的重复率,我建议先计算唯一y & z
的结果,然后将结果分配给主数据表。
。
<强> 2。并行化循环:
您的迭代是独立的,这使得循环可以并行化。检查foreach
包。但请注意.combine
参数/函数,因为这可能会极大地减少结果组合开销。