Как разделить фрейм данных на элементы одинакового размера с R, перекрывающиеся другим размером, сохраняя каждый элемент?

#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