如何按rep分组压缩数据:保留连续重复Event的首个记录
按分组保留连续相同Event的首条记录
原始数据
df <- data.frame(rep = c(1,1,1,1,1,1,2,2,2,2,2,2), time = c(0.0000,0.0002,0.0003,0.0015,0.0450,0.07800,0.0000,0.0002,0.0003,0.0015,0.0450,0.07800), Event = c("A", "A", "A", "B", "C", "C","A", "B", "B", "B", "C", "C"))
需求
按rep分组压缩数据,每组内仅保留连续相同Event序列的第一条记录,直到出现不同Event,目标结果如下:
df2 <- data.frame(rep = c(1,1,1,2,2,2), time = c(0.0000,0.0015,0.0450,0.0000,0.0002,0.0450), Event = c("A","B", "C", "A", "B", "C"))
尝试的代码(存在问题)
new_df <- df %>% group_by(rep) %>% slice_head(rle(Event))
注:
slice_head()不支持直接传入rle()结果作为参数,这种写法无法实现需求,会导致错误或不符合预期的数据删除。
正确实现方法
方法1:结合dplyr与rle
利用rle()识别连续相同的Event序列,提取每组内每个序列的首行:
library(dplyr) new_df <- df %>% group_by(rep) %>% mutate( # 生成连续相同Event的分组标记 group_id = rep(seq_along(rle(Event)$values), rle(Event)$lengths) ) %>% group_by(rep, group_id) %>% slice_head(n = 1) %>% # 取每个连续序列的首条记录 ungroup() %>% select(-group_id) # 移除临时标记列
方法2:用lag()判断Event是否变化
通过比较当前行与前一行的Event是否不同,筛选出每组内的首行和Event变化的行:
library(dplyr) new_df <- df %>% group_by(rep) %>% filter( # 保留每组的第一行,或当前Event与前一行不同的行 row_number() == 1 | Event != lag(Event) ) %>% ungroup()
两种方法均可得到目标结果,其中方法2更简洁直观,无需额外生成分组标记。
内容的提问来源于stack exchange,提问作者Werrby
相关产品推荐
相关产品推荐

