I'm interested in using do.call
to pass arguments to two functions with use of one list. The do.call
solution should ignore unused arguments.
my_sum <- function(a, b) {
a + b
}
my_exp <- function(c, d) {
c^d
}
args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]
my_wrapper <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args)
res_two <- do.call(my_exp, fun_args)
res_one + res_two
}
Naturally, the example fails as superfluous arguments are passed to both functions.
my_wrapper_two <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args[1:2]) # Only a, b
res_two <- do.call(my_exp, fun_args[3:4]) # Only c, d
res_one + res_two
}
my_wrapper_two()
# 84
I would like for the subsetting operations [1:2]
and [3:4]
to be performed automatically depending on the function arguments.
One approach I was thinking of would be using names(formals(my_exp))
to create desired list of arguments as in:
my_wrapper_three <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args[names(formals(my_sum))])
res_two <- do.call(my_exp, fun_args[names(formals(my_exp))])
res_one + res_two
}
my_wrapper_three()
This doesn't look elegant and I'm wondering if there is a more intelligent solution?
The solution I cam up with is as follows:
do_call_on_existing <- function(fun, args_list) {
fun_args <- names(formals(fun))
viable_args <- args_list[fun_args]
viable_args <- Filter(Negate(is.null), viable_args)
do.call(fun, viable_args)
}
The Filter
/ Negate
bit prevents function from failing where my_sum
could have extra arguments that would result in arguments list returning null
element. So the code can work:
my_sum <- function(a = 999, b = 999, c = 999) {a + b + c}
my_nms <- list(a = 1, b = 2)
do_call_on_existing(my_sum, my_nms)
Try this (...
allows you to pass any number of arguments into my_sum
but only a
and b
are used as per your definition):
my_sum <- function(a, b, ...) {
a + b
}
my_exp <- function(c, d, ...) {
c^d
}
args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]
my_wrapper <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args)
res_two <- do.call(my_exp, fun_args)
res_one + res_two
}