You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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(...):检查同组是否存在其他行满足:
    1. 其他行的起始时间晚于/等于当前行
    2. 其他行的结束时间早于/等于当前行
    3. 不是当前行本身(避免自比较)
  • !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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:31:14