2011-10-03 182 views
3

我知道我應該避免for循環,但我不完全確定如何執行我想要對apply函數執行的操作。R:與apply()vs for循環混淆

這是我想要做的略微簡化的模型。所以,基本上我有一個預測變量的大矩陣,並且我想要在索引預測變量的每一邊使用一個包含5個預測變量的窗口進行迴歸(在for循環的情況下)。隨着一個循環,我只能這樣說:

results<-NULL 
window<-5 
for(i in 1:ncol(g)) 
{ 
    first<-i-window #Set window boundaries 
    if(first<1){ 
     1->first 
    } 
    last<-i+window-1 
    if(last>ncol(g)){ 
     ncol(g)->last 
    } 
    predictors<-g[,first:last] 

    #Do regression stuff and return some result 
    results[i]<-regression stuff 
} 

是否有與應用功能做到這一點的好辦法?我的問題是,應用向量將推入功能真的無所謂。重要的是索引。

+0

AFAIK的意思是'apply'家庭只是語法糖,它實際上並沒有加快你的碼。 –

+1

薩沙......不完全是真的..值得注意的是,拉普利有時可以有驚人的加速。此外,語法糖可以讓你分解複雜的循環和函數,以便適用於需要它的組件。 – John

+0

對於那些感興趣的人,[這](http://stackoverflow.com/q/2275896/324364)SO問題是這個問題的一個很好的參考。 – joran

回答

4

在這種情況下,使用apply函數進行迴歸大多是偏好問題;它可以爲你處理一些簿記(因此可能防止錯誤),但不會加速代碼。

我會建議使用矢量化功能,但計算您的first的和last的,不過,也許是這樣的:

window <- 5 
ng <- 15 #or ncol(g) 
xy <- data.frame(first = pmax((1:ng) - window, 1), 
        last = pmin((1:ng) + window, ng)) 

或者是更聰明與

xy <- data.frame(first= c(rep(1, window), 1:(ng-window)), 
       last = c((window+1):ng, rep(ng, window))) 

,那麼你可以

results <- list() 
for(i in 1:nrow(xy)) { 
    results[[i]] <- xy$first[i] : xy$last[i] 
} 
results 
:在 for循環這樣的使用

lapply這樣的:

results <- lapply(1:nrow(xy), function(i) { 
    xy$first[i] : xy$last[i] 
}) 

凡在這兩種情況下我剛剛回到第一和列表之間的序列;你會用你的實際迴歸代碼替代。

8

這個問題涉及的是在做一些點「將R地獄」 http://www.burns-stat.com/pages/Tutor/R_inferno.pdf

有一些循環,你應該避免,但不是所有的人。而使用apply函數更隱藏循環而不是避免它。這個例子似乎是留在'for'循環中的好選擇。

越來越多的對象通常是不好的形式 - 在某些情況下它可能效率極低。如果你要有一個全面的規則,那麼「不增長對象」比「避免循環」更好。

您可以通過創建一個最終長度的列表:

result <- vector("list", ncol(g)) 
for(i in 1:ncol(g)) { 
    # stuff 
    result[[i]] <- #results 
} 

在某些情況下,你可能會認爲該命令:

window<-5 

手段給我一個合理的載體,指出「窗口的哪些值'小於-5。

空間是很好用,主要是不要混淆人類,但要獲得正上方,不要混淆R.