基于值范围的行重复过滤:求dplyr与data.table解决方案
数据过滤解决方案
数据构造
首先生成测试数据:
date <- Sys.Date() + sort(sample(1:26, 26)) values <- c(sample(400:415, 10, replace = TRUE), 420, 421, 422, 420, 419, 421, sample(430:435, 10, replace = TRUE)) df <- data.frame(date, values)
需求说明
当date按升序排列时,筛选出values处于**420±2(即418~422)**范围内,且该范围内连续行数量至少5次的数据,最终保留中间的6个目标行,移除前后sample()生成的无关数据。
dplyr 解决方案
library(dplyr) result_dplyr <- df %>% arrange(date) %>% # 按日期升序排列 mutate(in_range = between(values, 418, 422)) %>% # 标记是否在目标区间内 group_by(rle_id = with(rle(in_range), rep(seq_along(lengths), lengths))) %>% # 按连续状态分组 filter(in_range, n() >= 5) %>% # 筛选符合条件的组 ungroup() %>% select(-in_range, -rle_id) # 移除辅助列
步骤说明
- 按
date对数据升序排序; - 标记每行
values是否落在418~422区间; - 用
rle()识别连续的同状态行,生成分组ID; - 筛选处于目标范围且组内行数≥5的分组;
- 移除辅助列得到最终结果。
data.table 解决方案
library(data.table) setDT(df) result_dt <- df[order(date)][, in_range := between(values, 418, 422)][, rle_id := rleid(in_range)][, .SD[in_range & .N >= 5], by = rle_id][, .(date, values)]
步骤说明
- 将data.frame转换为data.table并按
date升序排序; - 标记每行是否在目标区间内;
- 用
rleid()生成连续同状态的分组ID; - 按分组筛选,保留符合条件的子数据集;
- 仅保留
date和values列得到最终结果。
内容的提问来源于stack exchange,提问作者clc
相关产品推荐
相关产品推荐

