0

我正在尝试设置 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 函数的其他方法?

4

1 回答 1

2

.combine参数在函数中没有被赋予默认值foreach。相反,foreach检查.combine参数是否丢失。您的代码为 提供了一个默认值.combine,但如果您没有为其指定一个值,它仍然会丢失,因此默认的组合行为不会改变。

一种解决方案是创建一个包装函数,该函数具有相同的形式参数foreach,然后foreach通过操作并评估由以下方法返回的调用对象来调用match.call

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
于 2013-06-04T12:07:02.573 回答