首页 文章

将矩阵列表列表组合到矩阵列表中

提问于
浏览
0

我有一个相对较大的清单 . 列表的每个元素都是六个元素的列表 . 这些元素中的每一个都是具有固定行数和可变列数的矩阵 . 我想结合矩阵,最终得到一个六个矩阵的列表,其中每个矩阵是从每个子列表中的相应元素调用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]])

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

这是一个优雅和高效的解决方案吗?

提前致谢!

3 回答

  • 2

    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
    
  • 2
    do.call(mapply, c(cbind, temp))
    
  • 2

    我们可以使用 transpose 来自 purrrcbind

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

    或者我们可以使用 transposemap 来自 purrr

    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
    

相关问题