Агрегирование объекта зоопарка с отметкой времени по часам (т. е. не только по времени в объекте зоопарка)

У меня есть объект зоопарка, который состоит из временных рядов с отметкой времени (до секунды). Временные ряды нерегулярны в том смысле, что временные интервалы между значениями расположены неравномерно.

Я хотел бы преобразовать объект временной серии с неравномерным интервалом в объект с регулярным интервалом, где временные интервалы между значениями являются постоянными - скажем, 15 минут, и являются часами "реального мира".

Некоторые примеры данных могут помочь проиллюстрировать дальнейшие

# Sample data
2011-05-05 09:30:04 101.32
2011-05-05 09:30:14 100.09
2011-05-05 09:30:19 99.89
2011-05-05 09:30:35 89.66
2011-05-05 09:30:45 95.16
2011-05-05 09:31:12 100.28
2011-05-05 09:31:50 100.28
2011-05-05 09:32:10 98.28

Я хотел бы агрегировать их (используя мою пользовательскую функцию) для каждого указанного периода времени (например, 30-секундного интервала времени), чтобы результат выглядел как таблица, представленная ниже.

Суть в том, что я хочу агрегировать каждые 30 секунд по часам, а НЕ 30 секунд, начиная с моего первого времени наблюдения. Естественно, первый сегмент времени будет первым периодом времени, для которого у меня есть записанное наблюдение (т.е. строка) в данных для агрегирования.

2011-05-05 09:30:00   101.32
2011-05-05 09:30:30   89.66
2011-05-05 09:31:00   100.28

В приведенном примере моя пользовательская агрегатная функция просто возвращает первое значение в «наборе» «выбранных строк» ​​для агрегирования.


person Homunculus Reticulli    schedule 05.02.2012    source источник


Ответы (4)


Прочитайте данные, а затем агрегируйте их по минутам:

Lines <- "2011-05-05 09:30:04 101.32
2011-05-05 09:30:14 100.09
2011-05-05 09:30:19 99.89
2011-05-05 09:30:35 89.66
2011-05-05 09:30:45 95.16
2011-05-05 09:31:12 100.28
2011-05-05 09:31:50 100.28
2011-05-05 09:32:10 98.28"

library(zoo)
library(chron)
toChron <- function(d, t) as.chron(paste(d, t))
z <- read.zoo(text = Lines, index = 1:2, FUN = toChron)
aggregate(z, trunc(time(z), "00:01:00"), mean)

Результат:

(05/05/11 09:30:00) (05/05/11 09:31:00) (05/05/11 09:32:00) 
             97.224             100.280              98.280 
person G. Grothendieck    schedule 06.02.2012
comment
Краткий код ... почти есть, но я хочу агрегировать каждые 30 секунд, а не каждую минуту. - person Homunculus Reticulli; 06.02.2012
comment
Замените ссылку на одну минуту на 30 секунд. - person G. Grothendieck; 06.02.2012

Надеюсь, мы можем предположить, что это зоопарк или объект xts. Если да, то попробуйте это:

  # First get a start for a set of intervals, need to use your tz
beg<- as.POSIXct( format(index(dat[1,]), "%Y-%m-%d %H:%M", tz="EST5EDT"))
  # Then create a sequence of 30 second intervals
tseq <- beg+seq(0,4*30, by=30)
  # Then this will creat a vector than you can use for your aggregation fun
findInterval(index(dat), tseq)
  #[1] 1 1 1 2 2 3 4 5
  # To find the first row in a subset of rows from tapply, try "[" with 1
tapply(dat, findInterval(index(dat), tseq), "[", 1)
  #     1      2      3      4      5 
  #101.32  89.66 100.28 100.28  98.28 
person IRTFM    schedule 05.02.2012
comment
Мне бы никогда не пришло в голову попробовать этот подход. Интересно ... Кстати, не могли бы вы объяснить, почему вы используете 4 * 30 при создании последовательности. Я не понимаю эту часть. - person Homunculus Reticulli; 06.02.2012
comment
Вам нужно конечное время, большее, чем ваше последнее наблюдение. Если вы хотите вычислить это (и вам, вероятно, следует это сделать), вам нужно будет использовать max(index(dat))+30, чтобы убедиться, что вектор интервала для findInterval достаточно длинный. - person IRTFM; 06.02.2012

Я бы просто сократил время до вашего интервала, поэтому предположил, что t - это время (используйте as.POSIXct, если это не так)

bucket = t - as.numeric(t) %% 30

затем вы можете агрегировать более bucket, например aggregate(value, list(bucket), sum)

(я не использую zoo, так что это с чистым R)

person Simon Urbanek    schedule 05.02.2012

Вы должны посмотреть на align.time в xts. Он делает что-то очень близкое к тому, чего вы хотите достичь.

my.data <- read.table(text="date,x
2011-05-05 09:30:04,101.32
2011-05-05 09:30:14,100.09
2011-05-05 09:30:19,99.89
2011-05-05 09:30:35,89.66
2011-05-05 09:30:45,95.16
2011-05-05 09:31:12,100.28
2011-05-05 09:31:50,100.28
2011-05-05 09:32:10,98.28", header=TRUE, as.is=TRUE,sep = ",")

my.data <- xts(my.data[,2],as.POSIXlt(my.data[,1],format="%Y-%m-%d %H:%M:%S"))

library(xts)
res <-align.time(my.data,30)
res[!duplicated(index(res)),]

                      [,1]
2011-05-05 09:30:30 101.32
2011-05-05 09:31:00  89.66
2011-05-05 09:31:30 100.28
2011-05-05 09:32:00 100.28
2011-05-05 09:32:30  98.28

Вы можете отложить временной ряд на 30 секунд, если это сделает интерпретацию более понятной.

person Pierre Lapointe    schedule 05.02.2012
comment
Я что-то упускаю?. Я не вижу, где выполняется (настраиваемое) агрегирование... Результаты кажутся правильными, но я не вижу, как это было достигнуто с помощью приведенного выше фрагмента. - person Homunculus Reticulli; 06.02.2012
comment
Вы не сказали нам, как вы хотели агрегировать (имеется в виду, VWAP...). Я сделал то же самое, что и вы: выбрал только первую сделку за 30-секундный блок. Это то, что делает !duplicated. - person Pierre Lapointe; 06.02.2012