在R中判断时间窗口与日期区间是否重叠并生成新列
解决DataFrame中区间重叠判断的问题
你有如下结构的DataFrame:
Start_date End_date Start_time_window End_time_window 10 15 12 14 11 16 20 22 15 20 14 19 14 21 16 22
需要新增Available列,标记时间窗口区间与日期区间是否存在完全/部分重叠,预期结果如下:
Start_date End_date Start_time_window End_time_window Available 10 15 12 14 Yes 11 16 20 22 No 15 20 14 19 Yes 14 21 16 22 Yes
你的代码问题分析
- 第一个dplyr方案:你的条件是判断时间窗口完全包含在日期区间内,而非区间重叠。只有当时间窗口的起止都落在日期区间内时才标记Yes,这和需求不符(比如第三行
Start_time_window=14小于Start_date=15,但区间存在重叠,你的代码会误判为No)。 - 第二个DescTools方案:
%overlaps%默认对两个整体向量的区间做比较,而非逐行判断。你直接用c(Start_time_window, End_time_window)会把整列数据当成一个大区间,和c(Start_date, End_date)的大区间比较,结果自然不符合预期。
正确解决方案
方案1:用dplyr实现区间重叠判断
区间重叠的核心逻辑是:两个区间不重叠的情况只有两种——时间窗口完全在日期区间之前,或者完全在之后。取反即可得到重叠的条件:
library(dplyr) new_df <- df %>% mutate(Available = if_else( # 不重叠的两种情况:时间窗口结束 <= 日期开始,或者时间窗口开始 >= 日期结束 !(End_time_window <= Start_date | Start_time_window >= End_date), true = "Yes", false = "No" ))
运行结果:
> new_df Start_date End_date Start_time_window End_time_window Available 1 10 15 12 14 Yes 2 11 16 20 22 No 3 15 20 14 19 Yes 4 14 21 16 22 Yes
方案2:用DescTools的%overlaps%逐行判断
如果想用%overlaps%,需要用rowwise()让函数逐行处理每个区间:
library(dplyr) library(DescTools) new_df <- df %>% rowwise() %>% mutate(Available = if_else( c(Start_time_window, End_time_window) %overlaps% c(Start_date, End_date), "Yes", "No" )) %>% ungroup() # 取消行分组,避免后续操作受影响
该方案同样能得到符合预期的结果。
内容的提问来源于stack exchange,提问作者Teresa
相关产品推荐
相关产品推荐

