2017-05-16 68 views
1

我遇到問題在函數內部運行dopar,當註冊doRNG時,我需要訪問在函數內部創建的變量。R doRNG無法找到變量

我的總體目標是使用doRNG來確保我的並行進程得到不同的隨機數據流,所以如果有更好的方法來做到這一點,這也將解決我的問題。

我會繼續關注爲什麼使用doRNG失敗,因爲我試圖瞭解環境如何導出到並行進程。

這裏的代碼看起來有點人爲設計,但是這是總結一個更大更復雜的代碼。

library(doParallel) 
library(foreach) 

cl <- makePSOCKcluster(2) 
registerDoParallel(cl) 

#if I comment out these two lines, code runs fine 
library(doRNG) 
registerDoRNG() 

gVar <- 'gVar' 

cols <- matrix(1:10,nrow=2) 
res <- apply(cols,2, 
    function(col) { 
    lclVar <- sum(col) 

    res <- foreach(i=icount(2), 
    .export=c('gVar'), #'lclVar' 
    .combine='c') %dopar% { #change to %do% also works 
     return(sprintf('%s %s %s',gVar,lclVar,i)) 
    } 

    return(res) 
}) 

print(res) 
stopCluster(cl) 

注意,如果我註釋掉doRNG線,代碼運行正常。也從%dopar%更改爲%do%(並保留doRNG行未註釋)的作品。

我得到如下:

Error in { : task 1 failed - "object 'lclVar' not found" 
+0

使用'%dorng%'而不是'%dopar%'不會導致錯誤。試過了嗎? –

+0

@J_F實際上解決了我的問題。因此,當dopar被dorng包裹時,環境不會以相同的方式傳遞?無論如何,這是一個快速解決這個問題,謝謝! –

回答

0

我總在這裏的目標是使用doRNG以確保我的並行 過程獲得的隨機數的不同的數據流,所以如果有一個 更好的方法做這也將解決我的問題。

如果你能「改寫」你的問題,因爲一個lapply()呼叫,然後

y <- future_lapply(x, FUN, ..., future.seed = TRUE) 
future包(我是作者)將確保每個 FUN(x[[i]], ...)調用與適當的做的

( L'Ecuyer-CMRG)RNG流。未來軟件包還會自動處理全局變量(例如,gVarlclVar),並將其正確導出到每個工作人員。

您可以控制如何與plan()函數並行化,例如,

cl <- makePSOCKcluster(2) 
plan(cluster, workers = cl) 

這相當於:

plan(multiprocess, workers = 2L) 

這適用於所有操作系統相同。

+0

感謝這個偉大的答案。上面J_F的評論是最快的解決方案,所以這是最好的答案。但是,您的答案提供了一個很好的替代方法。 –