如何在R语言的case_when中结合dplyr的if_all()处理数值数据
问题解决:按组计算
true_score字段 需求说明
- 按
class字段分组 - 若组内所有
score1值均大于100,组内所有成员的true_score取score1的值 - 若组内存在
score1值小于等于100的成员,组内所有成员的true_score取score1 + score2的和
模拟数据
library(tidyverse) test <- tibble(person = c("c", "s", "j"), class = c(1, 2, 2), score1 = c(101, 200, 23), score2 = c(200, 100, 25))
期望输出
answer <- tibble(person = c("c", "s", "j"), class = c(1, 2, 2), score1 = c(101, 200, 23), score2 = c(200, 100, 25), true_score = c(101, 300, 48))
失败尝试及报错
test %>% group_by(class) %>% mutate(true_score = case_when( if_all(score1 > 100), score1 > 100 ~ score1, score1 + score2 > 100 ~ score1 + score2 ))
报错信息:
Error in
mutate():
! Problem while computingtrue_score = case_when(...).
ℹ The error occurred in group 1: class = 1.
Caused by error inif_all():
! object 'score1' not found
问题分析与正确解法
你的错误主要有两点:一是if_all()的用法错误,它需要传入列选择器而非直接的条件表达式;二是case_when()的语法格式错误,每个分支应该是条件 ~ 结果的结构,不能用逗号分隔多余内容。
针对单组内单字段的全量判断,用all(score1 > 100)比if_all()更简洁直观,以下是两种可行的实现方式:
方式一:用ifelse实现
test %>% group_by(class) %>% mutate(true_score = ifelse(all(score1 > 100), score1, score1 + score2)) %>% ungroup()
方式二:用case_when实现
test %>% group_by(class) %>% mutate(true_score = case_when( all(score1 > 100) ~ score1, TRUE ~ score1 + score2 )) %>% ungroup()
如果一定要使用if_all()(虽无必要,但匹配你的尝试方向),可以这样写:
test %>% group_by(class) %>% mutate(true_score = case_when( if_all(everything(), ~ all(score1 > 100)) ~ score1, TRUE ~ score1 + score2 )) %>% ungroup()
以上三种写法均能得到符合预期的输出结果。
内容的提问来源于stack exchange,提问作者J.Sabree
相关产品推荐
相关产品推荐

