如何从多行ICD编码数据中提取虚拟变量(Dummy Variables)?
问题描述
我有大量以分号分隔的个体特征数据,每行结构如下(示例为合成数据):
id; ICD_Codes 1; F10.10; F11.21; F31.81 2; G89.29; M54.5; F31.4; F11.21; F17.200; F43.10; Z72.0 3; F14.10; F17.200; F31.81; F31.32; F10.21
注:每行的“列数”不固定。
需要提取每个ICD编码作为虚拟变量,用1/0标记个体是否存在对应编码,最终转换为宽格式表格或R DataFrame。
R语言解决方案
方法一:tidyverse工具链(推荐,简便高效)
使用tidyr和dplyr可以快速完成格式转换,代码简洁易读:
- 加载依赖包
library(tidyverse)
- 读取数据
如果是从文件读取:
# 处理分号分隔、可变列数的文本数据,自动去除多余空格 df_raw <- read_delim("your_data_path.txt", delim = ";", col_names = TRUE, trim_ws = TRUE)
如果用示例数据手动构造:
df_raw <- tibble( id = c(1, 2, 3), ICD_Codes = list( c("F10.10", "F11.21", "F31.81"), c("G89.29", "M54.5", "F31.4", "F11.21", "F17.200", "F43.10", "Z72.0"), c("F14.10", "F17.200", "F31.81", "F31.32", "F10.21") ) )
- 转换为目标格式
df_result <- df_raw %>% unnest_longer(ICD_Codes) %>% # 将每行的ICD编码拆分为单独行 mutate(flag = 1) %>% # 标记该编码存在 pivot_wider( # 转换为宽格式,缺失值填充0 names_from = ICD_Codes, values_from = flag, values_fill = 0 )
运行后df_result即为所需的虚拟变量格式DataFrame。
方法二:Base R实现(无需额外包)
如果不想加载第三方包,可通过基础R函数完成:
- 读取并解析数据
# 读取文本行 raw_lines <- readLines("your_data_path.txt") # 提取表头 header <- strsplit(raw_lines[1], ";")[[1]] # 处理数据行 data_lines <- raw_lines[-1] parsed_data <- lapply(data_lines, function(line) { parts <- strsplit(trimws(line), ";")[[1]] list(id = as.integer(parts[1]), codes = trimws(parts[-1])) })
- 生成虚拟变量矩阵
# 获取所有唯一ICD编码 all_codes <- unique(unlist(lapply(parsed_data, function(x) x$codes))) # 初始化结果DataFrame df_result_base <- data.frame( id = sapply(parsed_data, function(x) x$id), matrix(0, nrow = length(parsed_data), ncol = length(all_codes), dimnames = list(NULL, all_codes)) ) # 填充存在编码的标记值1 for (i in seq_along(parsed_data)) { codes <- parsed_data[[i]]$codes df_result_base[i, codes] <- 1 }
结果验证
两种方法生成的结果均与目标格式一致,以tidyverse方法的输出为例:
print(df_result) #> # A tibble: 3 × 13 #> id F10.10 F11.21 F31.81 G89.29 M54.5 F31.4 F17.200 F43.10 Z72.0 F14.10 F31.32 F10.21 #> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 1 1 1 0 0 0 0 0 0 0 0 0 #> 2 2 0 1 0 1 1 1 1 1 1 0 0 0 #> 3 3 0 0 1 0 0 0 1 0 0 1 1 1
内容的提问来源于stack exchange,提问作者wes
相关产品推荐
相关产品推荐

