2013-07-01 85 views
14

我正在使用.combine = rbindlist的foreach。這似乎不起作用,但它工作正常,如果我使用.combine = rbind。R。foreach with .combine = rbindlist

只是爲了說明使用一個簡單的例子 -

> t2 <- data.table(col1=c(1,2,3)) 
> foreach (i=1:3, .combine=rbind) %dopar% unique(t2) 
    col1 
1: 1 
2: 2 
3: 3 
4: 1 
5: 2 
6: 3 
7: 1 
8: 2 
9: 3 

# But using rbindlist gives an error 

> foreach (i=1:3, .combine=rbindlist) %dopar% unique(t2) 
error calling combine function: 
<simpleError in fun(result.1, result.2): unused argument(s) (result.2)> 
NULL 

任何人都已經能夠使這項工作?

在此先感謝。

+0

我知道我們應該在列表對象上調用rbindlist - rbindlist(list(dt1,dt2))...但不知道如何使用foreach .combine函數執行它。 – xbsd

回答

16

它基本上你說的話 - rbindlist假定list的說法,而你得到的錯誤是一樣的,因爲這一個:

result.1 = data.table(blah = 23) 
result.2 = data.table(blah = 34) 

rbindlist(result.1, result.2) 
#Error in rbindlist(result.1, result.2) : unused argument (result.2) 

如果你想利用rbindlist的方式做到這一點會是這樣的:

rbindlist(foreach (i = 1:3) %dopar% unique(t2)) 

或該:

foreach (i=1:3, .combine=function(x,y)rbindlist(list(x,y))) %dopar% unique(t2) 
+0

謝謝!工作得很好。 – xbsd

+0

由於在這種情況下獲得了嵌套列表,因此如果有超過100個結果,則使用'.combine = list'的第一個解決方案會失敗。只需要省略'.combine'和'.multicombine'參數,並且它可以正常工作,因爲默認行爲是將結果返回到列表中。我最喜歡你的第二個解決方案,它可以處理任何數量的結果。 –

+0

@SteveWeston查看.maxcombine註釋和?foreach – eddi

11

這裏有一個辦法都使用rbindlist爲您.combine功能並有.multicombine=TRUE

foreach (i=1:3, 
     .combine=function(...) rbindlist(list(...)), 
     .multicombine=TRUE) %dopar% unique(t2) 

如果你有單獨的結果彙總像樣的數目,這可能是相當多的不僅僅是合併兩個以更快-a時間。

對於單一的foreach語句,這將產生相同的結果讓foreach默認.combine列出和包裝用rbindlist,如EDDI的首選解決方案。我不確定哪個更快,但我希望他們接近。

對於小型,單foreach工作我喜歡rbindlist包裹,但%:%鏈接幾個foreach的在一起時我覺得上面的方法(可能在第一foreach)看起來比較清爽。

+2

這種組合函數適用於並行後端,可以即時調用組合函數。這使得主人可以與工人並行地進行後處理。當組合功能執行縮減時更加有用。 –

+2

您也可以直接使用'rbindlist'作爲具有默認組合函數的「.final」函數,因爲它會生成一個列表。這是一個非常乾淨的解決方案,但我會使用你的組合功能。 –

+1

啊我不知道'.final'!我有幾個地方看起來更乾淨。 至於你的第一條評論,這正是我一直使用'doMPI'包的方式。如果你有成千上萬的個人工作,那麼在父母做任何事情之前,不要等待所有的孩子完成。 – ClaytonJY