如何为含"x"标注的Subject-batch组全批量标记"xx"?
问题解决:按Subject+Batch批量标记存在"x"的批次记录
原始数据
df <- data.frame( Subject = c(rep("Rater_1",9), rep("Rater_2",9), rep("Rater_3",9)), Trial = c(1:9,1:9,1:9), Annotation = c(rep("x",4),rep("m",5), rep("x",2),rep("m",4), rep("x",3), rep("x",1),rep("m",8)), batch = rep(c(0,0,0,1,1,1,2,2,2),3) )
需求说明
识别每个Subject下的batch:只要该批次中存在Annotation为"x"的记录,就将该Subject对应此批次的所有记录的Annotation_0标记为"xx";若批次中无"x",则保留原Annotation值。
当前代码问题
以下代码仅会在Annotation为"x"的行标记"xx",无法实现全批次标记:
library(dplyr) df %>% group_by(Subject, batch) %>% mutate(Annotation_0 = ifelse(if_any(Annotation, ~str_detect(., 'x')), "xx", Annotation))
原因是if_any是逐行判断当前行的Annotation是否含"x",而非判断整个分组内是否存在"x"。
期望输出
# A tibble: 27 × 5 # Groups: Subject, batch [9] Subject Trial Annotation batch Annotation_0 <chr> <int> <chr> <dbl> <chr> 1 Rater_1 1 x 0 xx 2 Rater_1 2 x 0 xx 3 Rater_1 3 x 0 xx 4 Rater_1 4 x 1 xx 5 Rater_1 5 m 1 xx 6 Rater_1 6 m 1 xx 7 Rater_1 7 m 2 m 8 Rater_1 8 m 2 m 9 Rater_1 9 m 2 m 10 Rater_2 1 x 0 xx 11 Rater_2 2 x 0 xx 12 Rater_2 3 m 0 xx 13 Rater_2 4 m 1 m 14 Rater_2 5 m 1 m 15 Rater_2 6 m 1 m 16 Rater_2 7 x 2 xx 17 Rater_2 8 x 2 xx 18 Rater_2 9 x 2 xx 19 Rater_3 1 x 0 xx 20 Rater_3 2 m 0 xx 21 Rater_3 3 m 0 xx 22 Rater_3 4 m 1 m 23 Rater_3 5 m 1 m 24 Rater_3 6 m 1 m 25 Rater_3 7 m 2 m 26 Rater_3 8 m 2 m 27 Rater_3 9 m 2 m
解决方案
核心是判断整个分组(Subject+batch)内是否存在至少一个"x",而非逐行判断。直接用any(Annotation == "x")即可高效完成分组内的存在性检查,代码如下:
library(dplyr) df %>% group_by(Subject, batch) %>% mutate(Annotation_0 = ifelse(any(Annotation == "x"), "xx", Annotation)) %>% ungroup() # 可选,若不需要保留分组可取消
代码说明
group_by(Subject, batch):按每个评分者的每个批次进行分组,确保后续判断基于正确的范围。any(Annotation == "x"):返回当前分组的逻辑值,只要分组内有一条记录的Annotation为"x",就返回TRUE。ifelse(...):根据分组的逻辑值,将整个分组的Annotation_0统一设为"xx",否则保留原Annotation。
执行后即可得到与期望输出完全一致的结果。
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

