Home > database >  Dealing with missing values when writing logical expressions
Dealing with missing values when writing logical expressions

Time:02-05

If you are familiar with SAS you know that missing values are considered as -inf, therefore, for an expression like this:

If a < 2 then c=1 ; 

else c= 5; 

Where "a" is missing; value of 1 will be assigned to c, because the logical expression "a < 2" will be "True". Please notice that my question is about the outcome of the logical expression. I do not care about "c".

I would like to get the same thing in R but the result of the logical expression will be "NA" :

a <-NA

a < 2

[1] NA

How can I change the output of this logical expression to "True" ?

I know I can do this:

output < ifelse( is.na(a), False, a <2)

But I am looking for something simple. Any ideas?

CodePudding user response:

If you use this frequently enough, then you could define an infix operator to wrap around your ifelse:

`%<%` <- function(a, b) { ifelse(is.na(a), TRUE, a < b) }

So if a is

a <- c(NA, 1, 3, 5, NA)

Then you only need do:

a %<% 2
#> [1]  TRUE  TRUE FALSE FALSE  TRUE

CodePudding user response:

You can use the fact that NA is a logical object.

(a < 2) | is.na(a)

CodePudding user response:

Just for fun, and I am absolutely not recommending this approach:

Ops.sas <- function (e1, e2) {
  comparison <- switch(.Generic, `<` = , `>` = , `==` = , `!=` = ,
                    `<=` = , `>=` = TRUE, FALSE)
  if (comparison) {
    e1[is.na(e1)] <- -Inf
    e2[is.na(e2)] <- -Inf
  }
  
  NextMethod(.Generic)
}

And now:

> foo <- structure(c(NA, 2,3,2, NA), class = "sas")
> bar <- structure(c(2,3,2, NA, NA), class = "sas")
> foo < bar
[1]  TRUE  TRUE FALSE FALSE FALSE
> foo <= bar
[1]  TRUE  TRUE FALSE FALSE  TRUE
> foo == bar
[1] FALSE FALSE FALSE FALSE  TRUE
> foo != bar
[1]  TRUE  TRUE  TRUE  TRUE FALSE
> foo > bar
[1] FALSE FALSE  TRUE  TRUE FALSE
> foo >= bar
[1] FALSE FALSE  TRUE  TRUE  TRUE

CodePudding user response:

if(is.na(a) | a < 2){
   c=1
} else {
   c=2
}

I think that the simplest way is just to add a new condition in your test. In R the | symbol stands for OR.

CodePudding user response:

I think you will have to modify the values in a for example like this

a <- c(NA, 1, 3, 4, NA)
a
#> [1] NA  1  3  4 NA

a < 2
#> [1]    NA  TRUE FALSE FALSE    NA

a[is.na(a)] <- -Inf

a < 2
#> [1]  TRUE  TRUE FALSE FALSE  TRUE

Created on 2022-02-04 by the reprex package (v2.0.1)

  •  Tags:  
  • Related