[r] Unused arguments in R

In R, is it possible to have a the software ignore the fact that there are unused arguments defined when a module is run?

For example, I have a module multiply(a,b), which returns the product of a and b. I will receive an error if I call the module like so:

multiply(a=20,b=30,c=10)

Returning an error on this just seems a bit unnecessary, since the required inputs a and b have been specified. Is it possible to avoid this bad behaviour?

An easy solution would be just to stop specifying c, but that doesn't answer why R behaves like this. Is there another way to solve this?

This question is related to r

The answer is


Change the definition of multiply to take additional unknown arguments:

multiply <- function(a, b, ...) {
  # Original code
}

One approach (which I can't imagine is good programming practice) is to add the ... which is traditionally used to pass arguments specified in one function to another.

> multiply <- function(a,b) a*b
> multiply(a = 2,b = 4,c = 8)
Error in multiply(a = 2, b = 4, c = 8) : unused argument(s) (c = 8)
> multiply2 <- function(a,b,...) a*b
> multiply2(a = 2,b = 4,c = 8)
[1] 8

You can read more about ... is intended to be used here


I had the same problem as you. I had a long list of arguments, most of which were irrelevant. I didn't want to hard code them in. This is what I came up with

library(magrittr)
do_func_ignore_things <- function(data, what){
    acceptable_args <- data[names(data) %in% (formals(what) %>% names)]
    do.call(what, acceptable_args %>% as.list)
}

do_func_ignore_things(c(n = 3, hello = 12, mean = -10), "rnorm")
# -9.230675 -10.503509 -10.927077

The R.utils package has a function called doCall which is like do.call, but it does not return an error if unused arguments are passed.

multiply <- function(a, b) a * b

# these will fail
multiply(a = 20, b = 30, c = 10)
# Error in multiply(a = 20, b = 30, c = 10) : unused argument (c = 10)
do.call(multiply, list(a = 20, b = 30, c = 10))
# Error in (function (a, b)  : unused argument (c = 10)

# R.utils::doCall will work
R.utils::doCall(multiply, args = list(a = 20, b = 30, c = 10))
# [1] 600
# it also does not require the arguments to be passed as a list
R.utils::doCall(multiply, a = 20, b = 30, c = 10)
# [1] 600

You could use dots: ... in your function definition.

myfun <- function(a, b, ...){
  cat(a,b)
}

myfun(a=4,b=7,hello=3)

# 4 7