You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中简洁实现多列ICD-10诊断编码的匹配标记?

问题:简洁筛选多列中的ICD-10编码

我想从数据集的诊断变量里筛选出特定的ICD-10编码,以此标记符合条件的受试者,但找不到简洁的实现方式。

背景

每个受试者ID对应50多个诊断实例,分别存在Disease_code_1、Disease_code_2……这类列中,同时配有对应的诊断日期列。示例数据如下:

df = data.frame(ID = c(1001, 1002, 1003, 1004, 1005),
                Disease_code_1 = c('I802', 'G200','I802',NA, 'H356'),
                Disease_code_2 = c('A071',NA,'G20',NA,'I802'),
                Disease_code_3 = c('H250', NA,NA,NA,NA),
                Date_of_diagnosis_1 = c('12/06/1997','13/06/1997','14/02/2003',NA,'18/03/2005'),
                Date_of_diagnosis_2 = c('12/06/1998',NA,'18/09/2001',NA,'12/07/1993'),
                Date_of_diagnosis_3 = c('17/09/2010',NA,NA,NA,NA))

# 输出结果
    ID Disease_code_1 Disease_code_2 Disease_code_3 Date_of_diagnosis_1 Date_of_diagnosis_2 Date_of_diagnosis_3
1 1001           I802           A071           H250          12/06/1997          12/06/1998          17/09/2010
2 1002           G200           <NA>           <NA>          13/06/1997                <NA>                <NA>
3 1003           I802            G20           <NA>          14/02/2003          18/09/2001                <NA>
4 1004           <NA>           <NA>           <NA>                <NA>                <NA>                <NA>
5 1005           H356           I802           <NA>          18/03/2005          12/07/1993                <NA>

可以看到,Disease_code_1和Disease_code_2中都有需要纳入分析的I802编码。

尝试过的方法

错误的简洁写法

我尝试用ifelse加字符串拼接的方式筛选,结果得到的符合条件的受试者数量为0:

data$diagnosis<- with(data, ifelse((data$disease_code_1 == "I802||G200||H356"),1,0))
data$diagnosis[is.na(data$diagnosis)] <- 0
sum(data$diagnosis)

可行但冗长的写法

目前唯一能运行的写法非常冗长,而实际场景中有50多个诊断列和12个目标编码,代码会变得异常繁琐甚至无法正常运行(命令行持续出现+符号):

data$diagnosis <- with(data, ifelse(((data$disease_code_1 == "I802")|(data$disease_code_1 == "G200")|(data$disease_code_1 == "H356")|(data$disease_code_2 == "I802")|(data$disease_code_2 == "G200")|(data$disease_code_2 == "H356")|(data$disease_code_3 == "I802")|(data$disease_code_3 == "G200")|(data$disease_code_3 == "H356")), 1, 0))
data$diagnosis[is.na(data$diagnosis)] <- 0
sum(data$diagnosis)

简洁解决方案

方法1:使用tidyverse转为长格式处理

这种方法更直观,适合处理多列重复结构的数据:

library(tidyverse)

# 定义目标编码
target_codes <- c("I802", "G200", "H356")

# 把宽格式转为长格式,只保留诊断编码列
df_long <- df %>%
  pivot_longer(cols = starts_with("Disease_code"), 
               names_to = "code_col", 
               values_to = "code") %>%
  filter(!is.na(code))

# 标记符合条件的ID,再合并回原数据
df <- df %>%
  left_join(df_long %>%
              group_by(ID) %>%
              summarise(diagnosis = any(code %in% target_codes) %>% as.integer()),
            by = "ID") %>%
  replace_na(list(diagnosis = 0))

# 查看结果
sum(df$diagnosis)

方法2:Base R 一行式处理

如果不想加载额外包,可以用Base R的方法,直接对诊断列进行批量判断:

# 定义目标编码
target_codes <- c("I802", "G200", "H356")

# 筛选所有诊断列
code_cols <- grep("^Disease_code", names(df), value = TRUE)

# 逐行判断是否有任意一个编码在目标列表中
df$diagnosis <- as.integer(rowSums(sapply(df[code_cols], function(x) x %in% target_codes), na.rm = TRUE) > 0)

# 查看结果
sum(df$diagnosis)

解释

  • 两种方法都先定义了目标编码列表target_codes,方便后续修改维护
  • 方法1通过转长格式,把所有诊断编码集中到一列,再按ID判断是否存在目标编码,逻辑清晰
  • 方法2用sapply批量处理所有诊断列,每行计算符合条件的数量,只要大于0就标记为1,高效简洁

内容的提问来源于stack exchange,提问作者Nic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:25:14