2014-02-13 44 views
2

我試圖找出聚合看起來類似於一個大的數據幀(約50M行)的最快方法:R:下大彙總數據幀分組條件

>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個具有3個日期的唯一ID和分配給每個日期的值。我知道我可以使用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

好問題,對不清楚的抱歉。是的,每個ID的日期應該是唯一的。如果有隻有1行的組,則應該返回該行的值。 – nfmcclure

+0

沒有NA值,數據是乾淨的。 – nfmcclure

回答

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而不是尾部來獲得更多的加速。你只需要處理只有一個日期的情況。基本上,這應該快得多。

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