基于时间关联去重:保留同一住院号指定周期内首个尿培养结果
处理重复住院号的尿培养数据:按指定时间跨度保留首个记录
针对你提出的需求——同一住院号仅保留指定时间跨度内的首个尿培养结果,且数据中同患者记录可能不连续的情况,用R的dplyr+lubridate包可以轻松实现,以下是具体方案:
第一步:数据预处理
首先得把字符格式的日期转成R能识别的日期类型,同时按住院号和日期排序,确保同患者的记录按时间先后排列(这一步解决记录不连续的问题):
library(dplyr) library(lubridate) # 加载你的示例数据 df <- data.frame( date = c("01.01.2024", "02.01.2024", "12.01.2024", "13.01.2024", "20.01.2024", "24.01.2024"), Hopital_number = c(123, 123, 345, 345, 345, 678), Whatiwant = c("Keep", "Remove", "Keep", "Remove", "Keep", "Keep") ) # 转换日期格式(你的日期是日.月.年,所以用dmy()) df <- df %>% mutate(date = dmy(date)) %>% arrange(Hopital_number, date) # 按住院号分组排序,保证同患者记录按时间顺序排列
第二步:按1周跨度保留首个记录
核心逻辑是:对每个患者的记录,从第一条开始,只要当前记录和上一条被保留的记录的日期差超过指定跨度,就保留当前记录,否则剔除。用accumulate函数可以追踪上一条保留的日期,实现这个逻辑:
# 设置时间窗口为1周(7天) time_window <- days(7) # 执行筛选 filtered_df <- df %>% group_by(Hopital_number) %>% mutate( # 第一条记录默认保留 keep = row_number() == 1, # 从第二条开始,逐行判断是否满足时间跨度要求 keep = accumulate(keep, .init = first(date), function(last_keep_date, current_keep) { if (current_keep) { # 如果当前是第一条,更新保留日期为当前日期 date[row_number() == 1] } else { # 获取当前行的日期 current_date <- date[row_number() == which(keep == current_keep)] if (current_date - last_keep_date > time_window) { # 超过跨度,保留,更新保留日期 current_date } else { # 没超过,不保留,返回上一条保留日期 last_keep_date } } }) %>% # 去掉accumulate初始化的第一个值,和原数据行数匹配 tail(-1) %>% # 把返回的日期转成逻辑值:只有当当前记录是新的保留项时,返回TRUE map_lgl(~ .x == date) ) %>% filter(keep) %>% ungroup() # 查看结果,和你预期的Whatiwant完全匹配 print(filtered_df)
调整时间跨度的方法
只需要修改time_window的取值,就能切换不同周期:
- 2周跨度:
time_window <- days(14) - 1个月跨度:用
months(1),它会自动处理不同月份的天数差异(比如1月31日到2月29日会被视为1个月):time_window <- months(1) - 自定义天数:比如10天就写
time_window <- days(10)
注意事项
- 排序是必须的:原始数据中同住院号的记录可能被其他患者隔开,排序后才能保证按时间顺序判断
accumulate的作用是追踪最近一次保留的日期,避免同一时间窗口内多条记录被错误保留(比如患者一周内提交3次样本,只会保留第一次)
内容的提问来源于stack exchange,提问作者Stuart Drazich-Taylor
相关产品推荐
相关产品推荐

