Ответ 1
Надеюсь, это не приведет к драконам.
foo <- function(x=NULL,y=NULL,z=2) {
mget(names(formals()),sys.frame(sys.nframe()))
}
foo(x=4)
$x
[1] 4
$y
NULL
$z
[1] 2
print(foo(x=4))
$x
[1] 4
$y
NULL
$z
[1] 2
Как часть функции, я хочу вывести список всех аргументов и их значений, включая значения по умолчанию. Например, функция с этими аргументами:
foo <- function(x=NULL,y=NULL,z=2) {
#formals()
#as.list(match.call())[-1]
#some other function?....
}
Чтобы дать результат как таковой:
> foo(x=4)
$x
[1] 4
$y
NULL
$z
[1] 2
formals
не обновляется, чтобы давать значения значений значений при вызове функции. match.call
делает, но не предоставляет значения аргументов по умолчанию. Есть ли еще одна функция, которая будет обеспечивать вывод, как я хочу?
Надеюсь, это не приведет к драконам.
foo <- function(x=NULL,y=NULL,z=2) {
mget(names(formals()),sys.frame(sys.nframe()))
}
foo(x=4)
$x
[1] 4
$y
NULL
$z
[1] 2
print(foo(x=4))
$x
[1] 4
$y
NULL
$z
[1] 2
вы можете использовать сочетание двух, match.call
и formals
foo <- function(x=NULL,y=NULL,z=2)
{
ll <- as.list(match.call())[-1] ##
myfor <- formals(foo) ## formals with default arguments
for ( v in names(myfor)){
if (!(v %in% names(ll)))
ll <- append(ll,myfor[v]) ## if arg is missing I add it
}
ll
}
Например:
foo(y=2)
$y
[1] 2
$x
NULL
$z
[1] 2
> foo(y=2,x=1)
$x
[1] 1
$y
[1] 2
$z
[1] 2
foo <- function(x=NULL,y=NULL,z=2) {
X <- list(x,y,z); names(X) <- names(formals()); X
}
z <- foo(4)
z
#------
$x
[1] 4
$y
NULL
$z
[1] 4
Вот попытка обернуть эту логику в функцию многократного использования вместо match.call
:
match.call.defaults <- function(...) {
call <- evalq(match.call(expand.dots = FALSE), parent.frame(1))
formals <- evalq(formals(), parent.frame(1))
for(i in setdiff(names(formals), names(call)))
call[i] <- list( formals[[i]] )
match.call(sys.function(sys.parent()), call)
}
Похоже, что он работает:
foo <- function(x=NULL,y=NULL,z=2,...) {
match.call.defaults()
}
> foo(nugan='hand', x=4)
foo(x = 4, y = NULL, z = 2, ... = pairlist(nugan = "hand"))