2014-10-27 30 views
2

我有一個很大的仿真,我想在多個內核上運行。 爲此,我正在使用foreach()包。使用foreach時使用循環計數器()

我迭代循環1000次,並在循環中,我使用從環路的位置矢量計數器,用於exampe:

reps<-1000 
for (i in reps){ 
a[i]<-mean(rnorm(100)) 
} 

如果我做同樣的事情用foreach:

library(foreach) 
cl<-makeCluster(8) 
registerDoParallel(cl) 
ls<-foreach(icount(reps)) %dopar% { 
rnorm(100) 
} 

我不能再像當初的循環一樣使用當前計數器了。 有沒有辦法使用它?

我也很擅長有一個計數器,就像每次迭代通過我做我i = i + 1從i = 0開始。

+0

'foreach(i = seq_len(reps))'然後你可以在循環中引用'i'。但是,請記住,您不會使用'foreach'循環來分配'a'。相反,您會使用'.combine'參數並在您顯示時分配給'ls'。 – Roland 2014-10-27 12:25:15

+0

但如果我在foreach序列中有另一個for循環呢?我可以在該循環中分配事物嗎? – user1723765 2014-10-27 12:29:23

+1

當然可以。但是,您需要了解「foreach」循環的工作方式,即它們具有返回值。閱讀'foreach'小插曲。 – Roland 2014-10-27 12:48:14

回答

2

羅蘭建議,你可以寫「的foreach」版本:

reps <- 1000 
ls <- foreach(i=icount(reps), .combine='c') %dopar% { 
    mean(rnorm(100)) 
} 

變量i沒有使用,但如果你想在將來它的可用。

使用「爲」內部「的foreach」循環迴路可用於獲取更好的性能是非常有用的,因爲它可以減少迭代次數,並允許工人做更多的工作並行:

reps <- 1000 
ls <- foreach(n=rep(reps/8, 8), .combine='c') %dopar% { 
    a <- numeric(n) 
    for (i in seq_len(n)) { 
    a[i] <- mean(rnorm(100)) 
    } 
    a 
} 

在「foreach」循環內部做a的作業很好,因爲它是一個局部變量。當「for」循環結束時,返回a,最後所有的a向量都與主函數的「c」函數組合在一起。

請注意,此示例在「foreach」循環內使用原始「for」循環。這樣做效率更高,因爲主人不需要做太多的工作來發送任務並收集和合並結果。

事實上,我會用「sapply」,而不是「for」循環和「IDIV」(從「迭代」包),而不是「代表」:

reps <- 1000 
ls <- foreach(n=idiv(reps, chunks=8), .combine='c') %dopar% { 
    sapply(seq_len(n), function(i) mean(rnorm(100))) 
} 

隨着「IDIV」我不如果迭代次數不能被工人數量整除,就不必擔心會發生什麼。