R lubridate 找到连续时间范围和一组间隔之间的非重叠周期
R lubridate find non overlapping periods between a continuous time frame and a set of intervals
我有以下时间范围:
A <- c('2016-01-01', '2019-01-05')
B <- c('2017-05-05','2019-06-05')
X_Period <- interval("2015-01-01", "2019-12-31")
Y_Periods <- interval(A, B)
我想找到 X_Period 和 Y_Periods 之间的非重叠时间段,这样结果就是:
[1]'2015-01-01'--'2015-12-31'
[2]'2017-05-06'--'2019-01-04'
[3]'2019-06-06'--'2019-31-12'
我正在尝试使用 setdiff,但它不起作用
setdiff(X_Period, Y_Periods)
这里有一个选项:
library(lubridate)
seq_X <- as.Date(seq(int_start(X_Period), int_end(X_Period), by = "1 day"))
seq_Y <- as.Date(do.call("c", sapply(Y_Periods, function(x)
seq(int_start(x), int_end(x), by = "1 day"))))
unique_dates_X <- seq_X[!seq_X %in% seq_Y]
lst <- aggregate(
unique_dates_X,
by = list(cumsum(c(0, diff.Date(unique_dates_X) != 1))),
FUN = function(x) c(min(x), max(x)),
simplify = F)$x
lapply(lst, function(x) interval(x[1], x[2]))
#[[1]]
#[1] 2015-01-01 UTC--2015-12-31 UTC
#
#[[2]]
#[1] 2017-05-06 UTC--2019-01-04 UTC
#
#[[3]]
#[1] 2019-06-06 UTC--2019-12-31 UTC
策略是将 interval
转换为按天序列(一个用于 X_Period
,一个用于 Y_Period
);然后我们发现所有天数都只是 X_Period
的一部分(而不是 Y_Periods
的一部分)。然后我们 aggregate
确定连续日期的所有子序列中的第一个和最后一个日期。结果 lst
是一个 list
和那些 start/end 日期。要转换为 interval
,我们只需遍历 list
并将 start/end 日期转换为 interval
。
我有以下时间范围:
A <- c('2016-01-01', '2019-01-05')
B <- c('2017-05-05','2019-06-05')
X_Period <- interval("2015-01-01", "2019-12-31")
Y_Periods <- interval(A, B)
我想找到 X_Period 和 Y_Periods 之间的非重叠时间段,这样结果就是:
[1]'2015-01-01'--'2015-12-31'
[2]'2017-05-06'--'2019-01-04'
[3]'2019-06-06'--'2019-31-12'
我正在尝试使用 setdiff,但它不起作用
setdiff(X_Period, Y_Periods)
这里有一个选项:
library(lubridate)
seq_X <- as.Date(seq(int_start(X_Period), int_end(X_Period), by = "1 day"))
seq_Y <- as.Date(do.call("c", sapply(Y_Periods, function(x)
seq(int_start(x), int_end(x), by = "1 day"))))
unique_dates_X <- seq_X[!seq_X %in% seq_Y]
lst <- aggregate(
unique_dates_X,
by = list(cumsum(c(0, diff.Date(unique_dates_X) != 1))),
FUN = function(x) c(min(x), max(x)),
simplify = F)$x
lapply(lst, function(x) interval(x[1], x[2]))
#[[1]]
#[1] 2015-01-01 UTC--2015-12-31 UTC
#
#[[2]]
#[1] 2017-05-06 UTC--2019-01-04 UTC
#
#[[3]]
#[1] 2019-06-06 UTC--2019-12-31 UTC
策略是将 interval
转换为按天序列(一个用于 X_Period
,一个用于 Y_Period
);然后我们发现所有天数都只是 X_Period
的一部分(而不是 Y_Periods
的一部分)。然后我们 aggregate
确定连续日期的所有子序列中的第一个和最后一个日期。结果 lst
是一个 list
和那些 start/end 日期。要转换为 interval
,我们只需遍历 list
并将 start/end 日期转换为 interval
。