我正在试图找出聚合大型数据框(大约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来做到这一点。思考?提示?
答案 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]