Каков эффективный метод разделения и агрегирования интервалов из строк с метками времени в кадре данных?
Вопрос
Какой метод агрегирования статистики за интервалы лучше всего использовать из кадра данных со строками с отметками времени (результаты 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))
}
Решение
Стандартные функции для разделения векторов: 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.Вы можете испортить метки выходного коэффициента (преобразовать метки во время, каким-то образом округлить и преобразовать обратно в символ).
Другие советы
Использовать пакет временных рядов. В пакете xts есть функции, разработанные специально для этого.Или посмотрите на функцииагрегирования и RollApply в пакете Zoo.
В электронной книге rmetrics есть полезное обсуждение, включая сравнение производительности различных пакетов: https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf
Редактировать:Посмотри на мой ответ на этот вопрос.По сути, вам нужно усечь каждую временную метку до определенного интервала, а затем выполнить агрегацию, используя эти новые усеченные временные метки в качестве вектора группировки.
Это интересный вопрос;С распространением различных пакетов и методов временных рядов должен существовать подход к группированию нерегулярных временных рядов, отличный от грубой силы, как предлагает ФП.Вот один «высокоуровневый» способ получить интервалы, которые затем можно использовать для 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
которые теперь вы можете добавить к фрейму данных и агрегировать.
Приведенная выше акробатика приведения (от символа к timeDate, от символа к chron) немного неудачна, поэтому, если есть более чистые решения для объединения нерегулярных данных времени с использованием xts или любого другого пакета timeSeries, я бы тоже хотел о них услышать. !..
Мне также интересно узнать, какой подход будет наиболее эффективным для группирования больших высокочастотных нерегулярных временных рядов, напримерсоздание 1-минутных баров объема на тиковых данных для очень ликвидных акций.