2013-07-01 63 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