Скользящие временные интервалы для данных временных рядов в R

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

Во-первых, воспроизводимый набор данных:

library(zoo)
set.seed(0)
nSamples    <- 5000
vecDT       <- rexp(nSamples, 3)
vecTimes    <- cumsum(c(0,vecDT))
vecDrift    <- c(0, rnorm(nSamples, mean = 1/nSamples, sd = 0.01))
vecVals     <- cumsum(vecDrift)
vecZ        <- zoo(vecVals, order.by = vecTimes)
rm(vecDT, vecDrift)

Предположим, что время в секундах. Есть почти 1700 секунд (всего 30 минут) vecZ серии и 5001 записей за это время. (NB: я бы попробовал использовать xts, но xts Кажется, нужна информация о дате, и я бы предпочел не использовать конкретную дату, когда она не актуальна.)

Мои цели следующие:

  • Определите индексы значений за 3 минуты до и 3 минуты после каждой точки. Поскольку времена непрерывны, я сомневаюсь, что любые две точки находятся на расстоянии точно 3 минуты. То, что я хотел бы найти, это точки, которые находятся не более чем за 3 минуты до и не менее чем через 3 минуты после данной точки, то есть что-то вроде следующего (в псевдокоде):

    backIX(t, vecZ, tDelta) = min{ix in length(vecZ) : t - time(ix) < tDelta}forwardIX(t, vecZ, tDelta) = min{ix in length(vecZ) : time(ix) - t > tDelta}

    Итак, на 3 минуты, tDelta = 180, Если t=2500то результат для forwardIX() будет 3012 (то есть время (vecZ)[2500] равно 860,1462, а время (vecZ)[3012] равно 1040,403 или чуть более 180 секунд спустя), а выход backwardIX() будет 2020 (соответствует времени 680,7162 секунд).

    В идеале я хотел бы использовать функцию, которая не требует t, так как это потребует length(vecZ) вызывает функцию, которая игнорирует тот факт, что скользящие окна времени могут быть рассчитаны более эффективно.

  • Примените функцию ко всем значениям в скользящем окне времени. я видел rollapply, который принимает фиксированный размер окна (т.е. фиксированное количество индексов, но не фиксированное окно времени). Я могу решить это наивным способом, с помощью цикла (или foreach;-)) это рассчитывается по индексу t, но мне было интересно, есть ли уже реализованные простые функции, например, функция для вычисления среднего значения всех значений за данный период времени. Поскольку это может быть эффективно сделано с помощью простой сводной статистики, которая скользит по окну, она должна быть вычислительно дешевле, чем функция, которая обращается ко всем данным несколько раз для вычисления каждой статистики. Некоторые довольно естественные функции: среднее, минимальное, максимальное и медианное.

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

Есть ли в R пакеты, которые облегчают такие манипуляции с данными во временных окнах, или мне не повезло, и я должен написать свои собственные функции?


Примечание 1: Этот вопрос направлен на то, чтобы сделать что-то похожее, за исключением непересекающихся интервалов, а не скользящих окон времени, например, я мог бы адаптировать это для выполнения моего анализа на каждом последующем 3-минутном блоке, но я не вижу способа адаптировать это для прокатки 3-х минутных интервалов.

Примечание 2: я обнаружил, что переключение с zoo Объект числового вектора (для времен) значительно ускорил проблему определения дальности / определения оконечной точки для первой цели. Это все еще наивный алгоритм, но стоит отметить, что работа с zoo объекты не могут быть оптимальными для наивного подхода.

1 ответ

Вот то, что я предложил, но я не уверен, что это точно отвечает на ваш вопрос

#Picking up where your code left off
library(xts)
library(TTR)
x <- .xts(vecZ, vecTimes)
xx <- na.locf(cbind(xts(, seq.POSIXt(from=start(x), to=end(x), by='sec')), x))
x$means <- runMean(xx, n=180)
out <- x[!is.na(x[, 1]), ]
tail(out)

                                  x     means
1969-12-31 18:28:17.376141 0.2053531 0.1325938
1969-12-31 18:28:17.379140 0.2101565 0.1329065
1969-12-31 18:28:17.619840 0.2139770 0.1332403
1969-12-31 18:28:17.762765 0.2072574 0.1335843
1969-12-31 18:28:17.866473 0.2065790 0.1339608
1969-12-31 18:28:17.924270 0.2114755 0.1344264

Начиная с версии v1.9.8 (в CRAN 25 ноября 2016 г.), data.table получил возможность агрегировать в неравном объединении, которое можно использовать для применения функции прокрутки к скользящему временному окну нерегулярного временного ряда.

Для демонстрации и проверки используется меньший набор данных.

library(data.table)   # development version 1.11.9 used

# create small dataset
set.seed(0)
nSamples    <- 10
vecDT       <- rexp(nSamples, 3)
vecTimes    <- cumsum(c(0,vecDT))
vecVals     <- 0:nSamples
vec         <- data.table(vecTimes, vecVals)
vec
      vecTimes vecVals
 1: 0.00000000       0
 2: 0.06134553       1
 3: 0.10991444       2
 4: 0.15651286       3
 5: 0.30186907       4
 6: 1.26685858       5
 7: 1.67671260       6
 8: 1.85660688       7
 9: 2.17546271       8
10: 2.22447804       9
11: 2.68805641      10
# define window size in seconds 
win_sec = 0.3

# aggregate in sliding window by a non-equi join
vec[.(t = vecTimes, upper = vecTimes + win_sec, lower = vecTimes - win_sec), 
    on = .(vecTimes < upper, vecTimes > lower), 
    .(t, .N, sliding_mean = mean(vecVals)), by = .EACHI]
     vecTimes     vecTimes          t N sliding_mean
 1: 0.3000000 -0.300000000 0.00000000 4          1.5
 2: 0.3613455 -0.238654473 0.06134553 5          2.0
 3: 0.4099144 -0.190085564 0.10991444 5          2.0
 4: 0.4565129 -0.143487143 0.15651286 5          2.0
 5: 0.6018691  0.001869065 0.30186907 4          2.5
 6: 1.5668586  0.966858578 1.26685858 1          5.0
 7: 1.9767126  1.376712596 1.67671260 2          6.5
 8: 2.1566069  1.556606875 1.85660688 2          6.5
 9: 2.4754627  1.875462707 2.17546271 2          8.5
10: 2.5244780  1.924478037 2.22447804 2          8.5
11: 2.9880564  2.388056413 2.68805641 1         10.0

Первые два столбца показывают верхнюю и нижнюю границы интервала времени, соответственно, t это оригинал vecTimes, а также N обозначает количество точек данных, включенных в расчет скользящего среднего.

Другие вопросы по тегам