Dealing with TRUE, FALSE, NA and NaN
Solution 1
To answer your questions in order:
1) The ==
operator does indeed not treat NA's as you would expect it to. A very useful function is this compareNA
function from r-cookbook.com:
compareNA <- function(v1,v2) {
# This function returns TRUE wherever elements are the same, including NA's,
# and false everywhere else.
same <- (v1 == v2) | (is.na(v1) & is.na(v2))
same[is.na(same)] <- FALSE
return(same)
}
2) NA stands for "Not available", and is not the same as the general NaN ("not a number"). NA is generally used for a default value for a number to stand in for missing data; NaN's are normally generated because a numerical issue (taking log of -1 or similar).
3) I'm not really sure what you mean by "logical things"--many different data types, including numeric vectors, can be used as input to logical operators. You might want to try reading the R logical operators page: http://stat.ethz.ch/R-manual/R-patched/library/base/html/Logic.html.
Hope this helps!
Solution 2
You don't need to wrap anything in a function - the following works
a = c(T,F,NA)
a %in% TRUE
[1] TRUE FALSE FALSE
Solution 3
So you want TRUE to remain TRUE and FALSE to remain FALSE, the only real change is that NA needs to become FALSE, so just do this change like:
a[ is.na(a) ] <- FALSE
Or you could rephrase to say it is only TRUE if it is TRUE and not missing:
a <- a & !is.na(a)
Solution 4
I like the is.element-function:
is.element(a, T)
Solution 5
Taking Ben Bolker's suggestion above you could set your own function following the is.na() syntax
is.true <- function(x) {
!is.na(x) & x
}
a = c(T,F,F,NA,F,T,NA,F,T)
is.true(a)
[1] TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE
This also works for subsetting data.
b = c(1:9)
df <- as.data.frame(cbind(a,b))
df[is.true(df$a),]
a b
1 1 1
6 1 6
9 1 9
And helps avoid accidentally incorporating empty rows where NA do exist in the data.
df[df$a == TRUE,]
a b
1 1 1
NA NA NA
6 1 6
NA.1 NA NA
9 1 9
Remi.b
Updated on March 05, 2020Comments
-
Remi.b about 4 years
Here is a vector
a <- c(TRUE, FALSE, FALSE, NA, FALSE, TRUE, NA, FALSE, TRUE)
I'd like a simple function that returns
TRUE
everytime there is aTRUE
in "a", andFALSE
everytime there is aFALSE
or aNA
in "a".The three following things do not work
a == TRUE identical(TRUE, a) isTRUE(a)
Here is a solution
a[-which(is.na(a))]
but it doesn't seem to be a straightforward and easy solution
Is there another solution ?
Here are some functions (and operators) I know:
identical() isTRUE() is.na() na.rm() & | !
What are the other functions (operators, tips, whatever,...) that are useful to deal with
TRUE
,FALSE
,NA
,NaN
?What are the differences between
NA
andNaN
?Are there other "logical things" than
TRUE
,FALSE
,NA
andNaN
?
Thanks a lot !
-
Matthew Plourde almost 11 yearsDivision by 0 is
Inf
, butInf - Inf
gives youNaN
. A lot of times R functions will raise an exception ifNaN
s are generated, e.g.,log(-1)
. -
Ben Bolker over 9 yearsyou really don't need the
ifelse()
here -- as @GregSnow's answer points out,!is.na(x) & x
is equivalent -
Ari B. Friedman about 9 yearsNice solution. You can use it in functional form:
'%in%'(aamc$forgive, FALSE)
which is useful forapply
and its ilk. -
Jim Maas almost 4 yearsVery nice and useful solution when trying to build functions that will not throw errors etc. when using logical tests involving ">=", "<=", "==", etc. when it might be evaluated against a NA.
-
Jim Maas almost 4 yearsBen, I really agree with this, and it works but it is not straight forward to follow the logic because you get into double and triple negatives paradigm .... which many of us find hard to follow. Is there not a better, more direct way that does not depend on double negatives ?
-
JRC about 2 yearseq = function(x,y) is.element(x == y, TRUE) | is.na(x) & is.na(y)