使用case_when+str_detect与&运算符提取R数据框颜色列异常问题
问题:提取单行唯一颜色值失败
现有数据框mydata,每行的am1-am4四列中仅有一列是有效颜色值,其余列均为"none"。尝试通过dplyr的mutate结合case_when、str_detect提取颜色到chosen_colour列,但部分行返回"none",结果不符合预期。
示例数据
am1 <- c('blue', 'blue', 'none', 'none', 'none', 'none', 'blue', 'none') am2 <- c('none', 'none', 'red', 'none','none', 'red', 'none', 'none') am3 <- c('none', 'none', 'none', 'purple', 'purple', 'none', 'none', 'none') am4 <- c('none', 'none', 'none', 'none', 'none', 'none', 'none', 'green') mydata <- data.frame(am1, am2, am3, am4)
尝试的错误代码
mydata1 <- mydata %>% mutate(chosen_colour = case_when( str_detect(am1, "none") ~ am2, str_detect(am1, "none") & str_detect(am2, "none") ~ am3, str_detect(am1, "none") & str_detect(am2, "none") & str_detect(am3, "none") ~ am4, TRUE ~ am1 ))
错误结果
| am1 | am2 | am3 | am4 | chosen_colour |
|---|---|---|---|---|
| blue | none | none | none | blue |
| blue | none | none | none | blue |
| none | red | none | none | red |
| none | none | purple | none | none |
| none | none | purple | none | none |
| none | red | none | none | none |
| blue | none | none | none | blue |
| none | none | none | green | none |
错误原因
case_when是按顺序匹配条件的,一旦前面的条件满足,就会执行对应赋值,后续条件不再判断:
- 以第4行为例:
am1为"none",第一个条件str_detect(am1, "none")成立,直接返回am2的"none",不会走到判断am2是否为"none"的第二个条件。 - 第8行同理:第一个条件成立,返回
am2的"none",跳过后续判断。
解决方案
方法1:调整case_when条件顺序
将最严格的多条件判断放在最前面,逐步放宽条件:
library(dplyr) library(stringr) mydata_fixed <- mydata %>% mutate(chosen_colour = case_when( str_detect(am1, "none") & str_detect(am2, "none") & str_detect(am3, "none") ~ am4, str_detect(am1, "none") & str_detect(am2, "none") ~ am3, str_detect(am1, "none") ~ am2, TRUE ~ am1 ))
方法2:用coalesce简化逻辑
利用每行仅一个有效颜色的特点,先将"none"转为NA,再用coalesce提取非NA值:
library(dplyr) mydata_fixed <- mydata %>% mutate(across(am1:am4, ~ifelse(.x == "none", NA, .x)), chosen_colour = coalesce(am1, am2, am3, am4))
正确结果
| am1 | am2 | am3 | am4 | chosen_colour |
|---|---|---|---|---|
| blue | none | none | none | blue |
| blue | none | none | none | blue |
| none | red | none | none | red |
| none | none | purple | none | purple |
| none | none | purple | none | purple |
| none | red | none | none | red |
| blue | none | none | none | blue |
| none | none | none | green | green |
内容的提问来源于stack exchange,提问作者dena
相关产品推荐
相关产品推荐

