如何在R语言中按条件将多列合并为单一Diagnosis列
问题
现有如下结构的数据集:
| City | Age | Name | Q11_1 | Q11_4 | Q11_5 | Q11_6 | Q11_7 |
|---|---|---|---|---|---|---|---|
| .... | .... | ... | yes | no | no | no | no |
| ... | ... | ... | no | yes | no | no | no |
| ... | ... | ... | no | no | yes | no | no |
| ... | ... | ... | no | no | no | yes | no |
| ... | .. | ... | no | no | no | no | yes |
| ... | ... | ... | no | no | no | no | no |
| .. | ... | ... | no | no | no | no | no |
Q11系列列记录受访者的疾病情况,每人仅能在一列选yes。需要生成名为Diagnosis的新列,规则如下:
- Q11_1为
yes时填"Alzheimer" - Q11_4为
yes时填"Dementia" - Q11_5为
yes时填"Parkinson" - Q11_6或Q11_7为
yes时填"other"
尝试用tidyverse的ifelse编写了如下代码,但生成了多列而非单一Diagnosis列:
df %>% mutate(diagnosis= ifelse(Q11_1== "Yes", "Alzheimer", NA), ifelse(Q11_4 == "Yes", "Dementia", NA), ifelse(Q11_5 == "Yes", "Parkinson", NA))
期望得到的Diagnosis列结构如下:
| Diagnosis |
|---|
| Alzheimer |
| Dementia |
| Parkinson |
| other |
求正确的R语言实现方法。
解决方案
方法1:使用case_when(推荐,可读性更强)
case_when是tidyverse中替代嵌套ifelse的更清晰方案,适合多条件分支判断:
library(tidyverse) df <- df %>% mutate(Diagnosis = case_when( Q11_1 == "yes" ~ "Alzheimer", Q11_4 == "yes" ~ "Dementia", Q11_5 == "yes" ~ "Parkinson", Q11_6 == "yes" | Q11_7 == "yes" ~ "other", TRUE ~ NA_character_ # 所有不满足条件的情况填充NA ))
注意:要和数据中yes的大小写保持一致,原数据为小写yes,之前代码中写的大写Yes会导致匹配失败,需统一格式。
方法2:嵌套ifelse
如果坚持使用ifelse,需将多个ifelse嵌套在同一个赋值语句中,而非拆分为多个参数:
df <- df %>% mutate(Diagnosis = ifelse(Q11_1 == "yes", "Alzheimer", ifelse(Q11_4 == "yes", "Dementia", ifelse(Q11_5 == "yes", "Parkinson", ifelse(Q11_6 == "yes" | Q11_7 == "yes", "other", NA)))))
方法3:长表转换法(适配多问题列场景)
因为每人仅能选一个yes,可将Q11系列列转为长表后匹配诊断名称,适合问题列较多的场景:
df <- df %>% pivot_longer(cols = starts_with("Q11_"), names_to = "question", values_to = "response") %>% filter(response == "yes") %>% mutate(Diagnosis = case_when( question == "Q11_1" ~ "Alzheimer", question == "Q11_4" ~ "Dementia", question == "Q11_5" ~ "Parkinson", question %in% c("Q11_6", "Q11_7") ~ "other" )) %>% pivot_wider(names_from = "question", values_from = "response")
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

