临床试验重复观测数据的识别与合并技术问询
解决方案:基于"四标识三一致"规则合并重复患者记录并补全缺失值
要实现按规则识别重复患者并合并补全数据,我们可以通过图论连通分量关联所有符合匹配条件的记录,再对同一患者的记录进行数据合并,具体步骤如下:
1. 核心思路
- 针对每一组3个标识的组合,找出所有在这三个标识上完全匹配的记录对
- 将这些记录对视为图中的边,所有关联的记录形成一个连通分量(即同一患者)
- 对每个连通分量内的记录进行合并,用非缺失值填充缺失字段
2. 代码实现
加载依赖包
library(tidyverse) library(igraph) library(lubridate)
示例数据
tibble(Name = c("Pedro", "Pedro","Pedro","Cristina","Walter","Sara","Mateus"), Birth = dmy(c("29/07/1994","29/07/1994","29/07/1994","01/04/1960", "22/12/1956", "20/02/1997","25/07/1994")), CNS = c("700",NA,"700","701","702","703","704"), Document = c("104","104",NA,"105","106","107","108"), SystolicBP1 = c(NA,NA,120,160,152,114,NA), DiastolicBP1 = c(NA,NA,80,100,100,92,NA), SystolicBP2 = c(NA,NA,NA,148,NA,NA,100), DiastolicBP2= c(NA,NA,NA,90,NA,NA,82), HBA1c = c(7,7,7,8.2,8,9,6.5)) -> dt
步骤1:生成所有3标识组合的匹配记录对
为每个3标识组合,筛选出匹配的记录索引对:
# 定义标识变量 identifiers <- c("Name", "Birth", "CNS", "Document") # 生成所有3标识组合 comb <- combn(identifiers, 3) # 收集所有匹配的记录对 matches <- map_dfr(1:ncol(comb), function(col_idx) { cols <- comb[, col_idx] # 过滤含NA的组(题目说明标识缺失率极低,可忽略此类情况) dt %>% filter(if_all(all_of(cols), ~!is.na(.x))) %>% group_by(across(all_of(cols))) %>% filter(n() > 1) %>% mutate(record_id = row_number()) %>% select(record_id, all_of(cols)) %>% group_by(across(all_of(cols))) %>% summarise(pairs = list(t(combn(record_id, 2))), .groups = "drop") %>% unnest(pairs) %>% transmute(from = pairs[,1], to = pairs[,2]) }) # 去重重复边(如(1,2)和(2,1)视为同一条) matches <- matches %>% mutate(pair = map2_chr(from, to, ~paste(sort(c(.x, .y)), collapse = "-"))) %>% distinct(pair, .keep_all = TRUE) %>% select(from, to)
步骤2:构建图并获取连通分量(患者分组)
# 创建图对象 g <- graph_from_data_frame(matches, directed = FALSE, vertices = tibble(record_id = 1:nrow(dt))) # 获取每个记录的连通分量ID(即患者ID) patient_groups <- components(g)$membership %>% enframe(name = "record_id", value = "patient_id") # 将患者ID关联到原数据 dt_with_patient <- dt %>% mutate(record_id = 1:nrow(.)) %>% left_join(patient_groups, by = "record_id") %>% select(-record_id)
步骤3:按患者ID合并数据,补全缺失值
# 合并函数:对每个字段取第一个非缺失值(若多值一致则直接保留) merge_records <- function(df) { df %>% summarise(across(everything(), ~first(na.omit(.x)))) } # 执行合并 final_data <- dt_with_patient %>% group_by(patient_id) %>% merge_records() %>% ungroup() # 查看结果 knitr::kable(final_data)
合并后的结果
| Name | Birth | CNS | Document | SystolicBP1 | DiastolicBP1 | SystolicBP2 | DiastolicBP2 | HBA1c | patient_id |
|---|---|---|---|---|---|---|---|---|---|
| Pedro | 1994-07-29 | 700 | 104 | 120 | 80 | NA | NA | 7.0 | 1 |
| Cristina | 1960-04-01 | 701 | 105 | 160 | 100 | 148 | 90 | 8.2 | 2 |
| Walter | 1956-12-22 | 702 | 106 | 152 | 100 | NA | NA | 8.0 | 3 |
| Sara | 1997-02-20 | 703 | 107 | 114 | 92 | NA | NA | 9.0 | 4 |
| Mateus | 1994-07-25 | 704 | 108 | NA | NA | 100 | 82 | 6.5 | 5 |
说明
- 该方法通过图论准确识别所有符合"四标识三一致"规则的重复患者,不会遗漏关联记录
- 合并时优先保留非缺失值,若同一字段存在多值冲突(如同一患者的同一字段有不同值),可修改
merge_records函数适配需求(例如取均值、标记冲突) - 基于题目中标识缺失率极低的前提,代码过滤了含NA的标识组合分组,避免误匹配
内容的提问来源于stack exchange,提问作者Pedro Henrique Faria
相关产品推荐
相关产品推荐

