如何使用dplyr过滤同一类别中被其他时间区间包含的数据行?
用dplyr剔除类别内被包含的时间区间行
先构造示例数据集
首先把你提供的示例数据转成可运行的R代码:
library(dplyr) library(lubridate) df <- tibble( Category = c("KA", "KA", "KA", "KB"), date_in = ymd(c("2018-09-05", "2018-09-05", "2018-09-18", "2018-09-24")), date_out = ymd(c("2018-10-08", "2018-09-18", "2018-09-24", "2018-10-08")) )
方法1:通用过滤(适用于多非重叠大区间场景)
核心逻辑是在每个类别内,判断当前行的时间区间是否被同类别其他任意一行完全包含,若被包含则剔除:
df_filtered <- df %>% group_by(Category) %>% filter( !any( date_in >= .$date_in & date_out <= .$date_out & (date_in != .$date_in | date_out != .$date_out) ) ) %>% ungroup()
逻辑说明
group_by(Category):限定只在同类别内做判断any(...):检查同组是否存在其他行满足:- 其他行的起始时间晚于/等于当前行
- 其他行的结束时间早于/等于当前行
- 不是当前行本身(避免自比较)
!any(...):不存在满足条件的行时,保留当前行
运行后得到预期结果:
# A tibble: 2 × 3 Category date_in date_out <chr> <date> <date> 1 KA 2018-09-05 2018-10-08 2 KB 2018-09-24 2018-10-08
方法2:高效简化(适用于单最大区间场景)
如果每个类别只需要保留覆盖范围最广的那一行,可以先计算类别内的全局最大区间,再筛选匹配的行,效率更高:
df_filtered <- df %>% group_by(Category) %>% mutate( global_start = min(date_in), global_end = max(date_out) ) %>% filter(date_in == global_start & date_out == global_end) %>% select(-global_start, -global_end) %>% ungroup()
内容的提问来源于stack exchange,提问作者ForEverNewbie
相关产品推荐
相关产品推荐

