【问题标题】:Mean of vector inside of list of lists列表列表中向量的平均值
【发布时间】:2014-08-20 03:21:56
【问题描述】:

我有一个具有以下结构的列表:

> mylist <- list(list(a=as.numeric(1:3), b=as.numeric(4:6)), 
                 list(a=as.numeric(6:8), b=as.numeric(7:9)))
> str(mylist)
List of 2
 $ :List of 2
  ..$ a: num [1:3] 1 2 3
  ..$ b: num [1:3] 4 5 6
 $ :List of 2
  ..$ a: num [1:3] 6 7 8
  ..$ b: num [1:3] 7 8 9

我想得到mylist 的向量ab 之间的元素均值。对于向量a,结果是这样的:

> a
[1] 3.5 4.5 5.5

我知道函数lapplyrbindcolMeans,但我无法用它们解决问题。我怎样才能达到我的需要?

【问题讨论】:

    标签: r list mean


    【解决方案1】:

    这是一种使用“reshape2”中的meltdcast 的方法。

    library(reshape2)
    
    ## "melt" your `list` into a long `data.frame`
    x <- melt(mylist)
    
    ## add a "time" variable to let things line up correctly
    ## L1 and L2 are created by `melt`
    ## L1 tells us the list position (1 or 2)
    ## L2 us the sub-list position (or name)
    x$time <- with(x, ave(rep(1, nrow(x)), L1, L2, FUN = seq_along))
    
    ## calculate whatever aggregation you feel in the mood for
    dcast(x, L2 ~ time, value.var="value", fun.aggregate=mean)
    #   L2   1   2   3
    # 1  a 3.5 4.5 5.5
    # 2  b 5.5 6.5 7.5
    

    这是基础 R 中的一种方法:

    x <- unlist(mylist)
    c(by(x, names(x), mean))
    #  a1  a2  a3  b1  b2  b3 
    # 3.5 4.5 5.5 5.5 6.5 7.5 
    

    【讨论】:

    • 这个“unlist”更好更干净!我非常怀疑使用“recursive = T”并且从未注意到任何可能的分组因素..
    【解决方案2】:

    更新:更好的是...sapply(mylist, unlist) 实际上为我们提供了一个很好的矩阵来应用rowMeans

    > rowMeans(sapply(mylist, unlist))
    #  a1  a2  a3  b1  b2  b3 
    # 3.5 4.5 5.5 5.5 6.5 7.5 
    

    原文: 另一个lapply 方法,其中抛出了sapply

    > lapply(1:2, function(i) rowMeans(sapply(mylist, "[[", i)) )
    # [[1]]
    # [1] 3.5 4.5 5.5
    #
    # [[2]]
    # [1] 5.5 6.5 7.5
    

    【讨论】:

      【解决方案3】:

      另一个想法:

      tmp = unlist(mylist, F)
      sapply(unique(names(tmp)), 
             function(x) colMeans(do.call(rbind, tmp[grep(x, names(tmp))])))
      #       a   b
      #[1,] 3.5 5.5
      #[2,] 4.5 6.5
      #[3,] 5.5 7.5
      

      【讨论】:

      • +1。我也刚刚发布了一个unlist 相关的答案,但与这个完全不同:-)
      【解决方案4】:

      这是data.tableRcppRoll 的组合(对于大型列表来说应该非常快)

      library(data.table)
      library(RcppRoll)
      roll_mean(as.matrix(rbindlist(mylist)), 4, weights=c(1,0,0,1))
      
      ##     [,1] [,2]
      ## [1,]  3.5  5.5
      ## [2,]  4.5  6.5
      ## [3,]  5.5  7.5
      

      【讨论】:

        【解决方案5】:

        许多可能的方法之一,通过data.frame

        mylist <- list(list(a = 1:3, b = 4:6),list(a = 6:8, b = 7:9))
        
        sapply(c("a","b"),function(x){
          listout <- lapply(mylist,"[[",x)
          rowMeans(do.call(cbind,listout))
        })
        
               a   b
        [1,] 3.5 5.5
        [2,] 4.5 6.5
        [3,] 5.5 7.5
        

        【讨论】:

        • 这不是正确的结果。 (1+6)/2 == 3.5,而不是 2.5
        猜你喜欢
        • 1970-01-01
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        • 2016-06-14
        • 1970-01-01
        • 2021-09-30
        • 2015-12-05
        • 1970-01-01
        相关资源
        最近更新 更多