将相同顺序的矩阵列表转换为数组

时间:2015-02-05 08:40:35

标签: r list matrix

我有一个列表(100个成员),每个成员都是4 * 2矩阵。如何将此列表转换为维度400 * 2的数组,而不使用R中的循环?

例如

A<-list()


A[[1]] 
        x         y
    85.56384 27.97745
    85.58448 28.02133
    85.60252 27.96366
    85.62318 28.00753

依此类推,最后

A[[100]]
         x         y
     85.58448 28.02133
     85.60500 28.06502
     85.62317 28.00754
     85.64372 28.05122

我想拥有    A&lt; -

      x         y
    85.56384 27.97745
    85.58448 28.02133
    85.60252 27.96366
    85.62318 28.00753
         :        :
    85.58448 28.02133
    85.60500 28.06502
    85.62317 28.00754
    85.64372 28.05122

感谢您的帮助。

3 个答案:

答案 0 :(得分:7)

这是对建议的不同策略的基准测试。如果您有新的想法/策略,请随时更新。

# packages
require(data.table)
require(tidyr)
require(microbenchmark)
# data
lst <- replicate(100, matrix(rnorm(16), ncol=4), simplify=FALSE)
# benchmark test
microbenchmark(
  do.call(rbind, lst)
  , 
  Reduce(rbind, lst)
  , 
  apply(simplify2array(lst), 2, rbind)
  , 
  rbindlist(lapply(lst, data.frame))
  , 
  unnest(lapply(lst, data.frame))
  )

结果:

Unit: microseconds
                                 expr       min         lq        mean     median        uq       max neval  
                  do.call(rbind, lst)    43.290    47.9760    55.63858    52.8845    62.703   101.307   100  
                   Reduce(rbind, lst)   542.236   570.7985   620.99652   585.3020   610.518  1871.272   100  
 apply(simplify2array(lst), 2, rbind)   311.061   345.2010   382.22978   368.6315   388.268  1563.782   100  
   rbindlist(lapply(lst, data.frame)) 11827.884 12472.3190 13092.57937 12823.0995 13595.841 15833.736   100   
      unnest(lapply(lst, data.frame)) 12371.905 12927.9765 13514.24261 13236.1360 14008.655 16121.143   100  

出于好奇,我已经为data.frame输入执行了这些基准测试,并且图片非常不同:

# packages
require(data.table)
require(tidyr)
require(microbenchmark)
# data
lst <- replicate(100, as.data.frame(matrix(rnorm(16), ncol=4)), simplify=FALSE)
# benchmark test
microbenchmark(
  do.call(rbind, lst)
  , 
  Reduce(rbind, lst)
  , 
  apply(simplify2array(lapply(lst, as.matrix)), 2, rbind)
  , 
  rbindlist(lst)
  , 
  unnest(lst)
)

结果

Unit: microseconds
                                                    expr       min         lq       mean    median        uq        max neval 
                                     do.call(rbind, lst) 12406.716 12944.2660 13746.8552 13571.966 14564.056  16333.128   100    
                                      Reduce(rbind, lst) 36316.866 38450.7765 39894.9806 39299.610 40325.395 100949.158   100    
 apply(simplify2array(lapply(lst, as.matrix)), 2, rbind)  9577.717  9940.9930 10273.8674 10065.059 10291.996  12114.846   100    
                                          rbindlist(lst)   324.896   369.0770   397.7828   402.995   426.202    500.732   100  
                                             unnest(lst)   926.487   974.9095  1011.7322  1010.834  1033.596   1171.051   100 

答案 1 :(得分:2)

您可以使用Reduce

> lst=list(matrix(1:16, ncol=4), matrix(4:23, ncol=4))
[[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,]    4    9   14   19
[2,]    5   10   15   20
[3,]    6   11   16   21
[4,]    7   12   17   22
[5,]    8   13   18   23

> Reduce(rbind, lst)
      [,1] [,2] [,3] [,4]
 [1,]    1    5    9   13
 [2,]    2    6   10   14
 [3,]    3    7   11   15
 [4,]    4    8   12   16
 [5,]    4    9   14   19
 [6,]    5   10   15   20
 [7,]    6   11   16   21
 [8,]    7   12   17   22
 [9,]    8   13   18   23

根据@Roland的建议,请避免Reduce:)

#> lst=lapply(1:100000, function(u) m+u)
#> system.time(do.call(rbind, lst))
#   user  system elapsed 
#   0.37    0.01    0.39 
#> system.time(Reduce(rbind, lst))
#   user  system elapsed 
# 704.94   38.66  743.96 

答案 2 :(得分:0)

#最简单的解决方案

lst <- replicate(100, matrix(rnorm(16), ncol=4), simplify=FALSE)

mat_array <- do.call(rbind, lst) #this is the answer

ra<-simplify2array(lst) #collection of matrices in an array

dim(ra)

#[1]   4   4 100

Help function for simplify2array