arraysrna

How to treat NAs like values when comparing elementwise in R


I want to compare two vectors elementwise to check whether an element in a certain position in the first vector is different from the element in the same position in the second vector.
The point is that I have NA values inside the vectors, and when doing the comparison for these values I get NA instead of TRUE or FALSE.

Reproducible example:

Here is what I get:

a<-c(1, NA, 2, 2, NA)
b<-c(1, 1, 1, NA, NA)
a!=b
[1] FALSE   TRUE   NA   NA   NA  

Here is how I would like the != operator to work (treat NA values as if they were just another "level" of the variable):

a!=b
[1] FALSE   TRUE   TRUE   TRUE   FALSE

There's a possible solution at this link, but the guy is creating a function to perform the task. I was wondering if there's a more elegant way to do that.


Solution

  • Taking advantage of the fact that:

    T & NA = NA but F & NA = F

    and

    F | NA = NA but T | NA = T

    The following solution works, with carefully placed brackets:

    (a != b | (is.na(a) & !is.na(b)) | (is.na(b) & !is.na(a))) & !(is.na(a) & is.na(b))
    

    You could define:

    `%!=na%` <- function(e1, e2) (e1 != e2 | (is.na(e1) & !is.na(e2)) | (is.na(e2) & !is.na(e1))) & !(is.na(e1) & is.na(e2))
    

    and then use:

    a %!=na% b