'Unused arguments 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?

r


Solution 1:[1]

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

Solution 2:[2]

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

Solution 3:[3]

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

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

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

# 4 7

Solution 4:[4]

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

Solution 5:[5]

R has a function prod() which does multiplication really well. The example the asker gave works fine with the prod() function without returning an error.`

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

 # 6000

In any case, an error highlighted is an opportunity to rectify it, so not a bad behaviour.

Solution 6:[6]

Since there are already a number of answers directly addressing the question, and R is often used by technically skilled non-programmers, let me quickly outline why the error exists, and advise against suppression workarounds.

The number of parameters is an important aspect defining a function. If the number of parameters mismatches, that's a good indication that there is a mismatch between the callers intent and what the function is about to do. For this reason, this would be a compilation error in many programming languages, including Java, Python, Haskell, and many others. Indeed, stricter type checking in many of these languages will also cause errors if types mismatch.

As a program grows in size, and code ages, it becomes harder to spot whether mismatches of this kind are intended or are genuine bugs. This is why an idea of "clean code" - simple to read code with no errors or warnings - is often a standard professional programmers work towards.

Accordingly, I recommend reworking the code to remove the unnecessary parameter. It will be simpler to understand and debug for yourself and others in the future.

Of course I understand that R users are often working on small scripts with limited lifespans, and the usual tradeoffs of large software engineering projects don't always apply. Maybe for your quick script, that will only be used for a week, made sense to just suppress the error. However, it is widely observed (and I have seen in my own experience) that what code endures is rarely obvious at the time of writing. If you are pursuing open science, and publishing your code and data, it is especially helpful for that code to be useful in the future, to others, so they can reproduce your results.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Wart
Solution 2 Chase
Solution 3 BenBarnes
Solution 4
Solution 5 Amaks
Solution 6 Adam Burke