Скользящие временные интервалы для данных временных рядов в 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
обозначает количество точек данных, включенных в расчет скользящего среднего.