R:在分组条件下聚合大数据帧

时间:2014-02-13 17:56:39

标签: r dataframe grouping aggregate data.table

我正在试图找出聚合大型数据框(大约50M行)的最快方法,它看起来类似于:

>sample_frame = data.frame("id" = rep(sample(1:100,2,replace=F),3),
+ "date" = sample(seq(as.Date("2014-01-01"),as.Date("2014-02-13"),by=1),6),
+ "value" = runif(6))
> sample_frame
  id       date      value
1 73 2014-02-11 0.84197491
2  7 2014-01-14 0.08057893
3 73 2014-01-16 0.78521616
4  7 2014-01-24 0.61889286
5 73 2014-02-06 0.54792356
6  7 2014-01-06 0.66484848

这里我们有2个唯一ID,包含3个日期和分配给每个日期的值。我知道我可以使用ddply或data.table,或只是一个lapply来聚合并找到每个ID的均值。

我真正想要的是一种快速查找最近两个日期的每个ID的平均值的方法。例如,使用sapply:

> sapply(split(sample_frame,sample_frame$id),function(x){
+   mean(x$value[x$date%in%x$date[order(x$date,decreasing=T)][1:2]])
+ })
        7        73 
0.3497359 0.6949492

我无法弄清楚如何获取data.table来做到这一点。思考?提示?

1 个答案:

答案 0 :(得分:4)

为什么不在“data.table”聚合步骤中使用tail

set.seed(1)
sample_frame = data.frame("id" = rep(sample(1:100,2,replace=F),3),
                          "date" = sample(seq(as.Date("2014-01-01"),
                                              as.Date("2014-02-13"),by=1),6),
                          "value" = runif(6))

DT <- data.table(sample_frame, key = "id,date")
DT
#    id       date      value
# 1: 27 2014-01-09 0.20597457
# 2: 27 2014-01-26 0.62911404
# 3: 27 2014-02-07 0.68702285
# 4: 37 2014-02-06 0.17655675
# 5: 37 2014-02-09 0.06178627
# 6: 37 2014-02-13 0.38410372
DT[, mean(tail(value, 2)), by = id]
#    id        V1
# 1: 27 0.6580684
# 2: 37 0.2229450

由于您只需要两个值的平均值,因此可以直接执行(不使用mean)。并且您可以使用内部变量.N而不是尾部来获得更快的速度。你只需要处理只有1个日期的情况。基本上,这应该快得多。

DT[, (value[.N]+value[max(1L, .N-1)])/2, by=id]