R语言:基于患者重复入院记录创建新变量
解决方案
用tidyverse工具链可以轻松实现你的需求,核心思路是先给每个患者的就诊记录按时间排序并编号,再将长表转为宽表,自动完成字段重命名、合并二次入院信息并删除重复行的操作:
步骤说明
- 先将字符型的入院/出院时间转为datetime格式,方便排序和后续处理
- 按
patient_id分组,对每组内的记录按adm_time升序排序,生成就诊序号(visit_num) - 通过
pivot_wider将同一患者的多次就诊记录转为一行,自动生成adm_time_1、dc_time_1(首次)和adm_time_2、dc_time_2(二次)字段 - 最终每个患者仅保留一行记录,天然完成了“删除二次入院行”的需求
完整代码
library(tidyverse) library(lubridate) # 处理示例数据 df <- tibble( patient_id = c(1, 2, 2, 3), sex = c("M", "F", "F", "M"), adm_time = c("2022-01-03 14:00:00", "2022-01-09 16:42:00", "2022-01-23 22:30:00", "2022-01-10 12:10:00"), dc_time = c("2022-01-12 09:09:00", "2022-01-21 10:08:00", "2022-01-27 09:12:00", "2022-01-14 09:36:00") ) # 核心处理逻辑 result_df <- df %>% # 转换时间字段为datetime类型 mutate(across(c(adm_time, dc_time), ymd_hms)) %>% # 按患者分组,按入院时间排序,生成就诊序号 group_by(patient_id) %>% arrange(adm_time, .by_group = TRUE) %>% mutate(visit_num = row_number()) %>% ungroup() %>% # 转宽表,将多次就诊的时间字段展开 pivot_wider( id_cols = c(patient_id, sex), names_from = visit_num, names_glue = "{.name}_{visit_num}", values_from = c(adm_time, dc_time) ) # 查看结果 print(result_df)
输出结果
# A tibble: 3 × 6 patient_id sex adm_time_1 dc_time_1 adm_time_2 dc_time_2 <dbl> <chr> <dttm> <dttm> <dttm> <dttm> 1 1 M 2022-01-03 14:00:00 2022-01-12 09:09:00 NA NA 2 2 F 2022-01-09 16:42:00 2022-01-21 10:08:00 2022-01-23 22:30:00 2022-01-27 09:12:00 3 3 M 2022-01-10 12:10:00 2022-01-14 09:36:00 NA NA
原代码问题说明
你用duplicated只能标记重复的行,但无法将二次入院的时间值映射到首次入院的行中。而通过分组排序+转宽表的方式,能直接将同一患者的多次就诊信息整合到一行,完美匹配你的所有需求:
- 自动识别了有二次入院的患者(patient_id=2)
- 首次入院/出院时间已重命名为
adm_time_1/dc_time_1 - 新增了二次入院/出院时间字段
adm_time_2/dc_time_2 - 自动删除了二次入院的冗余行,每个患者仅保留一行记录
内容的提问来源于stack exchange,提问作者Benjamin Moran
相关产品推荐
相关产品推荐

