Подтвердить что ты не робот

Match.call с аргументами по умолчанию

Как часть функции, я хочу вывести список всех аргументов и их значений, включая значения по умолчанию. Например, функция с этими аргументами:

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 делает, но не предоставляет значения аргументов по умолчанию. Есть ли еще одна функция, которая будет обеспечивать вывод, как я хочу?

4b9b3361

Ответ 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

Ответ 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

Ответ 3

 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

Ответ 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"))