6

式を入力として受け取り、その式が本体としてバインドされた関数を返すプログラムを作成しようとしています。

caller <- function (expr, params) {

    Function <- function (params, body, env = parent.frame()) {
        # returns a function

    }

    Function(params, body = expr)
}

func <- caller (a + b, c('a', 'b'))

func(1, 2)
[1] 3

次のようなものを使用して、パラメーターを非常に簡単にバインドできます

params <- c('a', 'b')
f <- function() {} 
formals(f) <- structure(
    replicate(length(params), NULL),
    names = params
)

式を本体として動的に追加する方法を考え出すのに苦労しています。私はsubstitute()を使用して、pryrライブラリからmake_functionを適応させようとしましたが、うまく動作しません。私の最善の試みは

    body(f, parent.frame()) <- as.list( match.call() )[-1]$body

これも代用で動作させることができませんでした。最上位のプログラムが期待どおりに動作するようにボディをバインドする方法について何か考えはありますか?

SOで同様の質問を見たことがありますが、解決策はこの問題を満足していないようです。

4

3 に答える 3

0

関数の引数を指定する興味深い代替方法は、関数と同じメカニズムを使用することです。alistこれは、一般に と組み合わせて使用​​されformalsます。baseこれは、パッケージで定義されている方法です。

alist <- function (...) as.list(sys.call())[-1L]

これは、次のもので動作するように簡単に調整できますcaller

caller <- function(...) {
  f <- function() NULL
  formals(f) <- as.list(sys.call())[-(1:2)]
  body(f, envir=parent.frame()) <- substitute(list(...))[[2]]
  f
}

最初の引数は引き続き関数本体を指定し、残りの引数は とまったく同じように機能しalistます。

> func <- caller(a+b, a=, b=10)
> func(1)
[1] 11
> func <- caller(a+b, a=, b=a)
> func(10)
[1] 20

を使用する関数を作成することもできます...:

> func <- caller(c(...), ...=)
> func("a", "b", "c")
[1] "a" "b" "c"
于 2013-05-19T20:11:12.070 に答える