Search code examples
rintrospection

Is there a convenient, maintainable way to get the actual arguments list from within function?


Suppose that I'm writing a function foo with signature

foo <- function (bar, baz, frobozz, quux = TRUE, frotz = 42) {
           # etc.
       }

If, within this function's body, I wanted to get a named list of the actual arguments that the function received at run time, I could define

actual_args <- list(bar = bar, baz = baz, frobozz = frobozz, quux = quux,
                    frotz = frotz)

...but this assignment is difficult to maintain, since it needs to be modified every time an argument gets added, removed, or renamed. (Not to mention that it is also tedious to write.)

Is there a way to initialize actual_args that would remain invariant with respect to future changes in the function's signature?


Solution

  • You can use ls() in a function to get a list of all the variables defined. If you call that right after the function starts, you'll get a list of all the parameters. You can then use mget() to put those values in a list. For example

    foo<-function(a,b,c) {
        mget(ls())
    }
    

    This will work with your do.call/mapply scenario

    df <- data.frame(
        a=1:3,
        b=letters[1:3],
        c = runif(3))
    
    do.call("mapply", c(foo, df))
    #   [,1]      [,2]      [,3]     
    # a 1         2         3        
    # b factor,1  factor,1  factor,1 
    # c 0.7845643 0.0297852 0.3611791