What Evaluates to True/False in R

What evaluates to True/False in R?

This is documented on ?logical. The pertinent section of which is:

Details:

‘TRUE’ and ‘FALSE’ are reserved words denoting logical constants
in the R language, whereas ‘T’ and ‘F’ are global variables whose
initial values set to these. All four are ‘logical(1)’ vectors.

Logical vectors are coerced to integer vectors in contexts where a
numerical value is required, with ‘TRUE’ being mapped to ‘1L’,
‘FALSE’ to ‘0L’ and ‘NA’ to ‘NA_integer_’.

The second paragraph there explains the behaviour you are seeing, namely 5 == 1L and 5 == 0L respectively, which should both return FALSE, where as 1 == 1L and 0 == 0L should be TRUE for 1 == TRUE and 0 == FALSE respectively. I believe these are not testing what you want them to test; the comparison is on the basis of the numerical representation of TRUE and FALSE in R, i.e. what numeric values they take when coerced to numeric.

However, only TRUE is guaranteed to the be TRUE:

> isTRUE(TRUE)
[1] TRUE
> isTRUE(1)
[1] FALSE
> isTRUE(T)
[1] TRUE
> T <- 2
> isTRUE(T)
[1] FALSE

isTRUE is a wrapper for identical(x, TRUE), and from ?isTRUE we note:

Details:
....

‘isTRUE(x)’ is an abbreviation of ‘identical(TRUE, x)’, and so is
true if and only if ‘x’ is a length-one logical vector whose only
element is ‘TRUE’ and which has no attributes (not even names).

So by the same virtue, only FALSE is guaranteed to be exactly equal to FALSE.

> identical(F, FALSE)
[1] TRUE
> identical(0, FALSE)
[1] FALSE
> F <- "hello"
> identical(F, FALSE)
[1] FALSE

If this concerns you, always use isTRUE() or identical(x, FALSE) to check for equivalence with TRUE and FALSE respectively. == is not doing what you think it is.

R check if a list of TRUE/FALSE values evaluate to TRUE

Maybe try the all function:

> x <- c(rep(TRUE, 5), FALSE)
> y <- c(rep(TRUE, 6))
> all(x)
[1] FALSE
> all(y)
[1] TRUE

As its name says, it checks if all the values are TRUE.

Why TRUE == TRUE is TRUE in R?

According to the help file ?`==` :

If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.

So TRUE is coerced to "TRUE" (i. e. as.character(TRUE)), hence the equality.

The equivalent of an operator === in some other language (i. e. are the two objects equal and of the same type) would be function identical:

identical(TRUE, "TRUE")
[1] FALSE

Boolean vector comparison for TRUE/FALSE single results

Similar to all as suggested in the comment by @akrun, one could take the slightly more "backwards" approach of using any, which evaluates to true if at least a one element in a vector is true -- in your example, one element is the same as the standard with respect to its index and value. By evaluating this (input) with !input, meaning NOT input, you can obtain the result you are after.

# Standard
logical.vector = c(TRUE, TRUE, FALSE, TRUE)

# Test Patterns

# Case 1 (non-match): should be FALSE
!any(logical.vector != c(TRUE, FALSE, TRUE, TRUE))

# Case 2 (non-match): should be FALSE
!any(logical.vector != c(FALSE, TRUE, FALSE, TRUE))

# Case 3 (non-match): should be FALSE
!any(logical.vector != c(TRUE, TRUE, TRUE, TRUE))

# Case 4 (non-match): should be FALSE
!any(logical.vector != c(FALSE, FALSE, FALSE, FALSE))

# Case 5 (match): should be TRUE
!any(logical.vector != c(TRUE, TRUE, FALSE, TRUE))

Why does as.numeric(1) == (3 | 4) evaluate to TRUE?

1 == 2 | 4

Operator precedence tells us it is equivalent to (1 == 2) | 4

1 == 2 is FALSE, 4 is coerced to logical (because |is a logical operator), as.logical(4) is TRUE, so you have FALSE | TRUE, that's TRUE

Indeed coercion rules for logical operators (?Logic) tell us that:

Numeric and complex vectors will be coerced to logical values, with
zero being false and all non-zero values being true.


3 == 2 | 4

Same thing


1 == (2 | 4)

2 | 4 will be coerced to TRUE | TRUE, which is TRUE. Then 1 == TRUE is coerced to 1 == 1 which is TRUE.

Indeed coercion rules for comparison operators (?Comparison) tell us that:

If the two arguments are atomic vectors of different types, one is
coerced to the type of the other, the (decreasing) order of precedence
being character, complex, numeric, integer, logical and raw.


as.numeric(1) == (2 | 4)

Same thing


1L == (2 | 4)

Same again


1 is equal to 2 or 4

is actually (1 is equal to 2) or (1 is equal to 4), which is:

(1==2)|(1==4)

which is

FALSE | FALSE

which is FALSE

Why do the expressions isTRUE(3) and isTRUE(NA) evaluate to false in R?

Straight from the documentation (try ?isTRUE)

isTRUE(x) is an abbreviation of identical(TRUE, x), and so is true if and only if x is a length-one logical vector whose only element is TRUE and which has no attributes (not even names).

It's not just doing a check on value, it's doing a check to ensure it is a logical value.

I know in computer science often 0 is false and anything non-zero is true, but R approaches things from a statistics point of view, not a computer science point of view, so it's a bit stricter about the definition.

Saying this, you'll notice this if statement evaluates the way you would imagine

if(3){print("yay")}else{print("boo")}

It's just the way R going about evaluation. The function isTRUE is just more specific.

Also note these behaviours

FALSE == 0 is true
TRUE == 1 is true
TRUE == 3 is false

So R will treat 0 and 1 as false and true respectively when perform these sorts of evaluations.

I'm not sure what your planned implementation was (if there was any) but it's probably better trying to be precise about boolean logic in R, or test things beforehand.

As for NA, more strange behaviour.

TRUE & NA equates to NA
TRUE | NA equates to TRUE

In these cases R forces NA to a logical type, since anything or'd with TRUE is a TRUE, it can equate that. But the value would change depending on the second term in an and operation, so it returns NA.

As for your particular case, again isTRUE(NA) is equated as false because NA is not a length-one logical vector whose only element is TRUE.

Change 0/1 values to TRUE/FALSE in R

Use x1 == 1:

> x1 == 1
[,1] [,2]
[1,] TRUE TRUE
[2,] FALSE TRUE
>

Or use x1 == TRUE:

> x1 == TRUE
[,1] [,2]
[1,] TRUE TRUE
[2,] FALSE TRUE
>

Or with apply and as.logical:

> apply(x1, 2, as.logical)
[,1] [,2]
[1,] TRUE FALSE
[2,] TRUE TRUE
>

What is going on with R coercing TRUE string to TRUE logical?

Here's what I made of it:
From the documentation of logical comparisons ?"==":

At least one of x and y must be an atomic vector, but if the other is a list R attempts to coerce it to the type of the atomic vector: this will succeed if the list is made up of elements of length one that can be coerced to the correct type.
If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.

To me it seems like the latter part of this is at work here. TRUE is being coerced to "TRUE" and the actual comparison becomes "TRUE"=="TRUE" instead of TRUE==TRUE.

T always gets converted to TRUE so T=="TRUE" holds. However ``"T"` has no such luck when conversion is to happen to.character and not to.logical. .

For values in list above a number set boolean (true, false) in R

>  a <- c(3, 5, 2, 7, 9)
> Result <- a>5
> Result
[1] FALSE FALSE FALSE TRUE TRUE


Related Topics



Leave a reply



Submit