2014-02-23 110 views
1

我目前正在循環一個大型數據集,而我發現的是循環索引越高,循環越慢。開始時速度非常快,但最後速度非常慢。這是什麼原因?有什麼方法可以繞過它嗎?for循環的速度正在遞減

備註: 1)我不能使用plyr,因爲計算是遞歸的。 2)輸出向量的長度是事先不知道的。

我的代碼如下rougly這樣的:

for (i in 1:20000){ 

    if(i == 1){ 

     temp <- "some function"(input data[i]) 
     output <- temp 

    } else { 

     temp <- "some function"(input data[i], temp) 
     out <- rbind(out, temp) 
    }  
    } 
+0

這是什麼功能呢? – marbel

+4

預分配而不是使用'rbind'。如果你不知道'out'的長度,那麼在循環終止時將其過度分配並修剪它。或者,如果''某個函數''返回一個向量,使'out'成爲一個列表並且'unlist'它。 –

+1

@JoshuaUlrich釘了它。查看http://stackoverflow.com/questions/2908822/speed-up-the-loop-operation-in-r/8474941#8474941獲取更多建議,但這幾乎肯定是這裏的罪魁禍首,因爲進步緩慢(作爲正在傳遞的數據變得越來越大,內存變得越來越分散,並且你開始盯住磁盤)。 –

回答

4

的問題是,你在每次迭代中,這將需要越來越大量複製爲out的尺寸增加的增長目標out(如您循環索引增加)。

在這種情況下,您知道循環需要20000個元素的向量,所以最初創建一個並在循環中填充該對象。這樣做也將消除if() ... else()的需要,這也會減慢你的循環,並且隨着循環的大小增加而變得可觀。

例如,你可以這樣做:

out <- numeric(20000) 
out[1] <- foo(data[1]) 
for (i in 2:length(out)) { 
    out[i] <- foo(data[i], out[i-1]) 
} 

什麼out需要在創建這將取決於什麼foo()回報是。相應地調整out的創建。