拆分Inj_code列并匹配对应日期列的R语言数据处理需求
R语言处理ICD10数据集转换为长格式解决方案
针对你手头的ICD10数据集,这里提供两种实用方法,把它转换成ID|Injury_code|Date的长格式,方便后续分析:
方法一:使用tidyverse工具链(推荐)
先加载tidyverse包,它整合了数据处理常用的dplyr、stringr、tidyr等工具:
library(tidyverse)
然后执行以下代码完成转换:
ICD10_long <- ICD10 %>% # 把每个ID的Inj_code按|拆分成编码列表 mutate(Injury_code = str_split(Inj_code, "\\|")) %>% # 将Date_0到Date_4的宽格式日期转成长格式,自动丢弃空值 pivot_longer(cols = starts_with("Date_"), names_to = "Date_num", values_to = "Date", values_drop_na = TRUE) %>% # 提取Date_后面的数字(比如Date_0提取0),用来匹配编码的位置 mutate(num = as.integer(str_extract(Date_num, "\\d+"))) %>% # 按ID分组,根据数字匹配对应位置的编码(R列表索引从1开始,所以加1) group_by(ID) %>% mutate(Injury_code = map2_chr(num, Injury_code, ~ .y[.x + 1])) %>% # 保留需要的列,过滤空编码 select(ID, Injury_code, Date) %>% filter(Injury_code != "") %>% ungroup()
代码说明:
str_split:把每个ID的多编码字符串拆成列表,每个元素对应一个编码pivot_longer:将分散的Date列转成统一的Date列,同时去掉空日期的行str_extract:提取日期列名里的数字,用来对应编码列表的索引map2_chr:按索引把日期和编码一一配对,确保每个编码对应正确的发生日期
方法二:Base R原生方法(无需额外包)
如果不想加载第三方包,用Base R也能实现:
# 拆分每个ID的编码为列表 code_list <- strsplit(ICD10$Inj_code, "\\|") # 获取每个ID的编码数量 code_counts <- sapply(code_list, length) # 重复ID和编码,对应后续展开的日期行数 expanded_ID <- rep(ICD10$ID, code_counts) expanded_codes <- unlist(code_list) # 把日期列转成矩阵,按行展开后筛选非空值 date_matrix <- as.matrix(ICD10[, startsWith(names(ICD10), "Date_")]) expanded_dates <- c(t(date_matrix)) expanded_dates <- expanded_dates[expanded_dates != ""] # 组合成最终的长格式数据框 ICD10_long_base <- data.frame( ID = expanded_ID, Injury_code = expanded_codes, Date = expanded_dates[1:length(expanded_codes)] )
两种方法最终都会得到你需要的长格式数据,每一行对应一个受试者的一条损伤记录,包含ID、损伤编码和发生日期。
内容的提问来源于stack exchange,提问作者DW1310
相关产品推荐
相关产品推荐

