R语言如何简便判断多列全为Yes并生成对应汇总列
问题说明
现有如下结构的数据集:
data <- data.frame(Subject = c("A","B","C"), Col1 = c("Yes", "Yes", "No"), Col2 = c("Yes", "Yes", "Yes"), Col3 = c("Yes", "Yes", "Yes") ) print(data)
数据集打印结果:
Subject Col1 Col2 Col3 1 A Yes Yes Yes 2 B Yes Yes Yes 3 C No Yes Yes
需求
新增汇总列,规则为:
- 对应行所有目标列取值均为
"Yes"时,汇总列返回"Yes" - 任意一列取值为
"No"或NA时,汇总列返回"No"
原有实现代码写法繁琐,存在语法错误,且列数变动时需要逐行修改判断条件,扩展性很差:
data %>% group_by(Subject) %>% summarize(Summary = case_when( Col1 == "Yes & Col2 == "Yes & Col3 == "Yes ~ "Yes", Col1 != "Yes & Col2 != "Yes & Col3 != "Yes ~ "No", TRUE ~ NA
简便实现方案
不需要逐列手写判断条件,用dplyr的行选择函数即可快速实现,同时自动兼容NA的判断逻辑。
写法1:易读版(适合小数据集)
用rowwise()配合c_across()按行做判断,逻辑直观好修改:
library(dplyr) data %>% rowwise() %>% mutate(Summary = ifelse(all(!is.na(c_across(Col1:Col3)) & c_across(Col1:Col3) == "Yes"), "Yes", "No")) %>% ungroup()
c_across(Col1:Col3)可按行选中Col1到Col3的所有列值,如果需要调整判断列范围,直接修改列选择规则即可,比如要选所有名称以Col开头的列,可替换为c_across(starts_with("Col"))all()函数会判断选中的所有值是否同时满足「非NA」且「等于"Yes"」两个条件,只要存在"No"或者NA,就会返回FALSE
写法2:高效版(适合大数据集)
用向量化运算实现,不需要逐行遍历,运行速度更快:
data %>% mutate(Summary = ifelse(rowSums(across(Col1:Col3, ~ is.na(.x) | .x != "Yes")) == 0, "Yes", "No"))
逻辑为统计每行中不符合要求(值是NA、或值不等于Yes)的列数量,数量为0即代表所有列都是Yes,返回"Yes",否则返回"No"。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

