【问题标题】:Extract series of successive vectors from matrix从矩阵中提取一系列连续向量
【发布时间】:2017-07-22 15:34:29
【问题描述】:

为了简化,我有一个大矩阵:

> mat = matrix(c(1:50), ncol = 5)
> mat
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1   11   21   31   41
 [2,]    2   12   22   32   42
 [3,]    3   13   23   33   43
 [4,]    4   14   24   34   44
 [5,]    5   15   25   35   45
 [6,]    6   16   26   36   46
 [7,]    7   17   27   37   47
 [8,]    8   18   28   38   48
 [9,]    9   19   29   39   49
[10,]   10   20   30   40   50

我想从每列中连续提取由 3 个元素组成的所有可能的垂直向量,例如(1,2,3), (2,3,4),...,(11,12,13)​​, (12,13,14),... 并生成由以下组成的 3×X 矩阵所有这些向量。 看起来像这样的东西:

      [,1] [,2] [,3] 
 [1,]    1   2   3 
 [2,]    2   3   4 
 [3,]    3   4   5 
 etc.    .   .   . 
 [5,]    11   12   13 
 [6,]    12   13   14 
 [7,]    13   14   15 
 etc.    ..   ..   .. 
 [9,]    21   22   23 
[10,]    22   23   24 

我尝试过使用 lapply 和 cbind 函数,以及更通用的 for 循环,但它显示“维数不正确”。感谢您的帮助!

【问题讨论】:

    标签: r matrix vector


    【解决方案1】:

    我们可以通过base R 做到这一点

    do.call(rbind, lapply(as.data.frame(mat), embed, 3))[,3:1]
    #       [,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
    # [9,]   11   12   13
    #[10,]   12   13   14
    #[11,]   13   14   15
    #[12,]   14   15   16
    #[13,]   15   16   17
    #[14,]   16   17   18
    #[15,]   17   18   19
    #[16,]   18   19   20
    #[17,]   21   22   23
    #[18,]   22   23   24
    #[19,]   23   24   25
    #[20,]   24   25   26
    #[21,]   25   26   27
    #[22,]   26   27   28
    #[23,]   27   28   29
    #[24,]   28   29   30
    #[25,]   31   32   33
    #[26,]   32   33   34
    #[27,]   33   34   35
    #[28,]   34   35   36
    #[29,]   35   36   37
    #[30,]   36   37   38
    #[31,]   37   38   39
    #[32,]   38   39   40
    #[33,]   41   42   43
    #[34,]   42   43   44
    #[35,]   43   44   45
    #[36,]   44   45   46
    #[37,]   45   46   47
    #[38,]   46   47   48
    #[39,]   47   48   49
    #[40,]   48   49   50
    

    【讨论】:

    • 作为替代方案,可以直接调用embed -- n = 3; embed(c(mat), n),然后找到一种方法来子集化冗余行,例如..[-c(outer(nrow(mat) * (1:(ncol(mat) - 1)), 0:(n - 2), "-")), n:1]
    【解决方案2】:

    像这样?

    编辑:根据 Grothendieck 在评论中的建议,将 rollapply 中的函数从 'print' 修改为 'c'。

    library(zoo)
    do.call(rbind,lapply(as.data.frame(mat), function(x) rollapply(x,width=3,c)))
    
          [,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
     [9,]   11   12   13
    [10,]   12   13   14
    [11,]   13   14   15
    [12,]   14   15   16
    [13,]   15   16   17
    [14,]   16   17   18
    [15,]   17   18   19
    [16,]   18   19   20
    [17,]   21   22   23
    [18,]   22   23   24
    [19,]   23   24   25
    [20,]   24   25   26
    [21,]   25   26   27
    [22,]   26   27   28
    [23,]   27   28   29
    [24,]   28   29   30
    [25,]   31   32   33
    [26,]   32   33   34
    [27,]   33   34   35
    [28,]   34   35   36
    [29,]   35   36   37
    [30,]   36   37   38
    [31,]   37   38   39
    [32,]   38   39   40
    [33,]   41   42   43
    [34,]   42   43   44
    [35,]   43   44   45
    [36,]   44   45   46
    [37,]   45   46   47
    [38,]   46   47   48
    [39,]   47   48   49
    [40,]   48   49   50
    

    【讨论】:

    • 或者这个变体:do.call(rbind, lapply(as.data.frame(mat), rollapply, 3, c))
    • 感谢分享,这种变化是一个很好的改进!又学到新东西了:)
    • 太好了,很高兴我能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2014-12-29
    • 2014-05-11
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    相关资源
    最近更新 更多