Reputation: 1671
I have a main function mainFunction
that calls sub-functions :
subFunctionA
subFunctionB
subFunctionC
Ideally I would like not to set manually all the "sub" parameters names in my mainFunction
signature but use the ...
instead. However I get the unused argument
error :
# Initial try
subFunctionA <- function(a = 1, b = 2) {a+b}
subFunctionB <- function(aa = 1, bb = 2) {aa+bb}
subFunctionC <- function(a = 1, bb = 2) {a+bb}
mainFunction <- function(...) {
x1 <- subFunctionA(...)
x2 <- subFunctionB(...)
x3 <- subFunctionC(...)
x1+x2+x3
}
mainFunction(a = 2, b = 2, aa = 3, bb = 4)
# Return error "Error in subFunctionA(...) : arguments inutilisés (aa = 3, bb = 4)"
Below the workaround I use, but I'm not sure I make good practice of additional parameters :
# Workaround
parameters_filters <- function(fun, ...) {
p <- list(...)
p[which(names(p) %in% names(as.list(args(fun))))]
}
mainFunction_workaround <- function(...) {
x1 <- do.call(subFunctionA, parameters_filters(subFunctionA, ...))
x2 <- do.call(subFunctionB, parameters_filters(subFunctionB, ...))
x3 <- do.call(subFunctionC, parameters_filters(subFunctionC, ...))
x1+x2+x3
}
mainFunction_workaround(a = 2, b = 2, aa = 3, bb = 4)
# Returns 17
Is there a "cleaner" way to do so ?
Upvotes: 0
Views: 67
Reputation: 132706
You were almost there with the initial try:
subFunctionA <- function(a = 1, b = 2, ...) {a+b}
subFunctionB <- function(aa = 1, bb = 2, ...) {aa+bb}
subFunctionC <- function(a = 1, bb = 2, ...) {a+bb}
mainFunction <- function(...) {
x1 <- subFunctionA(...)
x2 <- subFunctionB(...)
x3 <- subFunctionC(...)
x1+x2+x3
}
mainFunction(a = 2, b = 2, aa = 3, bb = 4)
#[1] 17
This will cause issues if the user uses positional arguments:
mainFunction(2, 2, 3, 4)
#[1] 12
Thus, I would avoid ...
in the main function (unless you actually have optional parameters):
mainFunction <- function(a, b, aa, bb) {
args <- list(a = a, b = b, aa = aa, bb = bb)
x1 <- do.call(subFunctionA, args)
x2 <- do.call(subFunctionB, args)
x3 <- do.call(subFunctionC, args)
x1+x2+x3
}
mainFunction(2, 2, 3, 4)
#[1] 17
And of course, not using ...
here at all would be the safest option.
Upvotes: 1