在他的评论中
here
here
,OP改变了问题的目的。现在,请求是
.
这需要一种完全不同的方法,证明可以发布一个单独的答案,IMHO。
要检查哪些票据在一小时的时间间隔内处于活动状态,请
foverlaps()
来自的函数
data.table
包装可用于:
library(data.table)
# IMPORTANT for reproducibility in different timezones
Sys.setenv(TZ = "UTC")
# convert timestamps from character to POSIXct
cols <- c("start", "end")
setDT(timeseries)[, (cols) := lapply(.SD, fasttime::fastPOSIXct), .SDcols = cols]
# create sequence of intervals of one hour covering all given times
hours_seq <- timeseries[, {
tmp <- seq(lubridate::floor_date(min(start, end), "hour"),
lubridate::ceiling_date(max(start, end), "hour"),
by = "1 hour")
.(start = head(tmp, -1L), end = tail(tmp, -1L))
}]
hours_seq
start end
1: 2016-12-31 16:00:00 2016-12-31 17:00:00
2: 2016-12-31 17:00:00 2016-12-31 18:00:00
3: 2016-12-31 18:00:00 2016-12-31 19:00:00
4: 2016-12-31 19:00:00 2016-12-31 20:00:00
5: 2016-12-31 20:00:00 2016-12-31 21:00:00
6: 2016-12-31 21:00:00 2016-12-31 22:00:00
7: 2016-12-31 22:00:00 2016-12-31 23:00:00
8: 2016-12-31 23:00:00 2017-01-01 00:00:00
# split up given ticket intervals in hour pieces
foverlaps(hours_seq, setkey(timeseries, start, end), nomatch = 0L)[
# compute active minutes and aggregate
, .(cnt_active_tickets = .N,
sum_active_minutes = sum(as.integer(
difftime(pmin(end, i.end), pmax(start, i.start), units = "mins")))),
keyby = .(group, interval_start = i.start, interval_end = i.end)]
group interval_start interval_end cnt_active_tickets sum_active_minutes
1: 1 2016-12-31 20:00:00 2016-12-31 21:00:00 1 18
2: 1 2016-12-31 21:00:00 2016-12-31 22:00:00 3 118
3: 1 2016-12-31 22:00:00 2016-12-31 23:00:00 3 180
4: 1 2016-12-31 23:00:00 2017-01-01 00:00:00 3 26
5: 2 2016-12-31 16:00:00 2016-12-31 17:00:00 1 2
6: 2 2016-12-31 17:00:00 2016-12-31 18:00:00 2 101
7: 2 2016-12-31 18:00:00 2016-12-31 19:00:00 2 120
8: 2 2016-12-31 19:00:00 2016-12-31 20:00:00 2 120
9: 2 2016-12-31 20:00:00 2016-12-31 21:00:00 2 120
10: 2 2016-12-31 21:00:00 2016-12-31 22:00:00 3 139
11: 2 2016-12-31 22:00:00 2016-12-31 23:00:00 3 180
12: 2 2016-12-31 23:00:00 2017-01-01 00:00:00 3 27
请注意,这种方法还考虑了“短期停车”,即活动时间不到一个小时、在整小时后开始、在下一个整小时前结束的车票。
宽格式输出
如果结果应与每个
group
dcast()
foverlaps(hours_seq, setkey(timeseries, start, end), nomatch = 0L)[
, active_minutes := as.integer(
difftime(pmin(end, i.end), pmax(start, i.start), units = "mins"))][
, dcast(.SD, i.start + i.end ~ paste0("group", group), sum)]
i.start i.end group1 group2
1: 2016-12-31 16:00:00 2016-12-31 17:00:00 0 2
2: 2016-12-31 17:00:00 2016-12-31 18:00:00 0 101
3: 2016-12-31 18:00:00 2016-12-31 19:00:00 0 120
4: 2016-12-31 19:00:00 2016-12-31 20:00:00 0 120
5: 2016-12-31 20:00:00 2016-12-31 21:00:00 18 120
6: 2016-12-31 21:00:00 2016-12-31 22:00:00 118 139
7: 2016-12-31 22:00:00 2016-12-31 23:00:00 180 180
8: 2016-12-31 23:00:00 2017-01-01 00:00:00 26 27