如何将数据帧拆分为与 R 大小相同的元素,并与另一个大小重叠,同时保留每个元素?

How to split a dataframe in elements of the same size with R, overlapped by another size, keeping every element?

我想应用一种称为 CCF Sliding-Windows 的方法,其中我需要将我的时间序列拆分为 windows 90 天,重叠 45 天,最后一部分需要在时间序列的最后一天结束(在某种程度上它可以与前一个拆分重叠超过 45 天)。

举例来说,有一张图来表示这个方法的应用:

有人知道我如何用 R 做到这一点吗?我想创建一个列表来聚合数据帧的时间 windows,这样我就可以 purrr::map 得到互相关。

我将在整数向量上进行演示。为了简洁起见,我不使用“90”和“45”,而是使用“14”和“7”(任意)。

vec <- 100 + 1:28
winsize <- 14
minsize <- 7

最后一个 window 应该从

开始
laststart <- length(vec) - winsize + 1
laststart
# [1] 15

从这里开始,我们可以将其拆分为

starts <- 1 + (seq_len(ceiling(length(vec) / minsize)) - 1) * minsize
starts <- c(starts[starts < 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 <- 100 + 1:40
winsize <- 14
minsize <- ceiling(winsize / 2)
laststart <- length(vec) - winsize + 1
starts <- 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 <- c(starts[starts < 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

您可以从 zoo 开始尝试 rollapply

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