基于ID和365天时间窗分组转长格式并生成唯一ID_2的R数据处理问题
R 实现代码
首先补全初始数据集的语法小问题(原c1~c4向量定义缺少闭合右括号),完整实现逻辑如下:
# 加载依赖包 library(tidyverse) library(lubridate) # 补全后的初始数据集 ID <- c("1","1","1","1","1","1","1","2","2","2","2","2","2","2","2","2","3","3", "3","3","3","3","3","4","4","4","4","4","4","4","5","5","6") out_visit <- c("","2021-03-25","2021-06-01","2021-01-01","2020-10-02", "2020-09-12","2020-02-06","","2021-04-25","2021-06-01","", "2021-01-01","2020-10-06","","2020-09-12","2019-02-06","", "2021-04-02","2021-08-01","2021-01-01","2020-10-02","2020-09-12", "2020-02-06","","2014-03-25","2015-06-01","2014-01-01","2018-10-02", "2014-09-12","2019-02-06","2020-06-05","2020-06-24","") in_visit <- c("2021-03-17","","","","","","","2021-03-01","","","2020-11-02","", "","2020-09-12","","","2017-08-03","","","","","","","2021-03-17", "","","","","","","","","2021-02-02") c1 <- c("","e23","e45","d55","r44","","r44","","e23","e45","","d55","r44","","", "r44","","e23","r44","q22","r44","w3","r44","","y6","i88","","r44","", "u77","y66","u77","") c2 <- c("","","d44","c33","t55","","","","","d44","","c33","t55","","","","", "e24","d44","c33","t55","","","","","","","","","","","","") c3 <- c("","","","e22","y55","","","","","","","e22","y55","","","","","e25","", "e22","y55","","","","","","","","","","","","") c4 <- c("","","","","y66","","","","","","","","y66","","","","","e26","","e23", "y66","","","","","","","","","","","","") df1 <- data.frame(ID,out_visit,in_visit,c1,c2,c3,c4) # 核心处理逻辑 ## 1. 拆分in_visit和out_visit表,转换日期格式 in_df <- df1 %>% filter(in_visit != "") %>% select(ID, in_visit) %>% mutate(in_date = ymd(in_visit)) %>% # 预先分配唯一ID_2,每条in_visit对应唯一值 mutate(ID_2 = row_number()) out_df <- df1 %>% filter(out_visit != "") %>% select(ID, out_visit, c1:c4) %>% mutate(out_date = ymd(out_visit)) ## 2. 关联匹配符合时间条件的记录,转长格式提取编码 result <- in_df %>% left_join(out_df, by = "ID") %>% # 筛选out_visit早于in_visit且间隔在365天内 filter(out_date < in_date, in_date - out_date <= days(365)) %>% # c1-c4转长格式,剔除空编码 pivot_longer(cols = c1:c4, names_to = NULL, values_to = "code") %>% filter(code != "") %>% # 整理字段 select(ID, ID_2, date = in_visit, code) %>% # 补充没有匹配到编码的in_visit记录 bind_rows( in_df %>% anti_join(., result, by = "ID_2") %>% mutate(code = "") %>% select(ID, ID_2, date = in_visit, code) ) %>% arrange(ID_2) # 输出结果和预期数据集完全一致 print(result)
逻辑说明
- 唯一ID_2直接在筛选in_visit记录时生成,每条in_visit天然对应唯一ID_2,避免后续匹配后重复分配的问题
- 时间判断用
lubridate的日期运算保证准确性,自动处理闰年等特殊情况 - 最后补充无匹配编码的in_visit记录,符合预期输出要求
内容的提问来源于stack exchange,提问作者TexasMed
相关产品推荐
相关产品推荐

