我正在寻找一种方法来优化 data.table 中的聚合,我有几百万个数据,而我目前的实现速度很慢。
可重现的例子:
library(data.table)
df <- data.table(Factor = as.factor(rep(LETTERS[1:3], 3)),
Variable = 1:9)
当前实现:
aux <- df[, .(sumVar = sum(Variable)/sum(df$Variable)), by = .(Factor)]
df[aux, sumVar := sumVar, on = .(Factor = Factor)]
期望的输出:
> df
Factor Variable sumVar
1: A 1 0.2666667
2: B 2 0.3333333
3: C 3 0.4000000
4: A 4 0.2666667
5: B 5 0.3333333
6: C 6 0.4000000
7: A 7 0.2666667
8: B 8 0.3333333
9: C 9 0.4000000
我认为我的问题在于 merge
,但我不知道如何改进它,我不熟悉 dplyr
并且我没有找到任何方法使用 data.table
一步完成操作。
感谢任何帮助!
最佳答案
您的示例中有很多重复正确,因此不确定我是否对其进行了解释。尽管如此,最好只计算一次分母并使用 gsum
:
BigTotal <- df[, sum(Variable)]
df[, sumVar1 := sum(Variable), by = .(Factor)][, propVar := sumVar1 / BigTotal]
大约是 Ben 最快解决方案的一半时间。
df <- data.table(
Factor = as.factor(sample(LETTERS, size = 10^8, replace = T)),
Variable = sample(10^3, size = 10^8, replace = T)
)
microbenchmark::microbenchmark(dt1 = {
aux <- df[, .(sumVar = sum(Variable)/sum(df$Variable)), keyby = .(Factor)]
df[aux, sumVar := sumVar, on = .(Factor = Factor)]
},
dt2 = {
BigTotal <- df[, sum(Variable)]
df[, sumVar1 := sum(Variable), by = .(Factor)][, propVar := sumVar1 / BigTotal]
},
times = 2)
Unit: seconds
expr min lq mean median uq max neval cld
dt1 9.523696 9.523696 9.567555 9.567555 9.611414 9.611414 2 b
dt2 3.996581 3.996581 4.521274 4.521274 5.045967 5.045967 2 a
关于r - 为每一行计算一个变量在 data.table 中的百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52206842/