【问题标题】:Convert a matrix into a specific list in R将矩阵转换为 R 中的特定列表
【发布时间】:2016-02-11 16:08:52
【问题描述】:

“a”是一个矩阵,“b”是一个数字。 “a”的行数与“b”的长度一致。

a<-matrix(1:24,6,4,byrow = T)
b<-c(3,1,2)

我想将“a”转换为一个列表,其中每个对象中的元素个数与“b”相同。预期结果如下:

[[1]]
     [,1] [,2] [,3] [,4] 
[1,]    1    2    3    4 
[2,]    5    6    7    8  
[3,]    9   10   11   12 

[[2]]
     [,1] [,2] [,3] [,4] 
[1,]   13   14   15   16 

[[3]]
     [,1] [,2] [,3] [,4] 
[1,]   17   18   19   20  
[2,]   21   22   23   24 

非常感谢您的帮助!

【问题讨论】:

    标签: r list matrix


    【解决方案1】:

    这是一个选项,它将根据b 拆分a,因为这将返回一个原子向量列表,所以我们通过lapply 将其再次转换为matrix

    lapply(split(a, rep(seq_along(b),b)), matrix, ncol = ncol(a))
    #$`1`
    #     [,1] [,2] [,3] [,4]
    #[1,]    1    2    3    4
    #[2,]    5    6    7    8
    #[3,]    9   10   11   12
    #
    #$`2`
    #     [,1] [,2] [,3] [,4]
    #[1,]   13   14   15   16
    #
    #$`3`
    #     [,1] [,2] [,3] [,4]
    #[1,]   17   18   19   20
    #[2,]   21   22   23   24
    

    或者,如果您不介意data.frames 的列表,它可能是:

    split(as.data.frame(a), rep(seq_along(b),b))
    

    【讨论】:

      【解决方案2】:

      你也可以像这样使用mapply()

      id <- mapply(seq, to=cumsum(b), length.out =b)
      lapply(id, function(i) a[i,, drop = FALSE])
      

      或者,如果您想一次性完成所有操作:

      mapply(function(i,j){a[seq(to=i, length.out = j),,drop=FALSE]},
                 i = cumsum(b),
                 j = b)
      

      与使用 lapply(split(...)) 相比,此解决方案的速度大约快 1.5 倍。

      a<-matrix(1:(87*400),87,400,byrow = TRUE)
      b<-c(3, 1, 2, 5, 2, 2, 1, 11, 19, 12, 9, 20)
      
      benchmark(
        {
          id <- mapply(seq, to=cumsum(b), length.out =b)
          lapply(id, function(i)a[i,, drop = FALSE])
        },
        {
          lapply(split(a, rep(seq_along(b),b)), matrix, ncol = ncol(a))
        },
        replications = 10000
      )
      

      给予

        replications elapsed relative user.self sys.self user.child sys.child
      1        10000    3.53    1.000      3.53        0         NA        NA
      2        10000    6.02    1.705      5.95        0         NA        NA
      

      【讨论】:

        【解决方案3】:

        我们可以使用split

        split(as.data.frame(a),cumsum(c(TRUE,diff(sequence(b))!=1)))
        #$`1`
        #  V1 V2 V3 V4
        #1  1  2  3  4
        #2  5  6  7  8
        #3  9 10 11 12
        
        #$`2`
        #  V1 V2 V3 V4
        #4 13 14 15 16
        
        #$`3`
        #  V1 V2 V3 V4
        #5 17 18 19 20
        #6 21 22 23 24
        

        【讨论】:

        • 我认为“c(1, b[-1]), c(b[-length(b)]”写错了
        • @lightsnail 是的,我认为这是一个骗局,没有看它得到的输出。发生这样的事情真是太糟糕了。
        猜你喜欢
        • 2015-05-27
        • 1970-01-01
        • 2015-04-27
        • 2014-05-15
        • 1970-01-01
        • 2015-07-24
        • 2017-03-22
        • 2017-12-22
        • 2018-07-17
        相关资源
        最近更新 更多