【问题标题】:how to combine 60 matrices in R quickly如何在 R 中快速组合 60 个矩阵
【发布时间】:2013-06-22 18:30:34
【问题描述】:

我在 R 中有 60 个矩阵,命名为 mat1、mat2....mat60,我想使用 rbind 将它们组合成一个大矩阵。我知道我可以写类似的东西

matList <- list(mat1, mat2, ... mat60)
rbind(matList)

但这似乎是一个非常愚蠢的解决方案。知道如何简化流程吗?

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    我认为它们都有相同的列数(以及相同的colnames)。如果是这样,试试这个:

    do.call("rbind", matlist)
    

    否则:

    matlist <- lapply(matlist, as.data.frame)
    
    library(plyr)
    rbind.fill(matlist)
    

    编辑:

    添加一些时间:

    lst <- list()
    
    for(i in 1:1000)
      lst[[i]] <- matrix(rnorm(10000, 100))
    
    f1 <- function()
      do.call("rbind", lst)
    
    f2 <- function(){
      lst <- lapply(lst, as.data.table)
      rbindlist(lst)
    }
    
    library(data.table)
    library(microbenchmark)
    
    > microbenchmark(f1(), f2())
    Unit: milliseconds
     expr       min        lq    median        uq      max neval
     f1()  53.78661  55.22728  63.43546  66.08829 103.1996   100
     f2() 210.46232 215.32043 217.93846 221.35012 333.2758   100
    

    如果 OP 将他的数据保存在矩阵中,我认为包含 lst &lt;- lapply(lst, as.data.table) 是正确的比较方式。否则会是:

    > lst.dt <- lapply(lst, as.data.table)
    > f2 <- function(){
    +   rbindlist(lst.dt)
    + }
    > microbenchmark(f1(), f2())
    Unit: milliseconds
     expr      min       lq   median       uq      max neval
     f1() 49.00308 50.28515 54.98947 60.71945 87.66487   100
     f2() 24.23454 28.57692 31.79278 32.75494 63.78825   100
    

    【讨论】:

    • 请注意,在矩阵的情况下,do.call(rbind 中的列名无关紧要 - rbind 不会关心名称是否不同;只有当那些是 data.frames 时它才会抱怨(它可能不会做你想做的事,但它不会抱怨)
    • 我知道 (...) 第一列和第一列,第二列和第二列。并且colnames 将从第一个矩阵中获取。但它没有意义......
    • @Michele 我可能会建议您在基准测试中添加@JackManey 命题,并仅使用for 循环...当然是基准测试+1。
    • @agstudy 你的意思是第一个和第二个,结果是第三个,然后是第四个等等? :-D 这会很有趣... :-))) 一秒
    • 另一个基准建议 - 转换为 data.frame: lst.df = lapply(lst, as.data.frame),并尝试使用 do.call(rbind, 方法(这是为了说明拥有 data.table 真的重要)
    【解决方案2】:

    我认为这个问题真的与 OP 必须手动输入矩阵的名称有关。您可以使用mget 返回列表中的矩阵,然后使用@Michele 提出的do.callrbind(假设矩阵位于.GlobalEnv 中):

    matList <- mget(paste0("mat",1:60),env=globalenv())
    bigm <- do.call("rbind" , matList)
    

    【讨论】:

    • 是的!你可能是对的! OP主要需要mget。他绝对没有提到任何清单。他只是输入了list(mat1, mat2, .., mat60)
    • @Michele 对所有时间的回答都很好。 +1 给你。
    【解决方案3】:

    这应该更快:

     library(data.table)
     rbindlist(matList)
    

    编辑 上述解决方案适用于 data.frame 或列表列表,如果您有矩阵列表,则应先转换它们:

     rbindlist(lapply(ll,as.data.frame))
    

    【讨论】:

    • 尚未实现(尚未?)矩阵:“列表输入的第 1 项不是 data.frame、data.table 或列表”
    • 确实如此!如果rbindlist 可以包含rbind.fill 的“填充”功能,那就太好了
    • @eddi 那么它可能是一个矩阵(或通用向量)。这是rbindlist的第二个缺点
    • @agstudy 我从来没有说过它可以。我的主要答案 id do.call...关于使用 matrix 的性能通常更快。我只在需要连接和多类结构时才使用 df 和 dt
    • @Michele 所以合乎逻辑的结论是编辑您的答案并删除 rbind.fill 部分,因为它不正确(就 OP 问题而言);或编辑它并解释plyr 部分是关于不同的问题
    猜你喜欢
    • 2020-08-19
    • 2018-01-23
    • 1970-01-01
    • 2018-09-03
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    相关资源
    最近更新 更多