1

2つの非常に大きなデータフレーム(50MM以上の行)があり、それらに対していくつかの計算を実行する必要があります。次のループを作成しましたが、実行が遅すぎます。applyやその他の方法を使用してみましたが、機能させることができませんでした。

#### Sample Data
df=data.frame(id=1:10,time=Sys.time()-1:10,within5=NA)
df2=data.frame(id2=c(1,1,1,5,5,10),time2=Sys.time()-c(9,5,2,3,4,6))

#### Loop shows how many results from df2 are within 5 secs of the creation of the ID    in df
for (i in 1:length(df$id))
{
temp=df2[df2$id==df$id[i],]
df$within5[i]=sum(abs(as.numeric(difftime(temp$time2,df$time[i],units="secs")))<5)
}
4

2 に答える 2

3

手順の改善を確認するために、サンプル データを大きくしました。

df=data.frame(id=1:100,time=Sys.time()-1:100)
df2=data.frame(id2=sample(1:100,300000,replace=T),time2=Sys.time()-sample(1:5,300000,replace=T))

ddply()パッケージの関数を使用plyrして、 column に従ってデータを分割しますid2。次に、関数を各サブセットに適用します。

library(plyr)
df3 <- ddply(df2,"id2",function(x){ 
    data.frame(within5=sum(abs(as.numeric(difftime(x$time2,df$time[df$id==x$id2[1]],units="secs")))<5))})

その結果、新しいデータ フレームが取得されます。

 head(df3)
  id2 within5
1   1    3129
2   2    3032
3   3    2935
4   4    3121
5   5    3042
6   6    2426

within5元のデータ フレームに列が必要な場合は、 function を使用できますmerge()

df4 <- merge(df,df3,by.x="id",by.y="id2",all=T)

私のサンプル データでは、この計算は 10 倍速くなりました。

于 2013-01-10T10:11:07.160 に答える
1

上記のデータについて、2 番目の ID を使用して参照時間を検索し、そこからイベント時間を減算します。

dt <- df2$time2 - df$time[df2$id]

次に、絶対時間差が 5 未満のイベント ID を選択します

okIds <- df2$id2[abs(as.numeric(dt)) < 5]

これらを表にして、元のデータ フレームに追加します

df$within5 <- tabulate(okIds, max(df$id))

これは、ID が連続した整数であることに依存しており (そうでない場合は、ID を にしてfactor()から、結果をエンコードする整数を使用します)、非常に高速です。

于 2013-01-10T21:23:50.750 に答える