我有一个相对较大的数据帧(~2,000,000行),对于每一行,我需要在该观察组中计算大于或等于当前行值的每个值的总和 .
这是一个示例数据框:
sample_df = data.frame(
group_id = c(1,1,1,1,2,2,2,2),
value = c(10,12,14,12,8,8,21,10)
)
我目前有一个非常缓慢的解决方案,使用循环和一些过滤来做到这一点,但是,更好的解决方案是更优选的 . 我一直在尝试使用dplyr,但我无法弄清楚如何在数据分组后得到其他观察值的总和 .
通过上面的玩具示例,这里将是所需的输出:
desired_output = data.frame(
group_id = c(1,1,1,1,2,2,2,2),
value = c(10,12,14,12,8,8,21,10),
output = c(38,26,0,26,39,39,0,21)
)
为了找到已经发布的解决方案,我没有看到一个明确的答案,它解释了如何将一组中的每个观察结果与其他观察结果进行比较,并按照某些标准对该组进行筛选 . 我更喜欢基于dplyr的解决方案,但如果有高效的base-R或data.table解决方案,我会同样感激!
4 回答
使用
tidyverse
. 诀窍是使用map_dbl
循环每个value
.mutate行中的
value
是你的value
'subcolumn'(该组),而.x
是你正在循环的元素 .a base solution
不太紧凑,有点棘手,但速度更快,仅使用
data.table
.诀窍在于,一旦您的数据按每个
group_id
的值按降序排序,您需要计算的是累计和group_id
,这非常快 .每当
value
在组内多次出现时,您希望保留最后一次累积总和,该总和已考虑到之前发生的所有事件 .该解决方案比为观察基准提出的替代方案快了~2501587次 . 它可以在不到一分钟的时间内完成最多
10^8
次观测 .我用
sys.Time()
使用以下基准计算时间:使用R base
*apply
函数 . 不像@Moody_Mudskipper那样可读,但是相同的输出没有任何额外的包 .这是一个简单的非等连接问题: