在R语言中按条件筛选评分列行和为指定值的行
问题解决:筛选评分人员打1数量符合要求的行
背景
有如下R语言数据框df,记录了不同任务的三位评分人员的质量合格评分(1=合格,0=不合格):
df <- data.frame(task = c("a","b","c", "d","e"), rater_1 = c(1,0,1,0,0), rater_2 = c(1,0,1,1,1), rater_3 = c(1,0,0,0,0), stringsAsFactors=FALSE) > df task rater_1 rater_2 rater_3 1 a 1 1 1 2 b 0 0 0 3 c 1 1 0 4 d 0 1 0 5 e 0 1 0
需求
筛选出恰好有n位评分人员打1的行,比如n=2时,期望得到仅包含任务c的子集:
task rater_1 rater_2 rater_3 3 c 1 1 0
原方法问题
使用dplyr::filter时直接用sum(rater_1, rater_2, rater_3) == 2会返回空数据框,原因是**sum()在这里是对三列所有元素整体求和**,不是按行计算每行的和。比如这里三列的总和是7,7不等于2,所以没有符合条件的行被筛选出来。
正确解法
方法1:用rowSums()直接计算行和
最简洁的方式,先选中所有评分列,再计算每行的和:
library(dplyr) df %>% filter(rowSums(select(., starts_with("rater_"))) == 2)
方法2:用rowwise()实现行级计算
通过rowwise()让sum()按行执行,计算每行三个评分列的和:
df %>% rowwise() %>% filter(sum(rater_1, rater_2, rater_3) == 2) %>% ungroup() # 记得取消行分组,避免后续操作受影响
方法3:用c_across()指定列范围
如果评分列是连续的,可以用c_across()快速选中列,配合rowwise():
df %>% rowwise() %>% filter(sum(c_across(rater_1:rater_3)) == 2) %>% ungroup()
以上三种方法都能得到预期结果:
# 输出 task rater_1 rater_2 rater_3 1 c 1 1 0
内容的提问来源于stack exchange,提问作者logjammin
相关产品推荐
相关产品推荐

