设置'foreach'函数的正式参数

时间:2013-06-04 01:26:54

标签: r parallel-processing parallel-foreach

我正在尝试设置foreach函数的正式参数。我将使用.combine参数给出一个简单的例子。

我写了一个改变函数形式的通用包装器(下面的代码)

bind<-function(FUN,args.new) {
    args.all<-formals(FUN)
    args.all[names(args.all) %in% names(args.new)]<-args.new
    FUN.tmp<-FUN
    formals(FUN.tmp)<-args.all
    FUN.tmp
}

所以,我改变了foreach函数的形式

library(foreach)    
foreach.bind<-bind(foreach,list('.combine'='rbind'))

当我检查我得到的新形式时(如预期的那样):

> formals(foreach.bind)
$...


$.combine
[1] "rbind"

$.init


$.final
NULL

$.inorder
[1] TRUE

$.multicombine
[1] FALSE

$.maxcombine
if (.multicombine) 100 else 2

$.errorhandling
c("stop", "remove", "pass")

$.packages
NULL

$.export
NULL

$.noexport
NULL

$.verbose
[1] FALSE

> 

但是当我调用foreach.bind时,一切都像.combine变量一样没有设置!例如,声明:

a<-function(x) c(1,x)

并致电:

> foreach.bind(i=list(1,2,3)) %do% a(i)
[[1]]
[1] 1 1

[[2]]
[1] 1 2

[[3]]
[1] 1 3

> 

正如我所说,像.combine参数没有正式设置。

另一方面,如果我调用原始函数,它就会:

> foreach(i=list(1,2,3),.combine='rbind') %do% a(i)
         [,1] [,2]
result.1    1    1
result.2    1    2
result.3    1    3
> 

无论如何,有人可以解释一下这种情况会发生什么吗?或者为我提供其他方法来“绑定”foreach函数?

1 个答案:

答案 0 :(得分:2)

.combine参数未在foreach函数中给出默认值。而是foreach检查是否缺少.combine参数。您的代码为.combine提供了默认值,但是如果您没有为其指定值,它仍然会丢失,因此默认的组合行为不会更改。

一种解决方案是创建一个与foreach具有相同形式参数的包装函数,然后通过操作然后评估foreach返回的调用对象来调用match.call: / p>

library(foreach)
foreach.bind <- function() {
    cobj <- match.call()
    cobj[[1]] <- as.name('foreach')
    nms <- names(cobj)
    if (! '.combine' %in%  nms) {
      cobj[[length(cobj) + 1]] <- 'rbind'
      names(cobj) <- c(nms, '.combine')
    }
    eval(cobj)
}
formals(foreach.bind) <- formals(foreach)

这会修改默认的组合行为,同时仍允许您指定自己的组合功能:

> foreach.bind(i=1:3) %do% c(1,i)
         [,1] [,2]
result.1    1    1
result.2    1    2
result.3    1    3
> foreach.bind(i=1:3, .combine='c') %do% c(1,i)
[1] 1 1 1 2 1 3