【问题标题】:Elementwise summation of list entries in R [duplicate]R中列表条目的元素总和[重复]
【发布时间】:2021-11-16 21:58:15
【问题描述】:

我有大约 6000 个列表条目,它们都具有相同的格式和维度。我想对列表条目求和以创建一个矩阵,我们在其中获得以下内容

entry [1,1] = list[[1]][1,1]+....+list[[6000]][1,1], 

entry [1,2] = list[[1]][1,2]+....+list[[6000]][1,2]

等等。我有一个可重复的例子:

list_example <- list()
for(i in 1:100){
  list_example[[i]] <- rnorm(100,0,1)
}

【问题讨论】:

    标签: r list


    【解决方案1】:

    尝试Reduce,如下所示

    Reduce(`+`, list_example)
    

    sapply + data.table::transpose

    sapply(data.table::transpose(list_example), sum)
    

    【讨论】:

      【解决方案2】:

      强制转换为 matrix,然后转换为 rowSums

      rowSums(matrix(unlist(list_example), ncol=length(list_example)))
      # [1] 3.452629 1.049781 4.562073
      

      或者在rbind之后使用colSums

      colSums(do.call(rbind, list_example))
      # [1] 3.452629 1.049781 4.562073
      

      数据

      为了清楚起见,我在这里使用了一个较小的列表。

      set.seed(42)
      list_example <- list()
      for(i in 1:4){
        list_example[[i]] <- rnorm(3,0,1)
      }
      

      set.seed(42)
      list_example <- list()
      for(i in seq(1e5)) {list_example[[i]] <- rnorm(3,0,1)}
      microbenchmark::microbenchmark(list2DF=rowSums(list2DF(list_example)),
                                     rowSums=rowSums(matrix(unlist(list_example), ncol=length(list_example))),
                                     Reduce=Reduce(`+`, list_example),
                                     data.table=sapply(data.table::transpose(list_example), sum),
                                     data.table2=unlist(lapply(data.table::transpose(list_example), sum)),
                                     data.table3=vapply(data.table::transpose(list_example), sum, 0),
                                     colSums=colSums(do.call(rbind, list_example)),
                                     times=100L)
      
      # Unit: milliseconds
      #        expr        min         lq       mean     median         uq       max neval  cld
      #     list2DF 736.073711 771.667592 803.028556 795.729308 830.898798 920.98592   100    d
      #     rowSums   7.848909   7.943765   9.436778   8.002277   8.085766 106.27099   100 a   
      #      Reduce  60.616783  65.026398  70.332936  68.337665  71.649778 136.14140   100  b  
      #  data.table   6.371089   6.508093   7.447124   6.671454   6.846889  73.26115   100 a   
      # data.table2   6.286547   6.433442   7.792743   6.578557   6.842724  96.99866   100 a   
      # data.table3   6.254795   6.447059   6.796695   6.597071   6.796004  13.22731   100 a   
      #     colSums  60.533471  69.789563  89.329641  78.337311  95.657619 232.72070   100   c 
      

      【讨论】:

      • 不错的方法,点赞!另外,如果我们想使用rowSums,也许我们可以使用rowSums(list2DF(list_example))
      • @ThomasIsCoding 查看基准,我也包含了list2DF,但速度很慢。干杯!
      • 有趣的基准测试!也许sapply(data.table::transpose(list_example), sum) 可以是另一种选择。
      • @ThomasIsCoding 终于想出了一个更快的rowSums 解决方案!见编辑。
      • @ThomasIsCoding 将data.table 放入您的答案中!这是最快的,我尝试了不同的*apply 变体,但不确定哪个最快。
      【解决方案3】:

      reduce 的另一个选项

      library(purrr)
      reduce(list_example, `+`)
      

      【讨论】:

        猜你喜欢
        • 2015-06-13
        • 1970-01-01
        • 2022-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-28
        • 2022-01-11
        相关资源
        最近更新 更多