Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

match.call with default arguments

Tags:

r

As part of a function, I want to output a list of all the arguments and their values, including the default values. For example, a function with these arguments:

foo <- function(x=NULL,y=NULL,z=2) {
  #formals()
  #as.list(match.call())[-1]
  #some other function?....
}

To give output as such:

> foo(x=4)

$x
[1] 4

$y
NULL

$z
[1] 2

formals does not update to give the values argument values when the function is called. match.call does, but does not provide the defaults of the arguments. Is there another function out there that will provide the output as I want?

like image 823
guyabel Avatar asked Jan 18 '13 10:01

guyabel


3 Answers

Hopefully, this doesn't lead to dragons.

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
like image 173
Roland Avatar answered Nov 02 '22 12:11

Roland


you can use a mix of the 2 , match.call and 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
}

For example :

  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
like image 40
agstudy Avatar answered Nov 02 '22 10:11

agstudy


Here is an attempt to wrap this logic in a reusable function to drop in instead of 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)
}

It looks like it works:

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"))
like image 37
Neal Fultz Avatar answered Nov 02 '22 12:11

Neal Fultz