我正在尝试设置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函数?
答案 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