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

如何在R数据框中按条件切换参考行计算日期差并标记独立事件

问题描述

在同一受试者(按ID分组)有多条日期观测记录的场景下,需完成以下操作:

  • 计算每条记录日期与当前参考日期的天数差值
  • 默认参考日期为组内第一条记录的日期
  • 当某条记录的日期与当前参考日期差值超过28天时,将该日期设为新参考日期,以此识别独立事件

初始数据集

dfi = structure(list(ID = c(1, 1, 2, 2, 2, 2, 3, 3, 3), date_ric = c("2018-03-09", 
"2018-03-21", "2003-11-30", "2003-12-16", "2004-02-05", "2004-02-10", 
"2006-02-23", "2006-02-24", "2014-09-25")), class = "data.frame", row.names = c(NA, 
-9L))

数据预览:

> dfi
  ID   date_ric
1  1 2018-03-09
2  1 2018-03-21
3  2 2003-11-30
4  2 2003-12-16
5  2 2004-02-05
6  2 2004-02-10
7  3 2006-02-23
8  3 2006-02-24
9  3 2014-09-25

期望输出数据集

需生成包含以下字段的结果:

  • ID_n:组内记录的序号
  • diff.dd:当前日期与对应参考日期的天数差值
  • keep:标记是否为新参考日期(1表示是,0表示否)
dfo = structure(list(ID = c(1, 1, 2, 2, 2, 2, 3, 3, 3), date_ric = c("2018-03-09", 
"2018-03-21", "2003-11-30", "2003-12-16", "2004-02-05", "2004-02-10", 
"2006-02-23", "2006-02-24", "2014-09-25"), ID_n = c(1, 2, 1, 
2, 3, 4, 1, 2, 3), diff.dd = c(0, 12, 0, 16, 67, 5, 0, 1, 3136
), keep = c(1, 0, 1, 0, 1, 0, 1, 0, 1)), class = "data.frame", row.names = c(NA, 
-9L))

结果预览:

> dfo
  ID   date_ric ID_n diff.dd keep
1  1 2018-03-09    1       0    1
2  1 2018-03-21    2      12    0
3  2 2003-11-30    1       0    1
4  2 2003-12-16    2      16    0
5  2 2004-02-05    3      67    1
6  2 2004-02-10    4       5    0
7  3 2006-02-23    1       0    1
8  3 2006-02-24    2       1    0
9  3 2014-09-25    3    3136    1

遇到的问题

已尝试用for/while循环实现组内计数器,但无法在日期差值超过28天时自动切换新参考日期,也无法正确计算新参考日期后的差值(例如受试者2的第5条记录后续的差值计算)。


解决方案

使用dplyr结合purrr的accumulate函数实现,无需手动写循环,逻辑更清晰:

library(dplyr)
library(purrr)
library(lubridate)

# 处理数据
df_processed <- dfi %>%
  # 转换字符日期为日期格式
  mutate(date_ric = ymd(date_ric)) %>%
  group_by(ID) %>%
  # 生成组内序号
  mutate(ID_n = row_number(),
         # 追踪并更新参考日期
         ref_date = accumulate(date_ric, ~if_else(.y - .x > 28, .y, .x)),
         # 计算与当前参考日期的天数差
         diff.dd = as.integer(date_ric - ref_date),
         # 标记是否为新参考日期
         keep = as.integer(diff.dd == 0)) %>%
  ungroup()

# 查看结果
df_processed

代码说明

  1. 日期格式转换:用lubridate::ymd将字符型日期转为标准日期格式,支持差值计算
  2. 组内序号生成:row_number()直接生成组内记录的序号ID_n
  3. 参考日期追踪:accumulate函数逐个遍历组内日期,当当前日期与前一个参考日期差值超过28天时,自动更新参考日期为当前日期,否则保持原参考日期
  4. 差值计算:直接用当前日期减去参考日期,转为整数得到天数差diff.dd
  5. 参考点标记:当diff.dd为0时,说明该日期是新参考日期,标记keep=1,否则为0

运行后结果与期望输出完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 15:05:07