【问题标题】:Vector to list of matrices向量到矩阵列表
【发布时间】:2020-06-26 02:07:00
【问题描述】:

我正在尝试将一个向量转换为多个矩阵并将它们保存在一个列表中。

#Create list to save matrix
BSEPRA=vector("list", 420)

#Vector size 6720
temporalRA

我需要使用前 16 个元素构建 4*4 大小的矩阵,然后使用下一个元素 (17:32) 等等,直到 6705:6720 才能拥有 420 并将它们保存在列表中。但这不起作用:

for (i in 1:length(temporalRA)){
temp2<-matrix(temporalRA[seq(1,6720, 16), ],nrow = 4,ncol = 4, )
BSEPRA[[i]]=temp2
}
 

【问题讨论】:

    标签: r matrix vector


    【解决方案1】:
    vec <- 1:32
    split(vec, (seq_along(vec) - 1) %/% (4*4))
    # $`0`
    #  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
    # $`1`
    #  [1] 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
    
    lapply(split(vec, (seq_along(vec) - 1) %/% 16), matrix, nrow = 4, ncol = 4)
    # $`0`
    #      [,1] [,2] [,3] [,4]
    # [1,]    1    5    9   13
    # [2,]    2    6   10   14
    # [3,]    3    7   11   15
    # [4,]    4    8   12   16
    # $`1`
    #      [,1] [,2] [,3] [,4]
    # [1,]   17   21   25   29
    # [2,]   18   22   26   30
    # [3,]   19   23   27   31
    # [4,]   20   24   28   32
    

    如果您担心无法获得 16 的完美倍数,我鼓励您多走一步。

    问题:

    vec <- 1:30
    vecs <- split(vec, (seq_along(vec) - 1) %/% (4*4))
    vecs
    # $`0`
    #  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
    # $`1`
    #  [1] 17 18 19 20 21 22 23 24 25 26 27 28 29 30
    
    lapply(vecs, matrix, nrow = 4)
    # Warning in FUN(X[[i]], ...) :
    #   data length [14] is not a sub-multiple or multiple of the number of rows [4]
    # $`0`
    #      [,1] [,2] [,3] [,4]
    # [1,]    1    5    9   13
    # [2,]    2    6   10   14
    # [3,]    3    7   11   15
    # [4,]    4    8   12   16
    # $`1`
    #      [,1] [,2] [,3] [,4]
    # [1,]   17   21   25   29
    # [2,]   18   22   26   30
    # [3,]   19   23   27   17
    # [4,]   20   24   28   18
    

    (注意17:18 是如何“回收”的。)

    修复:

    vec <- 1:30
    vecs <- split(vec, (seq_along(vec) - 1) %/% (4*4))
    vecs <- lapply(vecs, `length<-`, max(lengths(vecs)))
    vecs
    # $`0`
    #  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
    # $`1`
    #  [1] 17 18 19 20 21 22 23 24 25 26 27 28 29 30 NA NA
    lapply(vecs, matrix, nrow = 4)
    # $`0`
    #      [,1] [,2] [,3] [,4]
    # [1,]    1    5    9   13
    # [2,]    2    6   10   14
    # [3,]    3    7   11   15
    # [4,]    4    8   12   16
    # $`1`
    #      [,1] [,2] [,3] [,4]
    # [1,]   17   21   25   29
    # [2,]   18   22   26   30
    # [3,]   19   23   27   NA
    # [4,]   20   24   28   NA
    

    【讨论】:

      【解决方案2】:

      我认为比拆分向量并遍历列表以生成矩阵更有效的另一种方法是创建一个数组并将其拆分:

      vec <- 1:32
      mdim <- 4
      mdimsq <- mdim^2
      
      asplit(array(vec, dim = c(mdim, mdim, length(vec) / mdimsq)), 3)
      
      [[1]]
           [,1] [,2] [,3] [,4]
      [1,]    1    5    9   13
      [2,]    2    6   10   14
      [3,]    3    7   11   15
      [4,]    4    8   12   16
      
      [[2]]
           [,1] [,2] [,3] [,4]
      [1,]   17   21   25   29
      [2,]   18   22   26   30
      [3,]   19   23   27   31
      [4,]   20   24   28   32
      

      同样,如果向量不是完美的倍数,它可以用 NA 填充:

      vec <- 1:30
      vln <- ceiling(length(vec)/mdimsq) * mdimsq
      if (length(vec) < vln) vec[vln] <- NA 
      
      asplit(array(vec, dim = c(mdim, mdim, length(vec) / mdimsq)), 3)
      
      [[1]]
           [,1] [,2] [,3] [,4]
      [1,]    1    5    9   13
      [2,]    2    6   10   14
      [3,]    3    7   11   15
      [4,]    4    8   12   16
      
      [[2]]
           [,1] [,2] [,3] [,4]
      [1,]   17   21   25   29
      [2,]   18   22   26   30
      [3,]   19   23   27   NA
      [4,]   20   24   28   NA
      

      【讨论】: