jmuhlenkamp
jmuhlenkamp

Reputation: 2150

Make R stopifnot or similar simple function raise an error when expression returns length of zero

I'm using the stopifnot function in R to validate an expected result. However, I've noticed that if the expression returns a vector of length 0, then stopifnot will not raise an error. Here is a simple reproducible example.

Imagine an optimization function where one of the list elements is named convergence containing either a 0 or 1, and I wish to validate that the element named convergence contains 0 and raise an error otherwise.

return01 <- function(x){
    return(list(convergence = x))
}
opt1 <- return01(1)

I can easily do the validation I desire with stopifnot.

stopifnot(opt1$convergence == 0) # raises desired error

However, imagine I typed the wrong element name such as converged instead of convergence. My validation no longer throws any error because opt1$converged is NULL and opt1$converged == 0 resolves to logical(0)

stopifnot(opt1$converged == 0) # does not raise an error
stopifnot(NULL == 0) # does not raise an error

I've come up the workaround below where I would always have to also validate the length of the expression as well.

stopifnot(opt1$converged == 0, length(opt1$converged == 0) > 0) # raises an error
stopifnot(NULL == 0, length(NULL == 0) > 0) # raises an error

Is there a simpler, more elegant, or better practice solution here to make this validation robust to the expression returning logical(0) yet retaining the simplicity and conciseness of stopifnot(opt1$convergence == 0) rather than having to explicitly do another expression using length? Specifically, I would like the validation to also raise an error if the expression returns logical(0).

Upvotes: 0

Views: 521

Answers (1)

G. Grothendieck
G. Grothendieck

Reputation: 269654

Check whether it is identical to zero:

stopifnot(identical(opt1$convergence, 0))

or if convergence is normally of integer type use 0L.

The code above will raise an error if convergence is anything other than 0. For example,

stopifnot(identical(1, 0))
## Error: identical(1, 0) is not TRUE

stopifnot(identical(NULL, 0))
## Error: identical(NULL, 0) is not TRUE

stopifnot(identical(numeric(0), 0)
## Error: identical(numeric(0), 0) is not TRUE

stopifnot(identical(logical(0), 0))
## Error: identical(logical(0), 0) is not TRUE

Upvotes: 1

Related Questions