You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按分组计算日期的滚动7天累计剂量?

滚动计算分组内7天累计剂量问题

需求说明

  • 创建total_dose变量,持续累加dosage的值
  • 当某条dosage记录距离当前记录超过7天时,从total_dose中减去该值,滚动执行
  • 当pid(患者ID)或medname(药物名称)变更时,total_dose需重新开始计数

示例数据集

pid    medname    date              route     dosage  
1  1     drugA    2023-04-15 17:30:00 patch     30      
2  1     drugA    2023-04-16 11:45:00 patch     30      
3  1     drugA    2023-04-17 10:30:00 patch     30      
4  2     drugB    2023-04-27 22:00:00 patch     30      
5  2     drugB    2023-04-30 13:15:00 patch     30      
6  2     drugB    2023-05-10 13:15:00 patch     30      
7  2     drugA    2023-05-11 06:30:00 patch     30          

期望输出

pid    medname    date              route     dosage   total_dose
1  1     drugA    2023-04-15 17:30:00 patch     30       30
2  1     drugA    2023-04-16 11:45:00 patch     30       60
3  1     drugA    2023-04-17 10:30:00 patch     30       90
4  2     drugB    2023-04-27 22:00:00 patch     30       30
5  2     drugB    2023-04-30 13:15:00 patch     30       60
6  2     drugB    2023-05-10 13:15:00 patch     30       30
7  2     drugA    2023-05-11 06:30:00 patch     30       30

已尝试的代码

方法一:使用transform与ave

df2 <- transform(df1, total_dosage = ave(dosage, list(pid, medname,
                      cumsum(c(0, diff(as.numeric(date - date[1]))) > 604800)), 
                 FUN = cumsum))

方法二:结合group_by与transform

df2 <- df1 %>% 
  group_by(pid, medname) %>% 
  arrange(date, .by_group = TRUE) 

df3 <- transform(df2,
        total_dose = ave(dose, cumsum(c(0, diff(as.numeric(date - date[1]))) > 604800), 
                 FUN=cumsum))

方法三:扩展分组逻辑

df2 <- df1 %>% 
  group_by(pid, medname) %>% 
  arrange(date, .by_group = TRUE) 

df3 <- transform(df2, 
            time_since_first_dose = cumsum(c(0, diff(as.numeric(date - date[1])))), 
            group_change = cumsum(c(TRUE, diff(pid) != 0 | diff(medname) != 0)), 
            total_dose = ave(dosage, group_change, time_since_first_dose, FUN=cumsum))

正确解决方案

之前的尝试仅按固定时间切割分组累加,未实现滚动移除超过7天记录的核心逻辑。以下用dplyr结合slider包实现需求:

代码实现

# 安装并加载依赖包
if (!require("dplyr")) install.packages("dplyr")
if (!require("slider")) install.packages("slider")
library(dplyr)
library(slider)

# 数据处理
df_result <- df1 %>%
  # 转换日期为时间格式(若未转换)
  mutate(date = as.POSIXct(date)) %>%
  # 按患者、药物分组,组内按日期排序
  group_by(pid, medname) %>%
  arrange(date, .by_group = TRUE) %>%
  # 计算滚动7天内的剂量总和
  mutate(total_dose = slide_dbl(
    .x = dosage,
    .i = date,
    .f = sum,
    .before = days(7),
    .complete = FALSE
  )) %>%
  ungroup()

代码说明

  • slide_dbl是slider包的滑动窗口函数,专门处理时序滚动计算
  • .i = date指定以日期为窗口索引,确保窗口范围基于实际时间
  • .before = days(7)定义窗口为当前日期往前推7天的范围
  • .complete = FALSE表示即使窗口未填满7天,也计算现有记录的总和,符合持续累加的需求

运行后即可得到期望输出。


内容的提问来源于stack exchange,提问作者db2020

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 17:13:13