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が、その値を指定しない場合は、まだ欠落しているため、デフォルトの結合動作は変わりません。

1 つの解決策は、 と同じ仮引数を持つラッパー関数を作成し、によって返された呼び出しオブジェクトを操作してから評価することによって呼び出すことforeachです。foreachmatch.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 に答える