基于dplyr识别28天周期内的首次就诊与复诊记录
就诊记录分组处理:识别间隔28天的首次就诊及复诊
原始数据集
以下是个人就诊记录:
| Identifier | date |
|---|---|
| "A1" | "28/01/2020" |
| "A1" | "01/04/2020" |
| "A1" | "16/08/2020" |
| "A1" | "20/08/2020" |
| "A1" | "30/08/2020" |
| "A1" | "31/10/2020" |
| "A1" | "14/11/2020" |
| "A1" | "26/11/2020" |
| "A1" | "25/12/2020" |
| "A1" | "04/05/2021" |
| "A1" | "08/05/2021" |
| "A1" | "26/07/2021" |
数据集的dput代码:
data <- structure(list(identifier = c("A1", "A1", "A1", "A1", "A1", "A1", "A1", "A1", "A1", "A1", "A1", "A1", "A1"), date = structure(c(18520, 18504, 18621, 18580, 18353, 18751, 18289, 18494, 18592, 18490, 18755, 18834, 18566), class = "Date")), row.names = c(NA, -13L), class = "data.frame")
需求说明
该个体就诊时间不规律,部分复诊间隔在28天内。需要按日期排序后,识别出间隔至少28天的首次就诊(索引就诊),以及28天窗口期内的复诊,最终生成包含index_visit(是否为索引就诊)和index_id(所属索引组ID)的数据集。
目标结果
处理后的数据格式如下:
| Identifier | date | index_visit | index_id |
|---|---|---|---|
| "A1" | "28/01/2020" | TRUE | 1 |
| "A1" | "01/04/2020" | TRUE | 2 |
| "A1" | "16/08/2020" | TRUE | 3 |
| "A1" | "20/08/2020" | FALSE | 3 |
| "A1" | "30/08/2020" | FALSE | 3 |
| "A1" | "31/10/2020" | TRUE | 4 |
| "A1" | "14/11/2020" | FALSE | 4 |
| "A1" | "26/11/2020" | FALSE | 4 |
| "A1" | "25/12/2020" | TRUE | 5 |
| "A1" | "04/05/2021" | TRUE | 6 |
| "A1" | "08/05/2021" | FALSE | 6 |
| "A1" | "26/07/2021" | TRUE | 7 |
dplyr解决方案
使用dplyr包实现需求,步骤如下:
- 按个体和日期排序,确保时间顺序正确;
- 跟踪每个就诊记录与最近一次索引就诊的时间间隔,判断是否需要生成新的索引;
- 根据索引标识生成连续的
index_id。
代码实现:
library(dplyr) processed_data <- data %>% # 按个体和日期排序 arrange(identifier, date) %>% group_by(identifier) %>% mutate( # 初始标记第一条记录为索引就诊 index_visit = row_number() == 1, # 记录当前索引就诊的日期,初始为第一条日期 current_index_date = ifelse(index_visit, date, NA) ) %>% # 向前填充索引日期,直到遇到新的索引就诊 fill(current_index_date, .direction = "down") %>% mutate( # 计算当前日期与对应索引日期的间隔 days_since_index = as.numeric(date - current_index_date), # 判断是否需要更新为新的索引就诊:间隔≥28天则标记为新索引 index_visit = ifelse(days_since_index >= 28 | row_number() == 1, TRUE, FALSE), # 重新更新索引日期:如果是新索引,替换为当前日期 current_index_date = ifelse(index_visit, date, current_index_date) ) %>% # 再次填充,确保后续复诊关联正确的索引日期 fill(current_index_date, .direction = "down") %>% # 生成连续的index_id mutate(index_id = cumsum(index_visit)) %>% # 移除中间辅助列 select(-current_index_date, -days_since_index) %>% ungroup() # 查看结果 print(processed_data)
代码说明
arrange确保数据按时间顺序排列,这是后续计算的基础;fill用于将索引就诊的日期向下填充,让同一组内的复诊记录关联到对应的索引日期;cumsum(index_visit)通过累加索引就诊的标记,生成连续的index_id,每个新索引对应一个递增的ID;- 两次判断
index_visit是为了确保首次就诊和间隔≥28天的就诊都被标记为索引就诊,同时修正中间步骤的索引日期。
内容的提问来源于stack exchange,提问作者hisspott
相关产品推荐
相关产品推荐

