Das ist wirklich keine einfache Sache zu tun. Wenn Sie die Funktion Gebäude sind, können Sie den Anruf mit match.call
, erfassen, die ohne allzu viel Mühe analysiert werden kann:
f <- function(x, y = 1, ...){
cl <- match.call()
as.list(cl[-1])
}
str(f(1))
#> List of 1
#> $ x: num 1
str(f(1, 'foo'))
#> List of 2
#> $ x: num 1
#> $ y: chr "foo"
str(f(1, 'foo', list(3), fun = sum))
#> List of 4
#> $ x : num 1
#> $ y : chr "foo"
#> $ : language list(3)
#> $ fun: symbol sum
Hinweis match.call
erfasst nur den Anruf, und nicht fügen in Standardparametern (Im ersten Beispiel gibt es keine y
. Diese können mit formals(f)
zugegriffen werden, da f
nicht primitiv ist, so vollständig Argumente könnten über
user_args <- f(1)
fun_args <- formals(f)
fun_args[names(user_args)] <- user_args
str(fun_args)
#> List of 3
#> $ x : num 1
#> $ y : num 1
#> $ ...: symbol
Dieser Ansatz funktioniert nicht gut für erledigte Punkte erzeugt werden, aber wenn sie dann match.call
selbst abgeschlossen sollte ausreichen . Um die an eine existierende Funktion übergebenen Parameter zu extrahieren, könnten Sie einen Wrapper mit match.call
schreiben, aber es ist kaum praktikabel, jede Funktion zu rekonstruieren, und der Aufruf, den Sie erfassen, wird sowieso lustig aussehen, wenn Sie bestehende Funktionen nicht überschreiben. Solange die Funktion nicht primitiv, Sie quote
verwenden könnte den formals
Ansatz zu ermöglichen, aber:
cl <- quote(rnorm(5, 2))
user_args <- as.list(cl[-1]) # subset call to only args
fun_args <- formals(as.character(cl[1])) # subset call to only function
names(user_args) <- names(fun_args)[seq(length(user_args))]
fun_args[names(user_args)] <- user_args
str(fun_args)
#> List of 3
#> $ n : num 5
#> $ mean: num 2
#> $ sd : num 1
Ein anderer Ansatz ist rlang zu verwenden, deren Funktionen handhaben Primitiven gut (fn_fmls(sum)
) können Teile extrahieren der Anruf einfach und zuverlässig (lang_fn
, lang_args
), unbenannte Parameter genau benennen (lang_standardize
) und mehr. Zusammen mit purrr Der neue list_modify
(dev-Version), es wird alles ziemlich schmerzlos:
library(rlang)
fun_call <- quo(rnorm(5))
fun_call
#> <quosure: frame>
#> ~rnorm(5)
default_args <- fn_fmls(lang_fn(fun_call))
str(default_args)
#> Dotted pair list of 3
#> $ n : symbol
#> $ mean: num 0
#> $ sd : num 1
user_args <- lang_args(lang_standardise(fun_call))
str(user_args)
#> List of 1
#> $ n: num 5
calling_args <- purrr::list_modify(default_args, user_args)
str(calling_args)
#> Dotted pair list of 3
#> $ n : num 5
#> $ mean: num 0
#> $ sd : num 1
AFAIK, würden Sie den Anruf sparen müssen und analysieren sie, welche Art von Schmerz ist. – alistaire
wie @alistaire sagte, Sie können auf den Aufruf innerhalb einer Funktion mit 'Sys.call()' zugreifen ... Aber was ist Ihr Ziel? – Val