OP указал, что у него есть несколько событий с заданным временем начала и окончания и что он хочет изобразить охват, то есть количество событий для каждого момента времени.
Точное решение возможно с использованием пакета Bioconductor IRanges
(см. Раздел 5.5 Подсчет диапазонов перекрытия в IRanges vignette).
Однако график в Q предполагает, что решение с использованием биннинга приемлемо для OP. Биннинг означает, что подсчитывается количество событий, которые перекрываются с временным растром. Это похоже на создание гистограммы, за исключением того, что конкретное событие может охватывать более одной ячейки.
Функция foverlaps()
из пакета data.table
может использоваться для процесса биннинга. Но сначала нам нужно подготовить фиктивные данные для демонстрации.
Создание фиктивных данных
Мы создаем два типа событий. Type1
- меньше, но более длинных событий, Type2
- большее количество более коротких событий.
set.seed(1L)
n1 <- 10L
n2 <- n1 * 10L
ref_time <- lubridate::ymd_hms("2017-4-26 10:11:12")
DT <- rbindlist(list(
data.table(t = ref_time + rnorm(n1) * 60 * 60,
d = rnorm(n1) * 60 * 60,
type = "Type1"),
data.table(t = ref_time + rnorm(n2) * 60 * 60,
d = rnorm(n2) * 60 * 6,
type = "Type2")
))
#
DT[, c("start", "end") := .(pmin(t, t + d), pmax(t, t + d))]
setkey(DT, start, end)
# add row numbers
DT[, rn := .I]
DT
# t d type start end rn
# 1: 2017-04-26 08:11:50 -64.64035 Type2 2017-04-26 08:10:45 2017-04-26 08:11:50 1
# 2: 2017-04-26 08:22:54 -91.80973 Type2 2017-04-26 08:21:22 2017-04-26 08:22:54 2
# 3: 2017-04-26 08:39:47 -528.21001 Type2 2017-04-26 08:30:58 2017-04-26 08:39:47 3
# 4: 2017-04-26 08:42:57 -13.54830 Type2 2017-04-26 08:42:43 2017-04-26 08:42:57 4
# 5: 2017-04-26 09:21:03 -2236.46609 Type1 2017-04-26 08:43:47 2017-04-26 09:21:03 5
# ---
#106: 2017-04-26 11:52:07 183.63903 Type2 2017-04-26 11:52:07 2017-04-26 11:55:11 106
#107: 2017-04-26 11:57:14 899.15817 Type2 2017-04-26 11:57:14 2017-04-26 12:12:13 107
#108: 2017-04-26 12:10:01 -387.06923 Type2 2017-04-26 12:03:34 2017-04-26 12:10:01 108
#109: 2017-04-26 12:21:33 74.71380 Type2 2017-04-26 12:21:33 2017-04-26 12:22:48 109
#110: 2017-04-26 12:35:17 153.03614 Type2 2017-04-26 12:35:17 2017-04-26 12:37:50 110
Лучше визуализировать:
library(ggplot2)
ggplot(DT, aes(x = start, y = rn, xend = end, yend = rn, colour = type)) +
geom_segment(size = 1) + theme_bw()
![введите здесь описание изображения](https://i.stack.imgur.com/7PaT5.png)
Создать растр времени для биннинга
Создаем временной растр с 15-минутными интервалами.
bin_start_time <- DT[, lubridate::floor_date(min(start), unit = "hour")]
bin_end_time<- DT[, lubridate::ceiling_date(max(end), unit = "hour")]
# time interval can be adjusted
bin_step <- as.difftime(15L, units = "mins")
bin_cuts <- seq(bin_start_time, bin_end_time, by = bin_step)
bins <- data.table(start = head(bin_cuts, -1L),
end = tail(bin_cuts, -1L),
key = "start,end")
# add row numbers
bins[, bn := .I]
head(bins)
# start end bn
#1: 2017-04-26 08:00:00 2017-04-26 08:15:00 1
#2: 2017-04-26 08:15:00 2017-04-26 08:30:00 2
#3: 2017-04-26 08:30:00 2017-04-26 08:45:00 3
#4: 2017-04-26 08:45:00 2017-04-26 09:00:00 4
#5: 2017-04-26 09:00:00 2017-04-26 09:15:00 5
#6: 2017-04-26 09:15:00 2017-04-26 09:30:00 6
Биннинг
Для биннинга требуется найти все совпадения событий, указанных в DT
, с растром времени, используя foverlaps()
и подсчитывая количество перекрытий. Это можно сделать одним оператором:
result <- foverlaps(DT, bins)[, .N, by = .(type, start, end)]
result[18:24]
# type start end N
#1: Type1 2017-04-26 11:00:00 2017-04-26 11:15:00 5
#2: Type1 2017-04-26 11:15:00 2017-04-26 11:30:00 4
#3: Type1 2017-04-26 11:30:00 2017-04-26 11:45:00 4
#4: Type1 2017-04-26 11:45:00 2017-04-26 12:00:00 2
#5: Type2 2017-04-26 09:45:00 2017-04-26 10:00:00 14
#6: Type2 2017-04-26 10:00:00 2017-04-26 10:15:00 17
#7: Type2 2017-04-26 10:15:00 2017-04-26 10:30:00 11
Обратите внимание, что частоты учитываются отдельно по типу.
Визуализация
ggplot(result, aes(start + bin_step/2, N, group = type, colour = type)) +
geom_line(size = 1) + expand_limits(y = 0) + theme_bw()
![введите здесь описание изображения](https://i.stack.imgur.com/bGau4.png)
Здесь точки данных центрированы в середине интервалов временного растра.
Другая возможность geom_step()
:
ggplot(result, aes(start, N, group = type, colour = type)) +
geom_step(size = 1) + expand_limits(y = 0) + theme_bw()
![введите здесь описание изображения](https://i.stack.imgur.com/ve0OM.png)
person
Uwe
schedule
26.04.2017
foverlaps()
из пакетаdata.table
. Вам необходимо указать временные интервалы, за которые вы хотите агрегировать.foverlaps()
находит пересечения, которые можно подсчитать. - person Uwe   schedule 26.04.2017foverlaps()
и опубликую свои выводы! - person Abaddon666   schedule 26.04.2017