#r #time-series #tidyverse #purrr #cross-correlation
#r #временные ряды #tidyverse #мурррр #перекрестная корреляция
Вопрос:
Я хочу применить метод, называемый скользящими окнами CCF, в котором мне нужно разделить свой временной ряд на окна продолжительностью 90 дней, перекрывающиеся на 45 дней, и последняя часть должна заканчиваться ровно в последний день временного ряда (таким образом, он может перекрываться более чем на 45 дней с предыдущим разделением).
Для примера приведем изображение, представляющее применение этого метода:
Кто-нибудь знает, как я могу это сделать с помощью R? Я хочу создать список, который объединяет временные окна фрейма данных, чтобы я мог мурлыкать::сопоставить, чтобы получить перекрестную корреляцию.
Ответ №1:
Я продемонстрирую на векторе целых чисел. Вместо того, чтобы использовать «90» и «45», я буду использовать «14» и «7» (произвольно) для краткости.
vec lt;- 100 1:28 winsize lt;- 14 minsize lt;- 7
Последнее окно должно начинаться с
laststart lt;- length(vec) - winsize 1 laststart # [1] 15
Отсюда мы можем разделить его на
starts lt;- 1 (seq_len(ceiling(length(vec) / minsize)) - 1) * minsize starts lt;- c(starts[starts lt; laststart], laststart) Map(function(a, b) vec[a:b], starts, starts - 1 winsize) # [[1]] # [1] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 # [[2]] # [1] 108 109 110 111 112 113 114 115 116 117 118 119 120 121 # [[3]] # [1] 115 116 117 118 119 120 121 122 123 124 125 126 127 128
Каждая из них имеет длину 14, и последняя заканчивается на последнем элементе vec
.
Если данные не полностью выровнены, это все равно работает.
vec lt;- 100 1:40 winsize lt;- 14 minsize lt;- ceiling(winsize / 2) laststart lt;- length(vec) - winsize 1 starts lt;- 1 (seq_len(ceiling(length(vec) / minsize)) - 1) * minsize # the last window is at most minsize, we need it to be between minsize and winsize starts lt;- c(starts[starts lt; laststart], laststart) Map(function(a, b) vec[a:b], starts, starts - 1 winsize) # [[1]] # [1] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 # [[2]] # [1] 108 109 110 111 112 113 114 115 116 117 118 119 120 121 # [[3]] # [1] 115 116 117 118 119 120 121 122 123 124 125 126 127 128 # [[4]] # [1] 122 123 124 125 126 127 128 129 130 131 132 133 134 135 # [[5]] # [1] 127 128 129 130 131 132 133 134 135 136 137 138 139 140
Ответ №2:
Вы можете попробовать rollapply
с zoo
.
library(zoo) # your data "ts" # window size 90 # function 'c' gives you the data # your overlap 45 # partial window at the end either "TRUE" or # the minimum window size allowed, e.g. half window size # align starts with first full window on left side rollapply( ts, 90, c, by=45, partial=45, align="left" ) # e.g. rollapply( 1:20, 5, c, by=3, partial=3, align="left" ) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 4 5 6 7 8 [3,] 7 8 9 10 11 [4,] 10 11 12 13 14 [5,] 13 14 15 16 17 [6,] 16 17 18 19 20