R数据框中的观察总和(按类似值分组)

时间:2016-06-16 07:05:15

标签: r dataframe

数据框由变量DateTypeTotal组成,其中TypeBuySell

我们如何对观察结果进行分组,以便只将相同Type的相邻观测值组合在一起,然后对每组中所有观测值的Total求和。换句话说,我们会继续向当前组添加下一个观察结果,直到Type的值发生变化。

例如,在下面的数据框中,组如下

  • Obs 1& 2
  • Obs 3& 4
  • Obs 5& 6
  • Obs 78& 9

enter image description here

可重复的数据,谢谢@bgoldst:

df1 <- data.frame(Date=rep(as.POSIXct('2016-06-16 06:27:39'),9L),
                  Type=c('Buy','Buy','Sell','Sell','Buy','Buy','Sell','Sell','Sell'),
                  Total=c(1.548012e+01,1.051480e+02,5.956740e+00,3.872415e+01,1.333391e+02,1.941060e-01,1.941060e-01,1.941060e-01,3.277059e-01))

2 个答案:

答案 0 :(得分:2)

这是一个围绕aggregate()构建的稍微丑陋的基础R解决方案。它使用Typecumsum()的连续元素之间的不等式比较来合成瞬态分组列,以区分Type的非顺序实例。

df <- data.frame(Date=rep(as.POSIXct('2016-06-16 06:27:39'),9L),Type=c('Buy','Buy','Sell','Sell','Buy','Buy','Sell','Sell','Sell'),Total=c(1.548012e+01,1.051480e+02,5.956740e+00,3.872415e+01,1.333391e+02,1.941060e-01,1.941060e-01,1.941060e-01,3.277059e-01));
aggregate(Total~Date+Type+TypeSeq,transform(df,TypeSeq=c(0L,cumsum(Type[-1L]!=Type[-nrow(df)]))),sum)[-3L];
##                  Date Type       Total
## 1 2016-06-16 06:27:39  Buy 120.6281200
## 2 2016-06-16 06:27:39 Sell  44.6808900
## 3 2016-06-16 06:27:39  Buy 133.5332060
## 4 2016-06-16 06:27:39 Sell   0.7159179

使用data.table实现相同的想法:

library(data.table);
dt <- as.data.table(df);
dt[,.(Total=sum(Total)),.(Date,Type,TypeSeq=c(0L,cumsum(Type[-1L]!=Type[-nrow(dt)])))][,-3L,with=F];
##                   Date Type       Total
## 1: 2016-06-16 06:27:39  Buy 120.6281200
## 2: 2016-06-16 06:27:39 Sell  44.6808900
## 3: 2016-06-16 06:27:39  Buy 133.5332060
## 4: 2016-06-16 06:27:39 Sell   0.7159179

答案 1 :(得分:0)

使用data.table的简单解决方案(最新稳定版,CRAN上的v1.9.6):

require(data.table)
# Create group id *and* aggregate in one-go using expressions in 'by'
setDT(df)[, .(total = sum(Total)), by=.(group=rleid(Type), Date)]

#    group                Date       total
# 1:     1 2016-06-16 06:27:39 120.6281200
# 2:     2 2016-06-16 06:27:39  44.6808900
# 3:     3 2016-06-16 06:27:39 133.5332060
# 4:     4 2016-06-16 06:27:39   0.7159179