Предположим, у нас есть интервал, охватывающий несколько дней (интервал "A" на рисунке ниже).
library(lubridate)
int <- interval("2018-01-01 22:00:00", "2018-01-04 10:00:00")
В часах я получаю
as.period(int, unit = "hours")
"60H 0M 0S"
Теперь я хочу вычестьвсе нерабочие часы, здесь 16: 00-08: 00 (выделены серым цветом) в этом интервале, т. е. оставьте только синие части (08: 00-16: 00) и, опять же, рассчитайте оставшиеся часы (см. «B»«на рисунке ниже), что составляет 8 + 8 + 2 = 18 часов.
Один из подходов заключается в создании списка интервалов Iхотите сохранить, который охватывает весь интервал, а затем рассчитать пересечения.(Приведенный ниже код, конечно, может быть настроен программно с использованием функций floor / floor / seq и т. Д.)
int_keep <- list(
interval("2018-01-01 08:00:00", "2018-01-01 16:00:00"),
interval("2018-01-02 08:00:00", "2018-01-02 16:00:00"),
interval("2018-01-03 08:00:00", "2018-01-03 16:00:00"),
interval("2018-01-04 08:00:00", "2018-01-04 16:00:00"),
interval("2018-01-05 08:00:00", "2018-01-05 16:00:00")
)
l <- lapply(int_keep, function(x) intersect(x, int))
mns <- sapply(l, as.numeric) # returns seconds
sum(mns, na.rm = T) / 60 / 60 # sum of intersections in hours
[1] 18
Хотя это работает, мне это кажется крайне неуклюжим.Что может быть менее утомительным способом сделать это?