基于日期条件合并抗生素数据行并保留附属列
问题:处理非完全时间匹配的抗生素联合治疗数据
我有按患者ID分组的长格式抗生素疗程数据,已处理完起止时间完全匹配的联合治疗。现在需要处理起止时间不完全对齐但符合特定模式的联合治疗:以氨苄西林(amp)为基础抗生素,若头孢曲松(ceft)、庆大霉素(gent)或链霉素在其启动后1-3天内启动,视为联合治疗。
具体需求:
- 检查所有使用氨苄西林患者的其他药物
- 若支持药物的
abx_start在氨苄西林abx_start的1-3天范围内:- 将氨苄西林行的
abx列改为联合标识(如amp, ceft) - 保留氨苄西林行的所有其他数据
- 删除支持药物对应的行
- 将氨苄西林行的
示例数据
ID <- c('C1', 'C1', 'C2', 'C2', 'C2', 'C3', 'C4', 'C4', 'C5', 'C5', 'C6') abx <- c('amp', 'ceft', 'amp', 'ceft', 'vanc', 'amp', 'amp', 'gent', 'amp', 'vanc', 'vanc') abx_start <- c(as.Date('1/1/2023'), as.Date('1/3/2023'), as.Date('1/10/2023'), as.Date('1/15/2023'), as.Date('1/1/2023'), as.Date('1/11/2023'), as.Date('1/20/2023'), as.Date('1/21/2023'), as.Date('1/12/2023'), as.Date('1/15/2023'), as.Date('1/1/2023')) abx_stop <- c(as.Date('1/30/2023'), as.Date('1/29/2023'), as.Date('2/14/2023'), as.Date('2/14/2023'),as.Date('1/3/2023'), as.Date('1/24/2023'), as.Date('2/10/2023'), as.Date('2/08/2023'), as.Date('1/30/2023'), as.Date('1/15/2023'), as.Date('1/14/2023')) cx_final <- c(as.Date('1/2/2023'), as.Date('1/2/2023'), as.Date('1/10/2023'), as.Date('1/10/2023'), as.Date('1/3/2023'), as.Date('1/11/2023'), as.Date('1/18/2023'), as.Date('1/18/2023'), as.Date('1/11/2023'), as.Date('1/11/2023'), as.Date('1/1/2023')) rrt <- c('HD', 'HD', 'none', 'none', 'none', 'none', 'RRT', 'RRT', 'none', 'none', 'HD') death <- c(as.Date('12/30/2023'), as.Date('12/30/2023'), as.Date('12/30/2023'), as.Date('12/30/2023'), as.Date('12/30/2023'), as.Date('1/25/2023'), as.Date('2/10/2023'), as.Date('2/10/2023'), as.Date('1/30/2023'), as.Date('1/30/2023'), as.Date('12/30/2023')) df_abx <- data.frame(ID, abx, abx_start, abx_stop, cx_final, rrt, death)
期望处理结果
| ID | abx | abx_start | abx_stop | cx_final | rrt | death |
|---|---|---|---|---|---|---|
| C1 | amp, ceft | 2023-01-01 | 2023-01-30 | 2023-01-02 | HD | 2023-12-30 |
| C2 | amp | 2023-01-10 | 2023-02-14 | 2023-01-10 | none | 2023-12-30 |
| C2 | ceft | 2023-01-15 | 2023-02-14 | 2023-01-10 | none | 2023-12-30 |
| C2 | vanc | 2023-01-01 | 2023-01-03 | 2023-01-03 | none | 2023-12-30 |
| C3 | amp | 2023-01-11 | 2023-01-24 | 2023-01-11 | none | 2023-01-25 |
| C4 | amp, gent | 2023-01-20 | 2023-02-10 | 2023-01-18 | RRT | 2023-02-10 |
| C5 | amp | 2023-01-12 | 2023-01-30 | 2023-01-11 | none | 2023-01-30 |
| C5 | vanc | 2023-01-15 | 2023-01-15 | 2023-01-11 | none | 2023-01-30 |
| C6 | vanc | 2023-01-01 | 2023-01-14 | 2023-01-01 | HD | 2023-12-30 |
解决方案(使用dplyr)
核心思路是按患者分组后,为每一行匹配符合条件的联合药物,合并标识后过滤掉被合并的行:
library(dplyr) # 定义需要匹配的支持药物列表 support_abx <- c("ceft", "gent") # 链霉素可自行添加到列表中 df_result <- df_abx %>% group_by(ID) %>% # 为每个amp行匹配符合时间条件的支持药物 mutate( # 找到当前患者中,属于支持药物且启动时间在amp启动后1-3天内的药物 matched_abx = ifelse( abx == "amp", paste(abx, paste(abx[abx %in% support_abx & abx_start >= abx_start + 1 & abx_start <= abx_start + 3], collapse = ", "), sep = ", "), abx ), # 标记需要保留的行:amp行保留,非amp行仅当未被匹配时保留 keep = ifelse( abx != "amp", !(abx %in% support_abx & any(abx_start >= abx[abx == "amp"] + 1 & abx_start <= abx[abx == "amp"] + 3)), TRUE ) ) %>% # 处理amp行的合并标识(避免出现"amp, "这种多余逗号) mutate(matched_abx = gsub(", $", "", matched_abx)) %>% # 过滤掉不需要保留的行,并重命名abx列 filter(keep) %>% rename(abx = matched_abx) %>% # 移除临时列 select(-keep) %>% ungroup() # 查看结果 print(df_result, n = Inf)
代码说明
- 分组匹配:按
ID分组后,为每个amp行查找同组内属于支持药物、且启动时间在amp启动后1-3天内的药物。 - 合并标识:将匹配到的药物与
amp合并为联合标识,处理多余逗号的情况。 - 标记保留行:非
amp的支持药物行,若被amp匹配到则标记为删除,否则保留;amp行始终保留。 - 过滤整理:过滤掉标记为删除的行,重命名列并清理临时变量。
这个方案能完整保留amp行的所有附属列数据,同时准确合并符合条件的联合治疗行,避免数据丢失。
内容的提问来源于stack exchange,提问作者TMHRLA3
相关产品推荐
相关产品推荐

