我有一个包含多个日期范围的数据框(准确地说是45):
Range Start End
1 2014-01-01 2014-02-30
2 2015-01-10 2015-03-30
3 2016-04-20 2016-10-12
... ... ...
它们永远不会重叠
我还有一个包含各种事件日期(200K +)的数据框:
Event Date
1 2014-01-02
2 2014-03-20
3 2015-04-01
4 2016-08-18
... ...
我想测试这些日期是否属于以下任何一个范围:
Event Date InRange
1 2014-01-02 TRUE
2 2014-03-20 FALSE
3 2015-04-01 FALSE
4 2016-08-18 TRUE
...
执行此测试的最佳方法是什么?我查看了lubridate的 和 interval 函数之间的以及各种Stackoverflow问题,但找不到一个好的解决方案。
答案 0 :(得分:3)
在您的第一个" data.frame"中有序,非重叠的间隔,您可以测试每个事件日期 - 如果它高于$Start
及其各自的{{1} }。使用$End
减少关系比较和所需的内存。
findInterval
使用数据(已修改" 2014-02-30"):
findInterval(events$Date, ranges$Start) > findInterval(events$Date, ranges$End)
#[1] TRUE FALSE FALSE TRUE
答案 1 :(得分:2)
您可以从第一个数据框创建日期范围的向量,然后使用%in%
运算符检查事件的每个日期是否在此日期范围内。假设您的第一个数据帧是dateRange
,第二个events
,将上述逻辑放在一行中将是:
events$InRange <- events$Date %in% unlist(Map(`:`, dateRange$Start, dateRange$End))
events
Event Date InRange
1 1 2014-01-02 TRUE
2 2 2014-03-20 FALSE
3 3 2015-04-01 FALSE
4 4 2016-08-18 TRUE
我们使用Map
创建日期范围向量。 Map
与:
运算符相结合,创建了从Start
到End
的日期范围列表。在接近list(2014-01-01 : 2014-02-30, 2015-01-10 : 2015-03-30, 2016-04-20 : 2016-10-12 ...)
(符号,无效)的地方,使用unlist
,我们将其展平为日期范围的向量,然后可以方便地与%in%
一起使用。
答案 2 :(得分:1)
编写您自己的function
以检查日期列表是否包含多个时间间隔。
date.in <- function(x){
m <- NULL
for (i in 1:NROW(df)){m <- c(m, ifelse(x>=df[i,1] & x<=df[i,2], TRUE, FALSE))}
any(m)}
数据:
df <- data.frame(start=c("2014-01-01", "2015-01-10", "2016-04-20"),
end=c("2014-02-30", "2015-03-30", "2016-10-12"))
df[] <- lapply(df, as.character)
s <- c("2014-01-02", "2014-03-20", "2015-04-01", "2016-08-18")
使用字符串s
进行测试。
as.character(lapply(s, date.in))#TRUE FALSE FALSE TRUE