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

R语言多列多条件下ifelse、coalesce、str_detect函数失效排查

问题分析与解决方案

核心问题

你代码里的判断逻辑存在两个关键错误:

  1. coalesce函数误用:coalesce的作用是返回第一个非NA的值,但如果前面的str_detect返回FALSE(不是NA),函数就会直接返回FALSE,不会继续检查后面的列——哪怕后面的列存在目标编码,也会被忽略,这是导致判断不一致的根本原因。
  2. 仅取first()丢失数据:分组后只保留每列的第一个值,会丢掉同一患者其他行的编码信息,可能漏检跨多行的目标编码。

修正方案

替换coalesce为any()逻辑,同时在分组内检查所有行的编码列,确保只要患者任一相关列(或行)存在目标编码,就标记为1。另外可以简化正则表达式,减少重复代码。

修正后的代码

test_ipd <- test_ipd %>%
  group_by(ID_NO) %>%
  mutate(
    # 糖尿病:检查所有行的指定列是否有匹配
    has_diabetes_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^250|^E1[0-4]"),
      str_detect(ICD9_CODE, "^250|^E1[0-4]"),
      str_detect(ICD10_CODE, "^250|^E1[0-4]"),
      str_detect(MDIAG_CODE, "^250|^E1[0-4]"),
      str_detect(CONFIRM_MDIAG, "^250|^E1[0-4]"),
      na.rm = TRUE
    )),
    # 肝癌:简化正则,检查所有行的指定列(包括CASITE)
    has_livercancer_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^155(\\.0)?|^C22(\\.|[0-9])+"),
      str_detect(ICD9_CODE, "^155(\\.0)?|^C22(\\.|[0-9])+"),
      str_detect(ICD10_CODE, "^155(\\.0)?|^C22(\\.|[0-9])+"),
      str_detect(MDIAG_CODE, "^155(\\.0)?|^C22(\\.|[0-9])+"),
      str_detect(CONFIRM_MDIAG, "^155(\\.0)?|^C22(\\.|[0-9])+"),
      str_detect(CASITE, "155(\\.0)?|C22(\\.|[0-9])+"),
      na.rm = TRUE
    )),
    # 慢性肝炎
    has_chronic_hepatitis_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^070\\.[23]|^B18\\.[0-2]"),
      str_detect(ICD9_CODE, "^070\\.[23]|^B18\\.[0-2]"),
      str_detect(ICD10_CODE, "^070\\.[23]|^B18\\.[0-2]"),
      str_detect(MDIAG_CODE, "^070\\.[23]|^B18\\.[0-2]"),
      str_detect(CONFIRM_MDIAG, "^070\\.[23]|^B18\\.[0-2]"),
      na.rm = TRUE
    )),
    # 酒精性肝病
    has_alcohol_liver_disease_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^571\\.0|^K70"),
      str_detect(ICD9_CODE, "^571\\.0|^K70"),
      str_detect(ICD10_CODE, "^571\\.0|^K70"),
      str_detect(MDIAG_CODE, "^571\\.0|^K70"),
      str_detect(CONFIRM_MDIAG, "^571\\.0|^K70"),
      na.rm = TRUE
    )),
    # NAFLD
    has_nafld_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^571\\.8|^K76\\.0"),
      str_detect(ICD9_CODE, "^571\\.8|^K76\\.0"),
      str_detect(ICD10_CODE, "^571\\.8|^K76\\.0"),
      str_detect(MDIAG_CODE, "^571\\.8|^K76\\.0"),
      str_detect(CONFIRM_MDIAG, "^571\\.8|^K76\\.0"),
      na.rm = TRUE
    )),
    # 肥胖
    has_obesity_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^278\\.0|^E66"),
      str_detect(ICD9_CODE, "^278\\.0|^E66"),
      str_detect(ICD10_CODE, "^278\\.0|^E66"),
      str_detect(MDIAG_CODE, "^278\\.0|^E66"),
      str_detect(CONFIRM_MDIAG, "^278\\.0|^E66"),
      na.rm = TRUE
    )),
    # 肝硬化
    has_cirrhosis_byicd = as.integer(any(
      str_detect(SDIAG_CODE, "^571\\.5|^K74(\\.[0-6])?"),
      str_detect(ICD9_CODE, "^571\\.5|^K74(\\.[0-6])?"),
      str_detect(ICD10_CODE, "^571\\.5|^K74(\\.[0-6])?"),
      str_detect(MDIAG_CODE, "^571\\.5|^K74(\\.[0-6])?"),
      str_detect(CONFIRM_MDIAG, "^571\\.5|^K74(\\.[0-6])?"),
      na.rm = TRUE
    ))
  ) %>%
  ungroup() # 处理完记得取消分组

额外说明

  • any(..., na.rm = TRUE)会忽略NA值,只要有一个str_detect返回TRUE,就会整体返回TRUE,符合“任一匹配即标记”的需求。
  • as.integer()把逻辑值TRUE/FALSE转换成1/0,和原代码的输出格式一致。
  • 正则表达式做了简化,比如肝癌的^C22(\\.|[0-9])+可以匹配C220、C22.0、C22.1等所有C22开头的编码,避免重复写多个选项。
  • 去掉了原代码里取first()的步骤,直接在分组内检查所有行的列,不会丢失数据。

内容的提问来源于stack exchange,提问作者Deniz Taş

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:34:54