【问题标题】:How to split a dataframe in elements of the same size with R, overlapped by another size, keeping every element?如何将数据框拆分为与 R 大小相同的元素,由另一个大小重叠,保留每个元素?
【发布时间】:2022-01-11 06:11:17
【问题描述】:

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

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

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

【问题讨论】:

    标签: r time-series tidyverse purrr cross-correlation


    【解决方案1】:

    您可以从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
    

    【讨论】:

      【解决方案2】:

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

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

      最后一个窗口应该开始于

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        • 2020-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多