2012-04-17 6 views
1

大Rデータフレーム内のすべての行のカウント最適化する方法:すべての一意の名前/日ペアのフィルタリングと、次のような、Iは、データフレームを有する

name day wages 
1 Ann 1 100 
2 Ann 1 150 
3 Ann 2 200 
4 Ann 3 150 
5 Bob 1 100 
6 Bob 1 200 
7 Bob 1 150 
8 Bob 2 100 

を、私は計算したいです「この人の現在または翌日には賃金の回数が175を超えた」などの合計の範囲。賃金よりも多くの列があり、各行に各合計に適用される4つのタイムスライスがあります。

私は現在、私のデータフレームunique'ingによって達成することができますdfに次の関数(わかりやすくするために書かれた手書き)を適用し、df.uniqueのすべての行について

df.unique <- df[!duplicated(df[,c('name','day')]),] 

そしてを:

for(i in 1:nrow(df.unique)) { 
    df.unique[i,"wages_gt_175_day_and_next"] <- wages_gt_for_person_today_or_next(df,175,df.unique[i,"day"],df.unique[i,"name"]) 
} 

wages_gt_for_person_today_or_next <- function(df,amount,day,person) { 
    temp <- df[df$name==person,] 
    temp <- temp[temp$day==day|temp$day==day+1,] 
    temp <- temp[temp$wages > amount,] 
    return(nrow(temp)) 
} 

私は、この簡単な例で私を与えます:

name day wages_gt_175_day_and_next 
Ann 1 1 
Ann 2 1 
Ann 3 0 
Bob 1 1 
Bob 2 0 

しかし、これは私が何十万行もあることを考えると、非常に遅いアプローチのようです。これを行うより洗練された方法がありますか?行列演算、適用、sqldfなど何か?

コード例のDF再現する:

structure(list(name = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L), .Label = c("Ann", "Bob"), class = "factor"), day = c(1, 
1, 2, 3, 1, 1, 1, 2), wages = c(100, 150, 200, 150, 100, 200, 
150, 100)), .Names = c("name", "day", "wages"), row.names = c(NA, 
-8L), class = "data.frame") 

答えて

3

はあなたの例の出力から単純に行くには、ここにdata.tableを使用して少し凝ったです:

require(data.table) 
DT <- data.table(df) 
setkey(DT,name,day) 

DT[,list(gt175 = sum(wages >= 175)),list(name,day)][,list(day = day,gt175 = as.integer(gt175 + c(tail(gt175,-1),0) > 0)),list(name)] 

これは少し複雑ですが、高速である必要があります。

+0

ありがとうございましたジョラン、本当に速いです – Ina

関連する問題