R语言按id分组筛选每组首次出现type="y"及之前行的实现问题
R按分组保留首次出现指定值及之前行的实现方案
原代码问题分析
你当前编写的代码不符合预期的核心原因有两点:
- 未提前按
id分组,求和逻辑是全局计算而非组内独立计算 - 筛选逻辑错误:仅判断
type为x或y的总计数为1,会保留第一个y之后的所有x记录,同时会过滤掉组内多个y的场景,完全不符合「保留到第一个y为止」的需求
正确实现方式
方法1:基于slice按位置截取(可读性更高)
library(dplyr) df %>% group_by(id) %>% slice(seq_len(which.max(type == "y"))) %>% ungroup()
逻辑说明:
which.max(type == "y")会返回组内第一个type="y"对应的行索引seq_len()生成从1到目标索引的整数序列,slice()按序列保留对应行,刚好覆盖首次y及之前的所有记录- 如果存在部分组没有
type="y"的场景,可以调整适配边界:slice(seq_len(if(all(type != "y")) n() else which.max(type == "y")))
方法2:基于cumsum累加判断(写法更简洁)
library(dplyr) df %>% group_by(id) %>% filter(cumsum(cumsum(type == "y")) <= 1) %>% ungroup()
逻辑说明:
- 内层
cumsum(type == "y")会对出现y的次数累加,首次出现y时累加值变为1,之后一直≥1 - 外层再做一次累加,首次y的位置累加值为1,之后的所有行累加值都≥2,通过
<=1筛选即可保留到第一个y为止的所有行
运行结果
两种方法执行后都将得到你期望的输出:
id type 1 1 x 2 1 x 3 1 y 4 2 x 5 2 x 6 2 x 7 2 y 8 3 x 9 3 x 10 3 x 11 3 x 12 3 y
内容的提问来源于stack exchange,提问作者berehan
相关产品推荐
相关产品推荐

