如何用dplyr判断interval_A的日期是否落在interval_B中
判断interval_A区间是否与interval_B存在重叠(dplyr解决方案)
需求说明
需要判断interval_A中的每个区间是否存在任意日期处于interval_B的某个区间范围内,即两个区间是否有重叠,优先使用dplyr实现,避免展开所有日期的低效方式。
原始数据
library(lubridate) interval_A <- new("Interval", .Data = c(20822400, 10454400, 42508800, 18662400, 12355200, 16243200, 10195200, 14774400, 37324800, 31276800, 27734400, 62985600, 15724800, 32054400, 21427200), start = structure(c(94953600, 131328000, 240451200, 294278400, 334454400, 449193600, 493344000, 546739200, 575596800, 760320000, 930700800, 1088553600, 1481673600, 1513123200, 1647388800), tzone = "UTC", class = c("POSIXct", "POSIXt")), tzone = "UTC") interval_B <- new("Interval", .Data = c(41904000, 15724800, 42163200, 20995200, 21168000, 47347200, 5184000), start = structure(c(120960000, 315532800, 362793600, 646790400, 983404800, 1196467200, 1580515200 ), tzone = "UTC", class = c("POSIXct", "POSIXt")), tzone = "UTC")
错误尝试说明
使用as.list(interval_A) %within% as.list(interval_B)报错,原因是%within%仅支持单个日期/时间与单个区间的判断,无法直接作用于列表对象。
解决方案
核心思路:判断两个区间是否重叠(只要重叠,就说明A区间内有日期在B区间范围内),无需展开所有日期。区间重叠的逻辑为:A的起始时间 < B的结束时间 且 A的结束时间 > B的起始时间。
代码实现
library(dplyr) library(lubridate) # 将interval对象转换为包含起止时间的dataframe df_a <- tibble( a_start = int_start(interval_A), a_end = int_end(interval_A) ) %>% mutate(a_id = row_number()) # 为每个A区间添加唯一标识 df_b <- tibble( b_start = int_start(interval_B), b_end = int_end(interval_B) ) # 交叉连接所有A-B区间组合,判断重叠后聚合结果 result <- df_a %>% cross_join(df_b) %>% mutate(is_overlap = a_start < b_end & a_end > b_start) %>% group_by(a_id, a_start, a_end) %>% summarise(has_overlap_with_B = any(is_overlap), .groups = "drop") # 查看结果 print(result)
结果解释
has_overlap_with_B为TRUE表示对应interval_A的区间与interval_B中至少一个区间存在重叠,即该A区间内有日期处于B区间范围内;- 例如
interval_A的第二个区间1974-03-01 UTC--1974-06-30 UTC与interval_B的第一个区间重叠,故标记为TRUE;第一个A区间无重叠,标记为FALSE。
内容的提问来源于stack exchange,提问作者DaveM
相关产品推荐
相关产品推荐

