Как разделить временной ряд на отдельные события и назначить идентификатор события? - PullRequest
0 голосов
/ 22 января 2019

Я хочу разбить нерегулярный временной ряд на отдельные события и назначить каждому событию уникальный числовой идентификатор для каждого сайта.

Вот пример фрейма данных:

structure(list(site = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("AllenBrook", "Eastberk"), class = 
"factor"), 
    timestamp = structure(c(10L, 13L, 8L, 4L, 5L, 6L, 7L, 9L, 
    11L, 12L, 1L, 2L, 3L), .Label = c("10/1/12 11:29", "10/1/12 14:29", 
    "10/1/12 17:29", "10/20/12 16:30", "10/20/12 19:30", "10/21/12 1:30", 
    "10/21/12 4:30", "9/5/12 12:30", "9/5/12 4:14", "9/5/12 6:30", 
    "9/5/12 7:14", "9/5/12 7:44", "9/5/12 9:30"), class = "factor")), class 
= "data.frame", row.names = c(NA, 
-13L))

Каждое событиене одинаковой длины или количества временных меток, поэтому я хочу разделить их на отдельные события, если между временной меткой и следующей временной меткой на этом сайте прошло более 12 часов.Каждое событие на сайте должно получить уникальный числовой идентификатор.Вот результат, который я хотел бы получить:

         site      timestamp eventid
1  AllenBrook    9/5/12 6:30       1
2  AllenBrook    9/5/12 9:30       1
3  AllenBrook   9/5/12 12:30       1
4  AllenBrook 10/20/12 16:30       2
5  AllenBrook 10/20/12 19:30       2
6  AllenBrook  10/21/12 1:30       2
7  AllenBrook  10/21/12 4:30       2
8    Eastberk    9/5/12 4:14       1
9    Eastberk    9/5/12 7:14       1
10   Eastberk    9/5/12 7:44       1
11   Eastberk  10/1/12 11:29       2
12   Eastberk  10/1/12 14:29       2
13   Eastberk  10/1/12 17:29       2

Подойдет любое решение для кодирования, но бонусные баллы за решение tidyverse или data.table.Спасибо за любую помощь, вы можете предоставить!

1 Ответ

0 голосов
/ 22 января 2019

Используя data.table, вы можете сделать следующее:

library(data.table)
setDT(tmp)[, timestamp := as.POSIXct(timestamp, format="%m/%d/%y %H:%M")][, 
    eventid := 1L+cumsum(c(0L, diff(timestamp)>720)), by=.(site)]

diff(timestamp) вычисляет разницу во времени между соседними строками. Затем мы проверяем, больше ли разница, чем 12 часов (или 720 минут). Обычная хитрость в R - использовать cumsum для определения, когда событие происходит в серии, и группировать последующие элементы вместе с этим событием, пока следующее событие не произойдет снова. Поскольку cumsum возвращает на 1 элемент меньше, мы используем 0L для дополнения начала. 1+ просто начинает индексирование с 1 вместо 0.

выход:

          site           timestamp eventid
 1: AllenBrook 2012-09-05 06:30:00       1
 2: AllenBrook 2012-09-05 09:30:00       1
 3: AllenBrook 2012-09-05 12:30:00       1
 4: AllenBrook 2012-10-20 16:30:00       2
 5: AllenBrook 2012-10-20 19:30:00       2
 6: AllenBrook 2012-10-21 01:30:00       2
 7: AllenBrook 2012-10-21 04:30:00       2
 8:   Eastberk 2012-09-05 04:14:00       1
 9:   Eastberk 2012-09-05 07:14:00       1
10:   Eastberk 2012-09-05 07:44:00       1
11:   Eastberk 2012-10-01 11:29:00       2
12:   Eastberk 2012-10-01 14:29:00       2
13:   Eastberk 2012-10-01 17:29:00       2

данные:

tmp <- structure(list(site = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("AllenBrook", "Eastberk"), class = 
     "factor"), 
 timestamp = structure(c(10L, 13L, 8L, 4L, 5L, 6L, 7L, 9L, 
     11L, 12L, 1L, 2L, 3L), .Label = c("10/1/12 11:29", "10/1/12 14:29", 
         "10/1/12 17:29", "10/20/12 16:30", "10/20/12 19:30", "10/21/12 1:30", 
         "10/21/12 4:30", "9/5/12 12:30", "9/5/12 4:14", "9/5/12 6:30", 
         "9/5/12 7:14", "9/5/12 7:44", "9/5/12 9:30"), class = "factor")), class 
 = "data.frame", row.names = c(NA, 
     -13L))
...