Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R check if any missing arguments

I have a function with MANY arguments. I need to throw an error if ANY of them are missing:

This can be done like so:

testFunction = function(a,b,c,d,e,f,g,....){
  if(missing(a)) stop("a is required")
  if(missing(b)) stop("b is required")
  if(missing(c)) stop("c is required")
  if(missing(d)) stop("d is required")
  if(missing(e)) stop("e is required")
  if(missing(f)) stop("f is required")
  if(missing(g)) stop("g is required")
}

But my actual case contains many more arguments than the above trivial example, and as such, I would rather execute an equivalent check using a loop, something like this: (which doesn't work)

testFunction = function(a,b,c,d,e,f,g,...){
  args = as.list(environment())
  for(n in names(args)){
    if(missing(as.name(n))) stop(sprintf("%s is required",n))
  }
}

The above throws an error:

Error in missing(as.name(n)) : invalid use of 'missing'

How can I check whether an argument is missing by a character representation of the argument name?

like image 260
Nicholas Hamilton Avatar asked Aug 04 '16 03:08

Nicholas Hamilton


1 Answers

What about something like this instead

f <- function(a,b,c,d) {
    defined <- ls()
    passed <- names(as.list(match.call())[-1])

    if (any(!defined %in% passed)) {
        stop(paste("missing values for", paste(setdiff(defined, passed), collapse=", ")))
    }
    a+b+c+d
}

And it works like this

f(1)
# Error in f(1) : missing values for b, c, d
f(2, d=3)
# Error in f(2, d = 3) : missing values for b, c
f(1,2,3,4)
# [1] 10

Basically we use ls() to get a list of variables in the function at the time (which should be all the arguments) and then we use match.call() to see what was actually passed to the function.

like image 88
MrFlick Avatar answered Nov 03 '22 12:11

MrFlick