Как сгруппировать время по каждые n минут в R - PullRequest
1 голос
/ 05 июня 2019

У меня есть фрейм данных с большим количеством временных рядов:

1   0:03    B   1
2   0:05    A   1
3   0:05    A   1
4   0:05    B   1
5   0:10    A   1
6   0:10    B   1
7   0:14    B   1
8   0:18    A   1
9   0:20    A   1
10  0:23    B   1
11  0:30    A   1

Я хочу сгруппировать временные ряды каждые 6 минут и посчитать частоту A и B:

1   0:06    A   2
2   0:06    B   2
3   0:12    A   1
4   0:12    B   1
5   0:18    A   1
6   0:24    A   1
7   0:24    B   1
8   0:18    A   1
9   0:30    A   1

Кроме того, класс временного ряда - символ.Что мне делать?

Ответы [ 2 ]

2 голосов
/ 05 июня 2019

Вот подход для преобразования времени в POSIXct, cut время с интервалами в 6 минут, затем count.

Сначала необходимо указать год, месяц, день, час,минуты и секунды ваших данных.Это поможет масштабировать его на более крупные наборы данных.

library(tidyverse)
library(lubridate)

# sample data
d <- data.frame(t = paste0("2019-06-02 ", 
                           c("0:03","0:06","0:09","0:12","0:15",
                             "0:18","0:21","0:24","0:27","0:30"), 
                           ":00"),
                g = c("A","A","B","B","B"))

d$t <- ymd_hms(d$t) # convert to POSIXct with `lubridate::ymd_hms()`

Если вы проверите class в вашем новом столбце даты, вы увидите, что это «POSIXct».

> class(d$t)
[1] "POSIXct" "POSIXt" 

Теперь, когда данные находятся в «POSIXct», вы можете cut их с минутными интервалами!Мы добавим этот новый фактор группировки как новый столбец с именем tc.

d$tc <- cut(d$t, breaks = "6 min")  
d
                     t g                  tc
1  2019-06-02 00:03:00 A 2019-06-02 00:03:00
2  2019-06-02 00:06:00 A 2019-06-02 00:03:00
3  2019-06-02 00:09:00 B 2019-06-02 00:09:00
4  2019-06-02 00:12:00 B 2019-06-02 00:09:00
5  2019-06-02 00:15:00 B 2019-06-02 00:15:00
6  2019-06-02 00:18:00 A 2019-06-02 00:15:00
7  2019-06-02 00:21:00 A 2019-06-02 00:21:00
8  2019-06-02 00:24:00 B 2019-06-02 00:21:00
9  2019-06-02 00:27:00 B 2019-06-02 00:27:00
10 2019-06-02 00:30:00 B 2019-06-02 00:27:00

Теперь вы можете group_by этот новый интервал (tc) и свой столбец группировки (g), а также подсчитать частоту появления.Получение частоты наблюдений в группе является довольно распространенной операцией, поэтому dplyr предоставляет count для этого:

count(d, g, tc)
# A tibble: 7 x 3
  g     tc                      n
  <fct> <fct>               <int>
1 A     2019-06-02 00:03:00     2
2 A     2019-06-02 00:15:00     1
3 A     2019-06-02 00:21:00     1
4 B     2019-06-02 00:09:00     2
5 B     2019-06-02 00:15:00     1
6 B     2019-06-02 00:21:00     1
7 B     2019-06-02 00:27:00     2

Если вы запустите ?dplyr::count() в консоли, вы увидите, что count(d, tc) - это просто оболочка для group_by(d, g, tc) %>% summarise(n = n()).

0 голосов
/ 05 июня 2019

В соответствии с образцом набора данных временной ряд задается как время суток, т. Е. Без даты.

Пакет data.table имеет класс ITime, который является временемДневной класс хранится как целое число секунд в дне.С data.table мы можем использовать скользящее соединение для отображения времени на верхний предел 6-минутных интервалов ( правосторонние интервалы ):

library(data.table)

# coerce from character to class ITime
setDT(ts)[, time := as.ITime(time)]

# create sequence of breaks
breaks <- as.ITime(seq(as.ITime("0:00"), as.ITime("23:59:59"), as.ITime("0:06")))

# rolling join and aggregate
ts[, CJ(breaks, group, unique = TRUE)
   ][ts, on = .(group, breaks = time), roll = -Inf, .(x.breaks, group)
     ][, .N, by = .(upper = x.breaks, group)]

который возвращает

      upper group N
1: 00:06:00     B 2
2: 00:06:00     A 2
3: 00:12:00     A 1
4: 00:12:00     B 1
5: 00:18:00     B 1
6: 00:18:00     A 1
7: 00:24:00     A 1
8: 00:24:00     B 1
9: 00:30:00     A 1

Приложение

Если направление подвижного соединения изменяется (roll = +Inf вместо roll = -Inf), мы получаем влево-замкнутые интервалы

ts[, CJ(breaks, group, unique = TRUE)
   ][ts, on = .(group, breaks = time), roll = +Inf, .(x.breaks, group)
     ][, .N, by = .(lower = x.breaks, group)]

, что значительно меняет результат:

      lower group N
1: 00:00:00     B 2
2: 00:00:00     A 2
3: 00:06:00     A 1
4: 00:06:00     B 1
5: 00:12:00     B 1
6: 00:18:00     A 2
7: 00:18:00     B 1
8: 00:30:00     A 1

Данные

library(data.table)
ts <- fread("
1   0:03    B   1
2   0:05    A   1
3   0:05    A   1
4   0:05    B   1
5   0:10    A   1
6   0:10    B   1
7   0:14    B   1
8   0:18    A   1
9   0:20    A   1
10  0:23    B   1
11  0:30    A   1"
, header = FALSE
, col.names = c("rn", "time", "group", "value"))
...