R 如何在数据表中生成一个向量,该向量基于另一个向量的值范围对子集进行求和?
我在R中试图做的是在下面的data.table中添加一个向量,称为RecentActivity,它对活动进行逐行求和计算,只包括周数不超过2周前的总和中的活动值(按ID) 例如:如果在第2周测量某个ID,我希望RecentActivity将该ID的所有值相加,其中周等于1或2。如果在第7周测量,总和需要包含第6周和第7周的活动值。在第一周中,只需要包括第1周 我想在data.table中找到答案,因为它的处理速度很快 这是我要将RecentActivity向量添加到的数据:R 如何在数据表中生成一个向量,该向量基于另一个向量的值范围对子集进行求和?,r,data.table,subset,R,Data.table,Subset,我在R中试图做的是在下面的data.table中添加一个向量,称为RecentActivity,它对活动进行逐行求和计算,只包括周数不超过2周前的总和中的活动值(按ID) 例如:如果在第2周测量某个ID,我希望RecentActivity将该ID的所有值相加,其中周等于1或2。如果在第7周测量,总和需要包含第6周和第7周的活动值。在第一周中,只需要包括第1周 我想在data.table中找到答案,因为它的处理速度很快 这是我要将RecentActivity向量添加到的数据: x <- da
x <- data.table(ID = c(1,1,1,2,2,2,3,4,4,4,4),
Week = c(1,2,7,1,20,21,1,1,2,5,6),
Activity = c(5,2,3,1,0,4,3,8,2,5,3))
x以下是构造新分组变量的解决方案:
x <- data.table(ID = c(1,1,1,2,2,2,3,4,4,4,4),
Week = c(1,2,7,1,20,21,1,1,2,5,6),
Activity = c(5,2,3,1,0,4,3,8,2,5,3))
x[, group:=cumsum((Week-shift(Week))>2 | is.na(shift(Week))), ID]
x[, RecentActivity:=cumsum(Activity), by=.(ID, group)][]
# > x[, RecentActivity:=cumsum(Activity), by=.(ID, group)][]
# ID Week Activity group RecentActivity
# 1: 1 1 5 1 5
# 2: 1 2 2 1 7
# 3: 1 7 3 2 3
# 4: 2 1 1 1 1
# 5: 2 20 0 2 0
# 6: 2 21 4 2 4
# 7: 3 1 3 1 3
# 8: 4 1 8 1 8
# 9: 4 2 2 1 10
# 10: 4 5 5 2 5
# 11: 4 6 3 2 8
另一种方法:
x[x[, .(ID, Week = Week + 1, Activity)],
RecentActivity := Activity + i.Activity, on = c('ID','Week')]
x[is.na(RecentActivity), RecentActivity := Activity]
x
# ID Week Activity RecentActivity
# 1: 1 1 5 5
# 2: 1 2 2 7
# 3: 1 7 3 3
# 4: 2 1 1 1
# 5: 2 20 0 0
# 6: 2 21 4 4
# 7: 3 1 3 3
# 8: 4 1 8 8
# 9: 4 2 2 10
# 10: 4 5 5 5
# 11: 4 6 3 8
正如Frank所建议的,我们还可以为RecentActivity
设置默认值,然后添加前一周的活动:
x[, RecentActivity := Activity]
x[x[, .(ID, Week = Week + 1, Activity)],
RecentActivity := RecentActivity + i.Activity, on = c('ID','Week')]
是否x[,c(“dwn”,“up”):=(第2周,第1周)];x[x,sum(Activity),on=(ID,Week>dwn,Week
适合你吗?有些价值观似乎并不适用match@DavidArenburg非常感谢你!工作起来很有魅力。@Bas,如果您喜欢Arenburg评论中的优雅解决方案,则无需接受一个答案。Fwiw,David的评论答案没有向表中添加列或其他内容(?),而是创建一个新表,因此我猜它是不完整的。顺便说一句,你可以做DT[,v:=默认值];DT[mDT,on=,v:=expr]
我想不是事后根据NAs分配默认值。@mt1022 Arenburg的回答足以让我明白如何解决我的问题,但Frank认为你的答案更完整是对的,因为它还添加了我想要的向量。谢谢你们两位。
x[, RecentActivity:=cumsum(Activity), by=.(ID, cumsum((Week-shift(Week))>2 | is.na(shift(Week))))][]
x[x[, .(ID, Week = Week + 1, Activity)],
RecentActivity := Activity + i.Activity, on = c('ID','Week')]
x[is.na(RecentActivity), RecentActivity := Activity]
x
# ID Week Activity RecentActivity
# 1: 1 1 5 5
# 2: 1 2 2 7
# 3: 1 7 3 3
# 4: 2 1 1 1
# 5: 2 20 0 0
# 6: 2 21 4 4
# 7: 3 1 3 3
# 8: 4 1 8 8
# 9: 4 2 2 10
# 10: 4 5 5 5
# 11: 4 6 3 8
x[, RecentActivity := Activity]
x[x[, .(ID, Week = Week + 1, Activity)],
RecentActivity := RecentActivity + i.Activity, on = c('ID','Week')]