2015-02-24 60 views
1

我想並行我有一個for循環。有問題的循環內有一個嵌套循環,我想並行化。答案必定非常類似於:nested foreach loops in R to update common array,但我似乎無法使其起作用。我已經嘗試了所有我能想到的選項,包括將內部循環轉換爲自己的函數並對其進行並行化處理,但我一直收到空列表。R在內部循環返回矩陣的嵌套的foreach循環

第一,非的foreach示例工作:

theFrame <- data.frame(col1=rnorm(100), col2=rnorm(100)) 

theVector <- 2:30 

regFor <- function(dataFrame, aVector, iterations) 
{ 
    #set up a blank results matrix to save into. 
    results <- matrix(nrow=iterations, ncol=length(aVector)) 

    for(i in 1:iterations) 
    { 
     #set up a blank road map to fill with 1s according to desired parameters 
     roadMap <- matrix(ncol=dim(dataFrame)[1], nrow=length(aVector), 0) 
     row.names(roadMap) <- aVector 
     colnames(roadMap) <- 1:dim(dataFrame)[1] 

     for(j in 1:length(aVector)) 
     { 
      #sample some of the 0s and convert to 1s according to desired number of sample 
      roadMap[j,][sample(colnames(roadMap),aVector[j])] <- 1 
     } 

     temp <- apply(roadMap, 1, sum) 

     results[i,] <- temp 
    } 

    results <- as.data.frame(results) 
    names(results) <- aVector 

    results 
} 

test <- regFor(theFrame, theVector, 2) 

但是這和我的其他類似的嘗試不起作用。

trying <- function(dataFrame, aVector, iterations, cores) 
{ 
    registerDoMC(cores) 

    #set up a blank results list to save into. i doubt i need to do this 
    results <- list() 

    foreach(i = 1:iterations, .combine="rbind") %dopar% 
    { 
     #set up a blank road map to fill with 1s according to desired parameters 
     roadMap <- matrix(ncol=dim(dataFrame)[1], nrow=length(aVector), 0) 
     row.names(roadMap) <- aVector 
     colnames(roadMap) <- 1:dim(dataFrame)[1] 

     foreach(j = 1:length(aVector)) %do% 
     { 
      #sample some of the 0s and convert to 1s according to desired number of sample 
      roadMap[j,][sample(colnames(roadMap),aVector[j])] <- 1 
     } 

     results[[i]] <- apply(roadMap, 1, sum) 
    } 
    results 
} 

test2 <- trying(theFrame, theVector, 2, 2) 

我認爲我不得不在內部循環中使用foreach,不管怎樣,對吧?

回答

4

使用的foreach,你從來沒有「建立一個空白的結果列表保存到」,你嫌。相反,您將評估foreach循環體的結果組合起來,並返回組合結果。在這種情況下,我們希望外部foreach循環將矢量(由內部foreach循環計算)按行逐行組合到矩陣中。該矩陣被分配給變量results,然後轉換爲數據幀。

這是我在您的轉換例如第一次嘗試:

library(doMC) 

foreachVersion <- function(dataFrame, aVector, iterations, cores) { 
    registerDoMC(cores) # unusual, but reasonable with doMC 
    rows <- nrow(dataFrame) 
    cols <- length(aVector) 
    results <- 
    foreach(i=1:iterations, .combine='rbind') %dopar% { 
     # The value of the inner foreach loop is returned as 
     # the value of the body of the outer foreach loop 
     foreach(aElem=aVector, .combine='c') %do% { 
     roadMapRow <- double(length=rows) 
     roadMapRow[sample(rows,aElem)] <- 1 
     sum(roadMapRow) 
     }  
    } 
    results <- as.data.frame(results) 
    names(results) <- aVector 
    results 
} 

內環不需要被實現爲foreach循環。您也可以使用sapply,但我會試着找出是否有更快的方法。但對於這個答案,我想演示一個foreach方法。我使用的唯一真正的優化是通過在內部foreach循環內執行sum來擺脫對apply的調用。

+0

謝謝!這很好。如果不清楚,我的實際代碼在兩個循環內部都會做更復雜的事情,所以使用sapply等可能會非常棘手。我的原始配方有兩個主要問題。首先是建立一個空白列表並試圖保存結果(順便說一下,在其他情況下,我已經成功完成了foreach),第二個並沒有理解.combine正在做什麼的含義。這很酷,並且可以生成結果,而無需使用像Reduce()這樣的事情,這是我在過去用foreach完成的。謝謝! – forlooper 2015-02-25 21:00:26

+0

@forlooper在foreach循環中可能會產生副作用,但取決於您使用的後端,它的工作方式會有所不同,因此強烈建議您不要這樣做。我最初試圖防止在foreach中出現副作用的可能性,但我最終放棄了嘗試。 – 2015-02-25 22:02:01

+0

謝謝史蒂夫。我想我應該重新編程一些東西! – forlooper 2015-02-27 19:05:48

3

你需要把結果的foreach的一個變量:

results<- foreach(... 
+0

這是問題的關鍵。謝謝!史蒂夫韋斯頓的上面答案是對這個問題的完整答案。 – forlooper 2015-02-25 20:53:35

+0

然後標記他的答案爲你的答案,並請投票。 – cmbarbu 2015-02-25 20:59:49

+0

對不起,我點擊了第一個錯誤的符號。我現在修好了。再次感謝。 – forlooper 2015-02-25 21:47:00