如何结合词列表使用mutate与case_when简化R脚本?
简化R中重复case_when+grepl的脚本
原始脚本
path_ko_rn_eq_car_2 = path_ko_rn_eq_car %>% mutate(new_var = case_when( grepl("C00469", equation) ~ "C00469", grepl("C00009", equation) ~ "C00009", grepl("C00409", equation) ~ "C00409", grepl("C01009", equation) ~ "C001009", grepl("C03409", equation) ~ "C03409", grepl("C09091", equation) ~ "C09091", grepl("C00001", equation) ~ "C00001", grepl("C00001", equation) ~ "C00001", grepl("C01001", equation) ~ "C001001", grepl("C03402", equation) ~ "C03402", grepl("C09095", equation) ~ "C09095", grepl("C00006", equation) ~ "C00006", grepl("C00005", equation) ~ "C00005" ))
尝试的简化写法(未成功)
cc = c("C00469","C00084","C00001","C03409","C03402") my_function= function(x){ path_ko_rn_eq_car_2 = path_ko_rn_eq_car %>% mutate(new_var = case_when(grepl(x, equation) ~ x)) } data.frame(sapply(cc, myfunction))
正确简化方案
方案一:使用stringr::str_extract(最简洁)
这种方法利用字符串提取直接匹配目标代码,和原脚本逻辑一致(匹配第一个符合的代码):
library(stringr) # 整理所有目标代码(修正原脚本中的笔误:C01009对应C01009,C01001对应C01001) target_codes <- c("C00469", "C00009", "C00409", "C01009", "C03409", "C09091", "C00001", "C01001", "C03402", "C09095", "C00006", "C00005") # 构造正则匹配模式,用|分隔所有目标代码 pattern <- str_c(target_codes, collapse = "|") path_ko_rn_eq_car_2 <- path_ko_rn_eq_car %>% mutate(new_var = str_extract(equation, pattern))
方案二:动态生成case_when条件(保留原逻辑结构)
如果需要保留case_when的写法,可以动态生成所有条件:
library(purrr) target_codes <- c("C00469", "C00009", "C00409", "C01009", "C03409", "C09091", "C00001", "C01001", "C03402", "C09095", "C00006", "C00005") # 生成每个代码对应的case_when条件,再合并为条件列表 case_conditions <- map(target_codes, ~ grepl(.x, equation) ~ .x) %>% reduce(c) path_ko_rn_eq_car_2 <- path_ko_rn_eq_car %>% mutate(new_var = case_when(!!!case_conditions))
原写法失败原因
- 自定义函数每次仅生成单个条件的
case_when,循环调用后会生成多个独立的dataframe,而非合并所有条件到同一个case_when中 sapply的用法不符合需求,它会将多个返回的dataframe拼接,这并非你想要的结果
内容的提问来源于stack exchange,提问作者Juliana B C
相关产品推荐
相关产品推荐

