【问题标题】:How is using aggregate function in R vs sum(Dataframe$columns)/N different?在 R 与 sum(Dataframe$columns)/N 中使用聚合函数有何不同?
【发布时间】:2015-11-11 01:20:54
【问题描述】:

我有一个如下所示的数据框 X:

A B C D E Identifier  
1 2 3 4 5          a  
2 3 2 2 1          b  
4 5 4 5 3          a   
2 3 4 5 6          a  
0 0 1 2 3          a  
1 2 1 1 1          b  

(这里的范围是 6,因为记录观察的时间段是 6。​​)

现在我想根据标识符计算 A、B、C、D、E 中的每一个的平均值。为此,我使用了 Process1

avgcalls <- function(calls){
  totcalls <- sum(calls)
  out <- totcalls/6
  return(out)
}

avgcallsdf <- data.frame((aggregate(X[, 1:4], by = X[6], avgcalls)))

输出是这样的

  Identifier        A          B    C     D
1          a  1.66667  1.6666667  2.0   2.5 
2          b  0.50000  0.8333333  0.5   0.5

或者我做了(请提出更好的方法)
Process2

samp1<-D[which(D$Identifier=='a')] #creating one dataframe with identifier as 'a'  
samp2<-D[which(D$Identifier=='b')]#creating another dataframe with'b'as identifier  

#calculating means   
mean1<-sum(sampl$A, na.rm=TRUE)/6  
mean2<-sum(sampl$B, na.rm=TRUE)/6  
mean3<-sum(sampl$C, na.rm=TRUE)/6  
mean4<-sum(sampl$D, na.rm=TRUE)/6
mean5<-sum(samp1$E, na.rm=TRUE)/6
finaldf<-data.frame(mean1,mean2,mean3,mean4,mean5)

与上面的 samp2 类似 两个结果是相同的。

我的实际数据有 1008 列和大约 80,000 行,结果是否会有所不同 如果存在 NA,则处理 1 和 Process2?

我看过这个Getting different results using aggregate() and sum() functions in R,但它不是很有帮助

【问题讨论】:

    标签: r aggregate average


    【解决方案1】:

    我们也可以使用data.table

    library(data.table)
    setDT(df1)[, lapply(.SD, mean), Identifier]
    #   Identifier    A   B   C   D    E
    #1:          a 1.75 2.5 3.0 4.0 4.25
    #2:          b 1.50 2.5 1.5 1.5 1.00
    

    如果我们需要sum 除以n=6

    setDT(df1)[, lapply(.SD, function(x) sum(x, na.rm=TRUE)/6), Identifier] 
    #   Identifier        A         B   C        D         E
    #1:          a 1.166667 1.6666667 2.0 2.666667 2.8333333
    #2:          b 0.500000 0.8333333 0.5 0.500000 0.3333333
    

    【讨论】:

      【解决方案2】:

      这是在dplyr 中用两行解决这个问题的好方法。

      library(dplyr)
      df <- data.frame(A=c(1, 2, 4, 2, 0, 1),  B=c(2, 3, 5, 3 ,0, 2),  C=c(3, 2, 4, 4, 1, 1), D=c(4, 2, 5, 5, 2, 1),  E=c(5, 1, 3, 6, 3, 1), Identifier=c('a', 'b', 'a', 'a', 'a', 'b'))  
      
      df %>%
        group_by(Identifier) %>%
        summarise(A =  mean(A), B = mean(B), C = mean(C), D = mean(D), E = mean(E))
      

      应该给你

        Identifier     A   B    C    D     E
            a       1.75 2.5  3.0  4.0  4.25
            b       1.50 2.5  1.5  1.5  1.00
      

      (注意我的数字和你的不同——我希望这是因为你在整个数据集上运行了这个,而不是像我那样只在头部)。

      编辑:
      您也可以按照@TheTime 所说的做,并节省一些墨水:
      summarise_each(funs(mean))

      【讨论】:

      • dplyr 解决方案如何扩展到 1008 列?
      • 好问题。也许 OP 可以尝试并报告。
      • 我假设做一个 microbenchmark() 测试给了我们一种方法来告诉我们 dplyr 与其他人相比如何扩展
      【解决方案3】:

      您可以通过公式界面更简单地使用aggregate
      编辑您的函数还可以让您更轻松地为分母传递n=

      avgcalls <- function(x,n) sum(x,na.rm=TRUE)/n
      aggregate(. ~ Identifier, data=dat, FUN=avgcalls, n=6, na.action=na.pass)
      
      #  Identifier        A         B   C        D         E
      #1          a 1.166667 1.6666667 2.0 2.666667 2.8333333
      #2          b 0.500000 0.8333333 0.5 0.500000 0.3333333
      

      【讨论】:

      • 非常感谢。这很好。是不是说聚合函数只是简单地执行了process2的步骤,但是屏蔽了它?
      • @krazzyr - 差不多,是的
      【解决方案4】:

      另一种使用“聚合”的解决方案,以“a”作为数据框,假设“标识符”在最后一列:

      aggregate(a[-c(ncol(a))], by=list(Identifier = a$Identifier), FUN=mean)
      

      或者更简洁,使用@thelatemail 指出的公式界面:

      aggregate(. ~ Identifier, data=a, FUN=mean)
      

      给出:

        Identifier    A   B   C   D    E
      1          a 1.75 2.5 3.0 4.0 4.25
      2          b 1.50 2.5 1.5 1.5 1.00
      

      【讨论】:

        猜你喜欢
        • 2014-02-24
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 2019-04-06
        • 1970-01-01
        相关资源
        最近更新 更多