使用mutate、case_when、if_any处理ICD10代码生成新列报错求解
问题解决:基于多列ICD10代码匹配创建新列
需求说明
需要创建新列injury,规则如下:
- 搜索目标列(
dx1、dx2、dx3、ecode)中符合ICD10代码模式的内容:属于T36-T50范围且第5位字符为2(示例:T3602) - 只要任一目标列匹配该模式,
injury标记为1;否则标记为0
示例数据
df <- data.frame (dx1 = c('K5039','T215','C219861','T36002'), dx2 = c('T38022','X72001','X55124','T36022'), dx3 = c('X80011','X790122','X55124','T36022'), pcode = c('R41','R44','R98','R99'), ecode = c('X79','X81012','X44015','X83012'), stringsAsFactors = FALSE)
错误原因分析
最初使用
across的错误:across的作用是对多列执行相同操作并返回多列结果,但case_when的每个条件需要单个布尔值,无法直接将across作为case_when的判断条件。改用
if_any后报错的原因:
正则表达式被拆分为多行书写,导致~后的表达式语法不完整,R无法将其解析为有效的函数。
正确实现代码
方法1:用as.integer简化转换
library(dplyr) library(stringr) df_new <- df %>% mutate( injury = as.integer( if_any( c(dx1:dx3, ecode), ~ str_detect(., regex('(T36|T37|T38|T39|T40|T41|T42|T43|T44|T45|T46|T47|T48|T49|T50).{1}2.*')) ) ) )
方法2:用case_when显式判断
df_new <- df %>% mutate( injury = case_when( if_any(c(dx1:dx3, ecode), ~ str_detect(., regex('(T36|T37|T38|T39|T40|T41|T42|T43|T44|T45|T46|T47|T48|T49|T50).{1}2.*')) ~ 1, TRUE ~ 0 ) )
正则说明
(T36|T37|...|T50):匹配T36到T50的ICD10前缀.{1}:匹配任意单个字符(对应第4位字符)2:匹配第5位必须为2的规则.*:匹配后续任意长度的字符(兼容更长的ICD10编码)
输出结果
dx1 dx2 dx3 pcode ecode injury 1 K5039 T38022 X80011 R41 X79 1 2 T215 X72001 X790122 R44 X81012 0 3 C219861 X55124 X55124 R98 X44015 0 4 T36002 T36022 T36022 R99 X83012 1
内容的提问来源于stack exchange,提问作者Jenny Mercado
相关产品推荐
相关产品推荐

