求助:在R语言中基于多列值生成合并分类列的实现方法
合并多分类列生成单一处理类别列的解决方案
数据集与需求
首先重现你的数据集:
treatment_alone = c("Yes", "No", "Yes", "No", "No", "No", "No", "No") treatment_and_fertilizer = c("No", "Yes", "No", "Yes", "No", "No", "No", "No") treatment_and_manure = c("No", "No", "No", "No", "Yes", "No", "Yes", "No") treatment_and_composte = c("No", "No", "No", "No", "No", "Yes", "No", "Yes") data_test = data.frame(treatment_alone, treatment_and_fertilizer, treatment_and_manure, treatment_and_composte)
需求:生成一个treatment列,将4个二分类列(Yes/No)合并为单一分类列,每行值对应该行中为"Yes"的列的自定义类别名称(如treatment_alone为Yes时,值为"treatment alone")。
问题分析
你之前的代码存在两个关键问题:
- 第一个代码块的
mutate语法错误,未将变量修改逻辑包裹在mutate()括号内; coalesce函数仅识别非NA值,你替换后的空字符串""或原有的"No"都不属于NA,因此无法正确匹配目标值。
解决方案
以下是三种可行的实现方式:
方法1:dplyr 逐行判断(直观易读)
使用rowwise()逐行处理,结合case_when匹配每个列的"Yes"状态:
library(dplyr) data_test %>% rowwise() %>% mutate(treatment = case_when( treatment_alone == "Yes" ~ "treatment alone", treatment_and_fertilizer == "Yes" ~ "treatment and fertilizer", treatment_and_manure == "Yes" ~ "treatment and manure", treatment_and_composte == "Yes" ~ "treatment and compost", TRUE ~ NA_character_ # 可选:处理无Yes的行,返回NA )) %>% ungroup()
方法2:tidyr 转长表处理(适合复杂场景)
通过宽表转长表,过滤出"Yes"的记录后再转回宽表:
library(dplyr) library(tidyr) data_test %>% mutate(row_id = row_number()) %>% pivot_longer(-row_id, names_to = "treatment_col", values_to = "value") %>% filter(value == "Yes") %>% mutate(treatment = recode(treatment_col, "treatment_alone" = "treatment alone", "treatment_and_fertilizer" = "treatment and fertilizer", "treatment_and_manure" = "treatment and manure", "treatment_and_composte" = "treatment and compost" )) %>% select(row_id, treatment) %>% right_join(data_test %>% mutate(row_id = row_number()), by = "row_id") %>% select(-row_id)
方法3:Base R 高效实现(无需加载包)
利用max.col定位每行"Yes"的位置,再匹配自定义类别名称:
# 定义列名与目标类别的映射关系 treatment_mapping <- c( "treatment_alone" = "treatment alone", "treatment_and_fertilizer" = "treatment and fertilizer", "treatment_and_manure" = "treatment and manure", "treatment_and_composte" = "treatment and compost" ) # 找到每行中值为"Yes"的列索引 yes_col_index <- max.col(data_test == "Yes", ties.method = "first") # 生成treatment列 data_test$treatment <- treatment_mapping[colnames(data_test)[yes_col_index]]
内容的提问来源于stack exchange,提问作者madina_b
相关产品推荐
相关产品推荐

