Каков эффективный метод разделения и агрегирования интервалов из строк с метками времени в кадре данных? - PullRequest
5 голосов
/ 14 марта 2010

Из фрейма данных со строками с временными метками (результаты strptime), каков наилучший метод для агрегирования статистики за интервалы?

Интервалы могут быть часом, днем ​​и т. Д.

Есть функция aggregate, но это не помогает при назначении каждой строке интервала. Я планирую добавить столбец данных во фрейм данных, обозначающий интервал, и использовать его с aggregate, но если есть лучшее решение, было бы здорово услышать его.

Спасибо за любые указатели!


Пример данных

Пять рядов с временными метками, разделенными на 15-минутные интервалы, начинающиеся с 03:00.

Интервал 1

  • "2010-01-13 03:02:38 UTC"
  • "2010-01-13 03:08:14 UTC"
  • "2010-01-13 03:14:52 UTC"

Интервал 2

  • "2010-01-13 03:20:42 UTC"
  • "2010-01-13 03:22:19 UTC"

Заключение

Решением должно быть использование пакета временных рядов, например xts; однако мне не удалось их использовать, и я получил cut. Поскольку в настоящее время мне нужно только строить гистограммы со строками, сгруппированными по интервалу, этого было достаточно.

cut используется так:

interv <- function(x, start, period, num.intervals) {
  return(cut(x, as.POSIXlt(start)+0:num.intervals*period))
}

Ответы [ 3 ]

6 голосов
/ 14 марта 2010

Стандартные функции для разделения векторов: cut и findInterval:

v <- as.POSIXct(c(
  "2010-01-13 03:02:38 UTC",
  "2010-01-13 03:08:14 UTC",
  "2010-01-13 03:14:52 UTC",
  "2010-01-13 03:20:42 UTC",
  "2010-01-13 03:22:19 UTC"
))

# Your function return list:
interv(v, as.POSIXlt("2010-01-13 03:00:00 UTC"), 900)
# [[1]]
# [1] "2010-01-13 03:00:00"
# [[2]]
# [1] "2010-01-13 03:00:00"
# [[3]]
# [1] "2010-01-13 03:00:00"
# [[4]]
# [1] "2010-01-13 03:15:00 CET"
# [[5]]
# [1] "2010-01-13 03:15:00 CET"

# cut returns factor, you must provide proper breaks:
cut(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 2010-01-13 03:00:00 2010-01-13 03:00:00 2010-01-13 03:00:00
# [4] 2010-01-13 03:15:00 2010-01-13 03:15:00
# Levels: 2010-01-13 03:00:00 2010-01-13 03:15:00

# findInterval returns vector of interval id (breaks like in cut)
findInterval(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 1 1 1 2 2

Для записи: cut имеет метод для типа POSIXt, но, к сожалению, нет способа предоставить аргумент start, эффект:

cut(v,"15 min")
# [1] 2010-01-13 03:02:00 2010-01-13 03:02:00 2010-01-13 03:02:00
# [4] 2010-01-13 03:17:00 2010-01-13 03:17:00
# Levels: 2010-01-13 03:02:00 2010-01-13 03:17:00

Как видите, начало в 03:02:00. Вы можете связываться с метками выходного фактора (конвертировать метки во время, округлять как-то и конвертировать обратно в символ).

6 голосов
/ 14 марта 2010

Используйте пакет временных рядов . В пакете xts есть функции, специально предназначенные для этого. Или посмотрите на агрегатные и роликовые функции в пакете zoo.

В электронной книге rmetrics есть полезное обсуждение, включая сравнение производительности различных пакетов: https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf

Редактировать : Посмотрите на мой ответ на этот вопрос . По сути, вам нужно урезать каждую временную метку до определенного интервала, а затем выполнить агрегирование, используя эти новые укороченные временные метки в качестве вектора группировки.

0 голосов
/ 14 марта 2010

Это интересный вопрос; с распространением различных пакетов и методов временных рядов, должен быть подход для объединения нерегулярных временных рядов, кроме как грубой силой, которую предлагает OP. Вот один «высокоуровневый» способ получить интервалы, которые затем можно использовать для aggregate и др., Используя версию cut, определенную для chron объектов.

require(chron)
require(timeSeries)

my.times <- "
2010-01-13 03:02:38 UTC
2010-01-13 03:08:14 UTC
2010-01-13 03:14:52 UTC
2010-01-13 03:20:42 UTC
2010-01-13 03:22:19 UTC
"

time.df <- read.delim(textConnection(my.times),header=FALSE,sep="\n",strip.white=FALSE)
time.seq <- seq(trunc(timeDate(time.df[1,1]),units="hours"),by=15*60,length=nrow(time.df))
intervals <- as.numeric(cut(as.chron(as.character(time.df$V1)),breaks=as.chron(as.character(time.seq))))

Вы получаете

intervals  
[1] 1 1 1 2 2

, который теперь можно добавить к фрейму данных и агрегировать.

Приведенная выше акробатика (от символа к времени, от даты к символу и к хрону) немного неудачна, поэтому, если есть более чистые решения для объединения нерегулярных данных времени с использованием xts или любого другого пакета timeSeries, я бы хотел услышать их тоже! ..

Мне также любопытно узнать, какой будет наиболее эффективный подход для группировки больших высокочастотных нерегулярных временных рядов, например, создание 1-минутных баров объема по тиковым данным для очень ликвидного запаса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...