在R中按条件为累积和补0(data.table实现)
解决方案
首先修正初始的data.table创建代码(ID值需要加引号,否则R会视为未定义变量):
library(data.table) DT <- data.table( ID = c("A","A","A","A","B","B","B","C","C","C","C"), date = c("2008-01-01","2009-01-01","2010-01-01","2011-01-01","1978-01-01","1982-01-01","1985-01-01","2001-01-01","2011-01-01","2015-01-01","2019-01-01"), Type = c(1,2,2,3,3,1,1,2,2,1,3), Days = c(18,333,26,57,48,10,17,212,55,64,18) )
接下来用简洁的代码实现需求:对每个ID,分别计算Type1、Type2、Type3的累积和(非对应Type时按0处理):
# 确保数据按ID和日期排序(若已排序可省略,但显式排序更稳妥) DT <- DT[order(ID, date)] # 批量生成三个累积和列 DT[, c(paste0("cumdays", 1:3)) := lapply(1:3, function(t) { cumsum(ifelse(Type == t, Days, 0)) }), by = ID]
代码说明
- 使用
lapply(1:3, ...)批量处理三个Type,避免重复编写代码 ifelse(Type == t, Days, 0)将非对应Type的Days替换为0,从根源上避免NAcumsum(...)按ID分组计算累积和,确保每个ID内的累积逻辑独立paste0("cumdays",1:3)自动生成目标列名,保持代码简洁
执行后得到的结果与期望输出一致:
ID date Type Days cumdays1 cumdays2 cumdays3 1: A 2008-01-01 1 18 18 0 0 2: A 2009-01-01 2 333 18 333 0 3: A 2010-01-01 2 26 18 359 0 4: A 2011-01-01 3 57 18 359 57 5: B 1978-01-01 3 48 0 0 48 6: B 1982-01-01 1 10 10 0 48 7: B 1985-01-01 1 17 27 0 48 8: C 2001-01-01 2 212 0 212 0 9: C 2011-01-01 2 55 0 267 0 10: C 2015-01-01 1 64 64 267 0 11: C 2019-01-01 3 18 64 267 18
内容的提问来源于stack exchange,提问作者Hong
相关产品推荐
相关产品推荐

