R语言中如何为医疗数据参与者生成等长唯一匿名ID
R实现SSN替换为等长唯一新ID的方案
核心逻辑
- 先提取所有唯一的原Patient_SSN,计算每个SSN对应的字符长度
- 为每个唯一SSN生成对应长度的不重复新ID,建立映射关系
- 将映射关系匹配回原数据集,替换原SSN字段
基础R实现(无需额外依赖包)
# 示例数据构造 Patient_Name = c("Alex", "Mary", "Sarah", "John", "Susan", "Jessica", "Sarah", "Karen", "Mary", "John") Patient_SSN = c(1234, 43251, 9320, 2901, 3229, 4291, 9320, 9218988, 43251 , 2901) Visit_Date = c('10_21', '10_21', '10_25', '10_25','10_26','10_27','10_28','10_28','10_28' ,'10_29') BMI = runif(10, min=12, max =25); data_hospital = data.frame(Patient_Name, Patient_SSN, BMI, Visit_Date) # 1. 提取唯一SSN,计算对应长度 unique_ssn <- unique(data_hospital$Patient_SSN) ssn_length <- nchar(as.character(unique_ssn)) # 2. 生成对应长度的唯一纯数字新ID set.seed(123) # 固定种子方便复现,实际使用可删除 new_id <- c() new_id <- mapply(function(len) { # 生成对应长度的随机数,范围是10^(len-1)到10^len -1,确保长度一致 repeat { id <- sample(10^(len-1):(10^len - 1), 1) # 确保新ID不重复 if (!id %in% new_id) break } return(id) }, len = ssn_length) # 3. 建立映射表 ssn_map <- data.frame( Patient_SSN = unique_ssn, New_Patient_ID = new_id ) # 4. 匹配回原数据集 data_hospital_new <- merge(data_hospital, ssn_map, by = "Patient_SSN", all.x = TRUE) # 可选:删除原SSN字段保护隐私 data_hospital_new$Patient_SSN <- NULL
运行后可验证:同一个患者的多次就诊记录New_Patient_ID完全一致,且新ID的字符长度和对应原SSN完全相同。比如原SSN为9218988的Karen,原长度为7,新ID也为7位数字;原SSN为43251的Mary两次就诊的新ID完全一致。
tidyverse版本(dplyr+stringr实现)
如果日常使用tidyverse生态,可以用更简洁的写法:
library(dplyr) library(stringr) set.seed(123) data_hospital_new <- data_hospital %>% # 按原SSN分组,生成分组级别的长度和唯一新ID group_by(Patient_SSN) %>% mutate( ssn_len = nchar(as.character(Patient_SSN)), New_Patient_ID = sample(10^(ssn_len[1]-1):(10^ssn_len[1] - 1), 1) ) %>% ungroup() %>% # 可选删除原SSN和临时长度字段 select(-Patient_SSN, -ssn_len)
注意事项
- 若需要新ID包含字母,可把随机生成部分替换为
stringi::stri_rand_strings(1, len, pattern = "[A-Za-z0-9]"),同时要确保生成的ID唯一 - 10000条量级的数据下上述方法运行效率足够,无需额外优化
- 固定
set.seed可以保证每次运行生成的新ID一致,需要随机化的场景删除该行即可
内容的提问来源于stack exchange,提问作者Identicon
相关产品推荐
相关产品推荐

