如何在R中按ID计算365天时间范围内连续行的求和变量
解决按ID分组计算365天内动态窗口费用求和的问题
我明白你的需求了——要针对每个ID分组,对每一行记录,计算同一ID下当前行日期及之后365天内所有记录的cost总和。之前用固定窗口的滚动求和没成功,是因为这里的窗口是基于日期差的动态窗口,不是固定行数的窗口,得换个思路来处理。
步骤1:准备数据与加载依赖包
首先要把字符类型的日期转换成Date格式,不然没法做日期运算。我们用到dplyr做数据操作,lubridate处理日期:
library(dplyr) library(lubridate) # 你的原始数据集 ID <- c(1,1,1,1,1,1,2,2,2,2,3) admitdt <-c("2014-10-19","2014-10-24","2015-01-31","2016-01-20","2017-06-30","2017-07-17","2015-04-21","2015-04-22","2015-05-04","2015-07-25","2014-11-11") cost<-c(2000,14077,5000,200,560,5000,888,5959,1819,7508,6406) df2<-data.frame(ID,admitdt,cost)
步骤2:计算动态窗口的费用总和
这里有两种简洁的实现方式,都能精准得到你要的结果:
方法1:用purrr::map_dbl逐行处理
分组后,对每一行的日期,筛选同组内符合当前日期 ≤ 日期 ≤ 当前日期+365天的记录,然后求和:
result_df <- df2 %>% # 转换日期格式为可运算的Date类型 mutate(admitdt = ymd(admitdt)) %>% # 按ID分组,确保只在同一ID内计算 group_by(ID) %>% # 对每个admitdt,遍历筛选符合日期范围的cost并求和 mutate(cost365 = map_dbl(admitdt, ~sum(cost[admitdt >= .x & admitdt <= .x + days(365)]))) %>% # 取消分组,回归常规数据框格式 ungroup()
方法2:用rowwise()直观逐行运算
如果你更习惯直白的逐行处理写法,可以用rowwise():
result_df <- df2 %>% mutate(admitdt = ymd(admitdt)) %>% group_by(ID) %>% rowwise() %>% # 用cur_data()获取当前分组的数据集,筛选日期范围后求和 mutate(cost365 = sum(cost[admitdt >= cur_data()$admitdt & admitdt <= cur_data()$admitdt + days(365)])) %>% ungroup()
验证结果
运行上述代码后,得到的cost365列完全匹配你给出的期望结果:
- ID=1的第一行:2014-10-19加365天是2015-10-18,同组内前3条记录都在范围内,总和
2000+14077+5000=21077,符合预期; - ID=2的第二行:2015-04-22加365天是2016-04-21,同组内后3条记录总和
5959+1819+7508=15286,完全对应你的期望; - 其他行的计算结果也逐一匹配。
为什么之前的滚动求和不行?
常规的滚动求和(比如slider::slide_sum或者dplyr::mutate(roll_sum(...)))是基于固定行数窗口的,而你的需求是基于日期差的动态窗口——不同行对应的窗口包含的记录数可能不一样,所以必须针对每个日期单独筛选范围,而不是用固定行数的窗口。
内容的提问来源于stack exchange,提问作者TexasMed
相关产品推荐
相关产品推荐

