2016-08-12 19 views
2

Rでは、異なるウィンドウ幅を使用して大きなベクトル(最大400k要素)の非常に高速なローリング平均を実行しようとしています。その後、各ウィンドウ幅について、 。以下の例は、うまくいけば分かります。 私はいくつかのアプローチを試しましたが、今のところ最速のものは、実行中の平均値はRcppRollパッケージのroll_mean、最大値はaggregateです。 メモリ要件は懸念されています。一度に1つのローリング平均と集計を行うため、以下のバージョンではメモリがほとんど必要ありません。これが好ましい。 data.frame 15と行と各WWの最大を含む120カラム(窓幅)と、各年(2001から2015年):高速ローリング平均+要約

#Example data frame of 10k measurements from 2001 to 2014 
n <- 100000 
df <- data.frame(rawdata=rnorm(n), 
       year=sort(sample(2001:2014, size=n, replace=TRUE)) 
       ) 

ww <- 1:120 #Vector of window widths 

dfsumm <- as.data.frame(matrix(nrow=14, ncol=121)) 
dfsumm[,1] <- 2001:2014 
colnames(dfsumm) <- c("year", paste0("D=", ww)) 

system.time(for (i in 1:length(ww)) { 
    #Do the rolling mean for this ww 
    df$tmp <- roll_mean(df$rawdata, ww[i], na.rm=TRUE, fill=NA) 
    #Aggregate maxima for each year 
    dfsumm[,i+1] <- aggregate(data=df, tmp ~ year, max)[,2] 
}) #28s on my machine 
dfsumm 

これは、所望の出力を与えます。

しかし、計算には時間がかかります(これらの計算には数千時間を要します)。私は他のオプション、つまりdplyrdata.tableで遊んでみましたが、私はそれらのパッケージの知識が不足しているために何かをより速く見つけることができませんでした。

これを実行する最も速い方法は、(コードはすでに別の場所で並列化されています)です。

答えて

7

メモリ管理、つまり割り当てとコピーが、あなたのアプローチであなたを殺しています。私はちょうど今あなたの提案(上記編集されたコードを参照)、次の試してみましたが、本当にどんな改善が見られなかった

library(data.table) 
setDT(df) 
alloc.col(df, 200) #allocate sufficient columns 

#assign rolling means in a loop 
for (i in seq_along(ww)) 
    set(df, j = paste0("D", i), value = roll_mean(df[["rawdata"]], 
             ww[i], na.rm=TRUE, fill=NA)) 

dfsumm <- df[, lapply(.SD, max, na.rm = TRUE), by = year] #aggregate 
+1

うわー!私は簡単な10倍のスピードアップを得て、幸せになれませんでした。どうもありがとう! – AF7

-1

作成するパフォーマンスの問題の1つは、cbindを使用してベクトルを動的に拡大することです。事前に予想されるサイズを割り当て、後でdfsumm[x] <- yを使用してサイズを設定することができます。

+0

:ここ

は、参照することによって割り当てdata.tableアプローチ、です。時間はまだ100kサンプルを使用して28sです。 – AF7

関連する問題