32

For an arbitrary function

f <- function(x, y = 3){
  z <- x + y
  z^2
}

I want to be able take the argument names of f

> argument_names(f)
[1] "x" "y"

Is this possible?

landau
  • 5,636
  • 1
  • 22
  • 50

1 Answers1

38

formalArgs and formals are two functions that would be useful in this case. If you just want the parameter names then formalArgs will be more useful as it just gives the names and ignores any defaults. formals gives a list as the output and provides the parameter name as the name of the element in the list and the default as the value of the element.

f <- function(x, y = 3){
  z <- x + y
  z^2
}

> formalArgs(f)
[1] "x" "y"
> formals(f)
$x


$y
[1] 3

My first inclination was to just suggest formals and if you just wanted the names of the parameters you could use names like names(formals(f)). The formalArgs function just is a wrapper that does that for you so either way works.

Edit: Note that technically primitive functions don't have "formals" so this method will return NULL if used on primitives. A way around that is to first wrap the function in args before passing to formalArgs. This works regardless of it the function is primitive or not.

> # formalArgs will work for non-primitives but not primitives
> formalArgs(f)
[1] "x" "y"
> formalArgs(sum)
NULL
> # But wrapping the function in args first will work in either case
> formalArgs(args(f))
[1] "x" "y"
> formalArgs(args(sum))
[1] "..."   "na.rm"
Dason
  • 60,663
  • 9
  • 131
  • 148
  • @MichaelChirico Hmmm. Looks like anything that is just a wrapper to a .primitive call has the same issue. – Dason Jun 01 '17 at 14:13
  • 1
    yea I was trying to find all the one-argument functions in base and ran into this issue -- all the good ones are just primitive wrappers – MichaelChirico Jun 01 '17 at 14:15
  • @MichaelChirico I think I found a workaround. Technically `formalArgs` providing NULL for primitives isn't a bug. The help page for `formals` says "Only closures have formals, not primitive functions." which explains why this happens. `args` itself returns a closure which is why the 'trick' gives us what we want. – Dason Jun 01 '17 at 14:44
  • Note that `formals()` also works for `f(x=1, y = a)` (`a` being an object like `a <- 3`). Then (for my use case) you can even do: `formals(f)$y == 'a'`. – Paul Lemmens Nov 07 '19 at 12:18