As @joran has already pointed out, formals()
exposes the default values. However, as I understand the question, what you're really after is the construction of the call expression. To that end, it is useful to combine formals()
with as.call()
to produce the call itself. The following function does just that, by producing a function that produces "argument-completed calls," for a given function name f
:
drop_missing <- function(sig) {
sig[!sapply(sig, identical, quote(expr =))]
}
complete_call <- function(f) {
nm <- as.name(f)
sig <- formals(args(f))
make_call <- function() {
args <- match.call()[-1]
sig[names(args)] <- args
as.call(c(nm, drop_missing(sig)))
}
formals(make_call) <- sig
make_call
}
Example usage:
complete_call("log")(1)
#> log(x = 1, base = exp(1))
complete_call("rnorm")(10)
#> rnorm(n = 10, mean = 0, sd = 1)
complete_call("rnorm")()
#> rnorm(mean = 0, sd = 1)
Remarks:
1) The output is a language object. To execute the call, you need to evaluate it, e.g.,
eval(complete_call("rnorm")(10))
#> [1] -0.89428324 -1.78405483 -1.83972728 ... (output truncated)
2) If you want complete_call()
to accept a function, rather than the name of a function, you could write nm <- as.name(deparse(substitute(f)))
in place of the given assignment. However, that would not work in a nested call, where you would get as.name("f")
for nm
, because of R's rules fo lexical scoping.
3) Without the call to args()
in the assignment of sig
, complete_call()
would only work for closures, since primitive and builtin functions don't have formals.