将矩阵列表的列表组合成矩阵列表

Combine list of lists of matrices into a list of matrices

我有一个比较大的列表。列表的每个元素都是六个元素的列表。这些元素中的每一个都是具有固定行数和可变列数的矩阵。我想组合这些矩阵,这样我最终得到一个包含六个矩阵的列表,其中每个矩阵都是对每个子列表中的相应元素调用 cbind 的结果,即第一个矩阵是内部所有第一个矩阵的 cbind列表,第二个矩阵是第二个矩阵的cbind,等等

例如:

 temp = list()
 temp[["a"]] = list(matrix(1, nrow=2, ncol=1), matrix(2, nrow=2,ncol=2))
 temp[["b"]] = list(matrix(3, nrow=2, ncol=3), matrix(4, nrow=2,ncol=4))

*调用一些 R 代码* 应该得到

的输出
$`1`
     [,1] [,2] [,3] [,4]
[1,]    1    3    3    3
[2,]    1    3    3    3

$`3`
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    2    4    4    4    4
[2,]    2    2    4    4    4    4

我可以看到调用

mapply(cbind, temp[[1]], temp[[2]])

为这个玩具示例生成所需的输出,但我是否为一个大列表执行此操作,从执行到执行可能有可变数量的元素。

是否有一个优雅且高效的解决方案?

提前致谢!

do.call(mapply, c(cbind, temp))

我们可以使用 purrrcbind

中的 transpose
library(purrr)
lapply(transpose(temp), function(x) do.call(cbind, x))

或者我们可以只使用 transposepurrr

中的 map
transpose(temp) %>% 
            map(~matrix(unlist(.), nrow=2))
#[[1]]
#      [,1] [,2] [,3] [,4]
#[1,]    1    3    3    3
#[2,]    1    3    3    3

#[[2]]
#     [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]    2    2    4    4    4    4
#[2,]    2    2    4    4    4    4

我们也可以尝试 split 选项

library(data.table)
with(melt(temp), lapply(split(value, L1), matrix, nrow=2))

基准

set.seed(24)
lst <- lapply(1:1e5, function(x) replicate(2, matrix(sample(1:5, 10, 
   replace=TRUE), nrow=2), simplify = FALSE))

system.time({

 do.call(mapply, c(cbind, lst))

})
#  user  system elapsed 
#   0.66    0.00    0.65 

system.time({
  lst %>% pmap(cbind)

})
#  user  system elapsed 
#   0.61    0.00    0.61 

system.time({
  lapply(transpose(lst), function(x) do.call(cbind, x))
})
# user  system elapsed 
#   0.39    0.00    0.40 

library(microbenchmark)
microbenchmark(Hong = do.call(mapply, c(cbind, lst)),
   ae = lst %>% pmap(cbind),
   akrun =  lapply(transpose(lst), function(x) do.call(cbind, x)), 
   unit = "relative")
#    Unit: relative
#   expr      min       lq     mean   median       uq      max neval
#   Hong 1.716893 2.346379 1.975948 2.069316 2.012889 1.288478   100
#     ae 1.623129 2.096566 1.697061 1.805834 1.702961 1.193930   100
#  akrun 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000   100

purrr::pmap 并行遍历列表项并传递给您指定的函数,因此您只需

即可获得所需的结果
library(purrr)

temp %>% pmap(cbind)
## [[1]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    3    3
## [2,]    1    3    3    3
## 
## [[2]]
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    2    2    4    4    4    4
## [2,]    2    2    4    4    4    4