【问题标题】:R Function to slice a vector/matrix in a rolling mannerR函数以滚动方式对向量/矩阵进行切片
【发布时间】:2017-10-12 08:54:23
【问题描述】:

我曾经见过这个函数,但现在不记得它的名字了。该函数执行输入向量/矩阵的滚动切片,并输出一个高一维的矩阵。下面是函数的作用:

rolling_slice <- function(v,window){
  rows = length(v)-window+1
  m <- matrix(0,rows,window)
  for(i in 1:rows){m[i,] <- v[i:(i+window-1)]}
  return(m)
}

带有向量输入的示例输出如下所示:

> v <- 1:10
> rolling_slice(v,3)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    2    3    4
[3,]    3    4    5
[4,]    4    5    6
[5,]    5    6    7
[6,]    6    7    8
[7,]    7    8    9
[8,]    8    9   10

尝试找到它的原因是我想加快 R 中的滚动窗口操作,我希望这个函数可以通过预先索引输入数据来提供帮助。

【问题讨论】:

    标签: r zoo sliding-window


    【解决方案1】:

    我刚刚发现了 R 基础函数 embed,现在它是我最喜欢的东西之一:

    > numcol <- 3
    > embed(1:10, numcol)
         [,1] [,2] [,3]
    [1,]    3    2    1
    [2,]    4    3    2
    [3,]    5    4    3
    [4,]    6    5    4
    [5,]    7    6    5
    [6,]    8    7    6
    [7,]    9    8    7
    [8,]   10    9    8
    

    它基本上完全按照您的描述来制作数据的滚动窗口矩阵,第二个输入是窗口大小。如果顺序很重要,您可以使用以下方法反转列:

    embed(1:10, numcol)[ , numcol:1]
    

    【讨论】:

    • 是的!这正是我正在寻找的功能。非常感谢!
    【解决方案2】:

    zoo:rollapply/rapply()roll*() 之类的声音是您所需要的。 您的实际最终应用是什么:滚动均值、中位数、加权和、过滤器、滚动标准差等等?我怀疑您的最终应用程序只是采用滑动窗口切片。生成大量不必要的临时数据结构是没有意义的,因为它会消耗内存和性能。

    另外,就性能而言,这听起来像是data.table 的顺序访问将击败 dplyr/tibbles/tidyverse 的情况。你用的是什么数据结构?

    【讨论】:

    • 我需要对一堆时间序列执行一些滚动相关/回归,可能具有不同的滚动窗口。我想快速完成它们。我一直在使用 data.tables,我喜欢它。但是好像没有快速滚动的apply功能
    • @Bill:大概您打开了 JIT,也进行了分析,并且可能对您的情况进行了硬编码 lm,它有一些缺陷。如果您告诉我们什么是输入向量/矩阵大小 N、列数 C 和窗口大小 W,这会有所帮助。我真诚地怀疑您是否想要存储 N 个完整模型,只存储它们的系数。
    • @Bill:其他用户正在使用 rollapplydata.table,如果您发现性能不佳,请发布实际数字并标记/标题 data.frame。此外,如果您要生成大量模型,请将它们存储为 biglm 而不是 lm Is there a way to 'compress' an lm() class for later prediction?
    【解决方案3】:

    您可以在基础 R 中进行矢量化处理:

    window <- 3
    m <- diag(length(v)-window+1)
    (row(m)+col(m)-1)[,1:window]
    
        # [,1] [,2] [,3]
    # [1,]    1    2    3
    # [2,]    2    3    4
    # [3,]    3    4    5
    # [4,]    4    5    6
    # [5,]    5    6    7
    # [6,]    6    7    8
    # [7,]    7    8    9
    # [8,]    8    9   10
    

    【讨论】:

      猜你喜欢
      • 2018-09-01
      • 2013-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-23
      相关资源
      最近更新 更多