如何在R的data.table中按ID与周范围生成Activity求和向量RecentActivity
嗨,这个需求在data.table里有两种高效的实现方式,得看你的Week列是不是连续的——我给你分别讲讲:
先构造个示例数据方便测试
library(data.table) # 常规连续周的示例数据 dt <- data.table( ID = rep(c("A", "B"), each = 5), Week = rep(1:5, 2), Activity = c(3, 5, 2, 7, 1, 4, 2, 6, 3, 8) ) # 带缺失周的示例数据(用来测试第二种方法) dt_missing <- data.table( ID = rep("A", 4), Week = c(1,3,4,6), Activity = c(3,2,7,1) )
场景1:每个ID的Week是连续无缺失的
这种情况用frollsum(滚动求和)最效率,data.table专门优化过这个函数,处理百万级数据都不在话下:
# 按ID分组,计算窗口大小为2的滚动求和,右端对齐当前行 dt[, RecentActivity := frollsum(Activity, n = 2, align = "right"), by = ID]
运行后你会得到这样的结果:
ID Week Activity RecentActivity 1: A 1 3 3 # 第1周只有自己 2: A 2 5 8 # 第1+2周的和 3: A 3 2 7 # 第2+3周的和 4: A 4 7 9 # 第3+4周的和 5: A 5 1 8 # 第4+5周的和 6: B 1 4 4 7: B 2 2 6 8: B 3 6 8 9: B 4 3 9 10: B 5 8 11
解释:by=ID确保每个ID单独计算窗口,n=2表示取当前行和前一行的数值,align="right"让窗口右端对齐当前行——完美匹配你要的“当前周及前1周(如果存在)”的求和逻辑。
场景2:Week可能有缺失(比如某ID跳过了某一周)
如果你的数据里存在Week不连续的情况,按行位置的滚动窗口就会出错(比如把第1周和第3周当成连续的加起来),这时候用非等连接更靠谱,它直接按Week的数值匹配:
# 先按ID和Week排序,保证逻辑正确 setorder(dt_missing, ID, Week) # 非等连接:匹配同一ID下Week在[当前Week-1, 当前Week]的所有行,求和Activity dt_missing[dt_missing, on = .(ID, Week >= Week -1, Week <= Week), RecentActivity := sum(Activity), by = .EACHI]
运行后带缺失周的数据结果如下:
ID Week Activity RecentActivity 1: A 1 3 3 # 无前置周,仅自己 2: A 3 2 2 # 没有Week=2,仅自己 3: A 4 7 9 # Week=3+4的和 4: A 6 1 1 # 没有Week=5,仅自己
解释:非等连接的on = .(ID, Week >= Week -1, Week <= Week)表示,对每一行,找到同一ID下Week大于等于当前Week-1且小于等于当前Week的所有行,然后by=.EACHI对每一组匹配结果求和,赋值给当前行的RecentActivity。
总结
- 小数据集随便选,两种方式都能用;
- 大数据且Week连续:优先
frollsum,速度拉满; - Week可能缺失:用非等连接,逻辑精准。
内容的提问来源于stack exchange,提问作者Bas
相关产品推荐
相关产品推荐

