Yannick Wurm
Yannick Wurm

Reputation: 3718

alternative to "!is.null()" in R

my R code ends up containing plethora of statements of the form:

if (!is.null(aVariable)) { 
     do whatever 
}

But this kind of statement is hard to read because it contains two negations. I would prefer something like:

 if (is.defined(aVariable)) { 
      do whatever 
 }

Does a is.defined type function that does the opposite of !is.null exist standard in R?

cheers, yannick

Upvotes: 74

Views: 168257

Answers (7)

LMc
LMc

Reputation: 18752

Create a not_null() function using Negate:

not_null <- Negate(is.null)

if (not_null("a")) "Here" else "There"
# [1] "Here"

if (not_null(NULL)) "Here" else "There"
# [1] "There"

Negate() does the exact solution given by @Etienne Racine

Upvotes: 2

Etienne Racine
Etienne Racine

Reputation: 1383

If it's just a matter of easy reading, you could always define your own function :

is.not.null <- function(x) !is.null(x)

So you can use it all along your program.

is.not.null(3)
is.not.null(NULL)

Upvotes: 26

bdetweiler
bdetweiler

Reputation: 1574

To handle undefined variables as well as nulls, you can use substitute with deparse:

nullSafe <- function(x) {
  if (!exists(deparse(substitute(x))) || is.null(x)) {
    return(NA)
  } else {
    return(x)
  }
}

nullSafe(my.nonexistent.var)

Upvotes: 3

Brandon Bertelsen
Brandon Bertelsen

Reputation: 44708

I have also seen:

if(length(obj)) {
  # do this if object has length
  # NULL has no length
}

I don't think it's great though. Because some vectors can be of length 0. character(0), logical(0), integer(0) and that might be treated as a NULL instead of an error.

Upvotes: 9

sgrubsmyon
sgrubsmyon

Reputation: 1229

The shiny package provides the convenient functions validate() and need() for checking that variables are both available and valid. need() evaluates an expression. If the expression is not valid, then an error message is returned. If the expression is valid, NULL is returned. One can use this to check if a variable is valid. See ?need for more information.

I suggest defining a function like this:

is.valid <- function(x) {
  require(shiny)
  is.null(need(x, message = FALSE))  
}

This function is.valid() will return FALSE if x is FALSE, NULL, NA, NaN, an empty string "", an empty atomic vector, a vector containing only missing values, a logical vector containing only FALSE, or an object of class try-error. In all other cases, it returns TRUE.

That means, need() (and is.valid()) covers a really broad range of failure cases. Instead of writing:

if (!is.null(x) && !is.na(x) && !is.nan(x)) {
  ...
}

one can write simply:

if (is.valid(x)) {
  ...
}

With the check for class try-error, it can even be used in conjunction with a try() block to silently catch errors: (see https://csgillespie.github.io/efficientR/programming.html#communicating-with-the-user)

bad = try(1 + "1", silent = TRUE)
if (is.valid(bad)) {
  ...
}

Upvotes: 3

JD Long
JD Long

Reputation: 60756

Ian put this in the comment, but I think it's a good answer:

if (exists("aVariable"))
{
  do whatever
}

note that the variable name is quoted.

Upvotes: 9

Alex Brown
Alex Brown

Reputation: 42942

You may be better off working out what value type your function or code accepts, and asking for that:

if (is.integer(aVariable))
{
  do whatever
}

This may be an improvement over isnull, because it provides type checking. On the other hand, it may reduce the genericity of your code.

Alternatively, just make the function you want:

is.defined = function(x)!is.null(x)

Upvotes: 46

Related Questions