Xiaotao Luo Xiaotao Luo - 4 months ago 40
R Question

Argument checking in R

In R, I wrote a function like:

fun <- function(A, B, C, D) {}

So, after writing a function, I must do argument checking first:

arguments = {A, B, C, D, ...}

But about these arguments, some is required, some is not, and the class(data type) of a argument must be what I want, for example: numeric, logical, And so on...

So I must do things in the beginning of func:

  • Is some required arguments missing

  • Is all arguments following the rules: class(data type) or A must be in range [1:3]

To accomplish this, I did things likeļ¼š

if(A Follow_the_rule){}
if(B Follow_the_rule){}
if(C Follow_the_rule){}

The code above, so much if condition which I think isn't the best way of argument checking.

So the question is:

Is there a better way of argument checking in R?

Any help will be appreciated.


Have a look at ?stopifnot which does exactly what you want. It checks for the condition within and stops if the condition is not given. The same as in if, you can concatenate conditions with && or || and & amd |. See information with e.g. ?"&". Further helpful may also be all or any to check if all elements of a given vector fulfill the condition or any, respectively. Some examples:

foo <- function(A, B, C){
  stopifnot(!missing(C), !missing(B), !missing(A)) ##A, B, C not missing, then continue
  stopifnot(class(B)=="matrix") ## B is a matrix, then continue
  stopifnot(class(B)==class(C), all(B > C)) ## class B is class C and all elements of B are greater than C
  stopifnot((length(A)>1 && !any(is.na(A))) || all(A==0)) ## (A has more than 1 element and no element is NA) or all elements of A are 0.
  stopifnot(all(A > 2), all(A < 10)) ## all elements of A are between 2 and 10, else stop.

  #... further code

The conditions above may not fit together in this combination, but I think there are enough examples for you to adapt to your problem. Of course you could write all in one stopifnot, but it is more useful to group the conditions if there are many, because the condition which stops the function is printed as error code. So the more stopifnot you have, the more precise is the error information you get.