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

如何简化基于ICD9编码筛选疾病的R语言grep实现逻辑?

问题描述

我的数据集结构如下:

id ACODE_ICD9_1 ACODE_ICD9_2 ACODE_ICD9_3
    <int>       <char>       <char>       <char>
 1:    20          463         4660         4720
 2:    27        42731        43490        73300
 3:    48        40210         2722        43410
 4:    52        40210        43410         4139
 5:    57        40210        43410         4139
 6:    58        40210        43410         4139
 7:    59         4660         7242         7245
 8:    77        40210         7804         7840
 9:    98        42731         7804        78650
10:   101          463         4269        78052
....

我需要基于ICD9编码筛选对应疾病,当前采用如下代码实现:

disease <- data %>%
  mutate(AF = ifelse(grepl("^42731", ACODE_ICD9_1) |
                       grepl("^42731", ACODE_ICD9_2) |
                       grepl("^42731", ACODE_ICD9_3), 1, 0),
         HTN = ifelse(grepl("^401|^402|^403|^404|^405", ACODE_ICD9_1) |
                            grepl("^401|^402|^403|^404|^405", ACODE_ICD9_2) |
                            grepl("^401|^402|^403|^404|^405", ACODE_ICD9_3), 1, 0),
         DM = ifelse(grepl("^250", ACODE_ICD9_1) |
                           grepl("^250", ACODE_ICD9_2) |
                           grepl("^250", ACODE_ICD9_3), 1, 0)...

由于需要处理的疾病数量较多,当前代码复杂且可读性差,请问是否有更简洁的实现方式?

优化方案

可以通过定义疾病编码映射表+向量化操作来简化代码,大幅提升可读性和可维护性,具体分两步:

1. 定义疾病-ICD9编码规则映射

先把所有疾病对应的ICD9匹配规则整理成一个列表,后续新增/修改疾病只需要调整这个列表即可:

disease_rules <- list(
  AF = "^42731",
  HTN = "^401|^402|^403|^404|^405",
  DM = "^250"
  # 新增疾病直接在这里添加,比如 Stroke = "^434"
)

2. 批量生成疾病标记列

方法一:使用dplyr的if_any(推荐,代码最简洁)

适用于dplyr 1.0.0及以上版本,利用if_any检查每行任意ICD9列是否匹配规则:

library(dplyr)

disease <- data %>%
  mutate(
    across(
      .cols = all_of(names(disease_rules)),
      .fns = ~ if_any(starts_with("ACODE_ICD9"), ~ grepl(disease_rules[[.y]], .x)),
      .names = "{.col}"
    ) %>%
    mutate(across(everything(), as.integer)) # 将布尔值转换为1/0格式
  )

方法二:使用purrr批量处理(兼容低版本dplyr)

如果你的dplyr版本较低,用purrr::map_dfc批量生成所有疾病标记列,再与原数据合并:

library(dplyr)
library(purrr)

disease_flags <- map_dfc(disease_rules, function(pattern) {
  data %>%
    rowwise() %>%
    mutate(flag = any(grepl(pattern, c(ACODE_ICD9_1, ACODE_ICD9_2, ACODE_ICD9_3)))) %>%
    pull(flag) %>%
    as.integer()
})

disease <- bind_cols(data, disease_flags)

额外优化:处理编码缺失问题

如果数据中存在NA值,可在grepl中添加na.rm = TRUE避免返回NA结果:

# 以if_any方法为例修改
grepl(disease_rules[[.y]], .x, na.rm = TRUE)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:34:51