【问题标题】:Aggregate data frame by date and apply different functions to corresponding columns?按日期聚合数据框并将不同的功能应用于相应的列?
【发布时间】:2013-05-13 16:54:09
【问题描述】:

我有以下数据框“DF”,它是一个更大的数据框的一部分:

             X1  X2            X3 X4 X5
4468 2010-03-24   3  1.000000e+00  1  2
7662 2010-03-24   9  3.000000e+00  2  1
1272 2010-03-25   8  2.000000e+00  1  1
1273 2010-03-26   9  0.000000e+00  1  1
1274 2010-03-27   8  0.000000e+00  1  1
4469 2010-03-28   4  0.000000e+00  1  2
7663 2010-03-28   4  3.000000e+00  3  1
8734 2010-03-28   7  4.000000e+00  2  3
1275 2010-03-29   8  0.000000e+00  1  1

如您所见,第一列包含一个日期。我想要做的如下: 我想将此数据框转换为一个新的“DF2”,其中每个日期只有 1 行具有相应的列值:

X2, the average 
X3, the sum
X4, the maximum

每个日期的所有先前值。 X5 不相关,可以删除。结果是这样的:

             X1  X2            X3 X4
7662 2010-03-24   6  4.000000e+00  2  
1272 2010-03-25   8  2.000000e+00  1  
1273 2010-03-26   9  0.000000e+00  1  
1274 2010-03-27   8  0.000000e+00  1  
8734 2010-03-28   5  7.000000e+00  3  
1275 2010-03-29   8  0.000000e+00  1  

有谁知道如何做到这一点?非常感谢您的帮助!

【问题讨论】:

    标签: r sum aggregate average max


    【解决方案1】:
    DF <- read.table(text="             X1  X2            X3 X4 X5
    4468 2010-03-24   3  1.000000e+00  1  2
    7662 2010-03-24   9  3.000000e+00  2  1
    1272 2010-03-25   8  2.000000e+00  1  1
    1273 2010-03-26   9  0.000000e+00  1  1
    1274 2010-03-27   8  0.000000e+00  1  1
    4469 2010-03-28   4  0.000000e+00  1  2
    7663 2010-03-28   4  3.000000e+00  3  1
    8734 2010-03-28   7  4.000000e+00  2  3
    1275 2010-03-29   8  0.000000e+00  1  1",header=TRUE)
    
    library(data.table)
    
    DT <- as.data.table(DF)
    
    DT[,list(X2=mean(X2),X3=sum(X3),X4=max(X4)),by=X1]
    
    #            X1 X2 X3 X4
    # 1: 2010-03-24  6  4  2
    # 2: 2010-03-25  8  2  1
    # 3: 2010-03-26  9  0  1
    # 4: 2010-03-27  8  0  1
    # 5: 2010-03-28  5  7  3
    # 6: 2010-03-29  8  0  1
    

    【讨论】:

    • 不确定行名是否是重要的数据。如果是这样,DT语句可以是DT &lt;- data.table(DF, rowName=rownames(DF))
    • 当取几行的平均值时,你会指定哪个行名?我认为行名在这里并不重要。
    • 抱歉,我应该更具体一些。如果用户想要继续使用DT 代替原来的DF,我的评论更像是一般性的,超出了这个特定任务的范围
    【解决方案2】:

    有很多方法可以做到这一点,但这里有一个sqldf 解决方案:

    library(sqldf)
    sqldf("select X1, avg(X2), sum(X3), max(X4) from DF group by X1")
    

    结果是:

              X1 avg(X2) sum(X3) max(X4)
    1 2010-03-24       6       4       2
    2 2010-03-25       8       2       1
    3 2010-03-26       9       0       1
    4 2010-03-27       8       0       1
    5 2010-03-28       5       7       3
    6 2010-03-29       8       0       1
    

    【讨论】:

      【解决方案3】:

      您可以使用 plyr 包中的 ddply 函数通过某些分组变量进行任意聚合或其他转换。

      对于您的问题,代码如下所示:

      library(plyr)
      result <- ddply(DF, .(X1), function(df) {
        with(df, data.frame( X1=mean(X1), X2=sum(X2), X3=max(X3) ) )
      } )
      

      如果这是一个中大型项目,那么您可能需要设置 progress 参数以显示进度条。对于非常大的问题,可以设置为使用并行处理。

      【讨论】:

      • summarise 是匿名函数的替代选项。
      • 我认为并行化只有在功能之一是速度瓶颈时才有帮助,meansummax 可能不是这种情况。
      【解决方案4】:

      这里是dplyr 方式:

      library(dplyr)
      DF %>%
         group_by(X1) %>%
         summarise(X2 = mean(X2), 
                   X3 = sum(X3), 
                   X4 = max(X4))
      
      #  X1            X2    X3    X4
      #  <fct>      <dbl> <dbl> <dbl>
      #1 2010-03-24    6.    4.    2.
      #2 2010-03-25    8.    2.    1.
      #3 2010-03-26    9.    0.    1.
      #4 2010-03-27    8.    0.    1.
      #5 2010-03-28    5.    7.    3.
      #6 2010-03-29    8.    0.    1.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-11
        • 2017-04-03
        • 1970-01-01
        • 2018-10-01
        • 2020-03-05
        • 1970-01-01
        相关资源
        最近更新 更多