Home > other >  Or operator not behaving as expected in R
Or operator not behaving as expected in R

Time:01-24

Can someone please explain what is going with the Or operator here (|)? I'm just trying to write a simple function to test if an element is in a vector. However when I pass two values which both aren't in the vector using the | operator it gives me a false positive (see last line). Everything else seems to behave as expected...

v <- c(1,2,3)

if (1 %in% v){print('present')}else{print('not present')}
# [1] "present"

if (1&2 %in% v){print('present')}else{print('not present')}
# [1] "present"
 
if (1|2 %in% v){print('present')}else{print('not present')}
# [1] "present"

if (4 %in% v){print('present')}else{print('not present')}
# [1] "not present"
 
if (1&4 %in% v){print('present')}else{print('not present')}
# [1] "not present"
 
if (1|4 %in% v){print('present')}else{print('not present')}
# [1] "present"
 
if (4&5 %in% v){print('present')}else{print('not present')}
# [1] "not present"
 
if (4|5 %in% v){print('present')}else{print('not present')}
#[1] "present"

CodePudding user response:

A few points:

  1. When numeric objects are used as arguments to logical operators 0 is regarded as FALSE and other numbers are regarded as TRUE. See ?as.logical .

     as.logical(0)
     ## [1] FALSE
    
     as.logical(4)
     ## [1] TRUE
    
  2. && and || are normally used within an if because they short-circuit whereas & and | do not. That means that the right hand side is not evaluated if the result can already be determined from the left hand side. (Another difference is that & and | are vectorized whereas && and || are not but since the condition in an if must be scalar we don't need vectorization in that situation.) For example

     0 & stop()
     ## Error: 
    
     0 && stop()
     ## [1] FALSE
    
  3. %in% is done before & or | if there are no parentheses. See ?Syntax for a table giving the order of operations. Parentheses are often used to avoid reliance on order of operations.

Examples

This is TRUE because 1 is in v:

1 %in% v
## [1] TRUE

These are the same and are TRUE because 1 is regarded as TRUE and 2 is in v

1 & 2 %in% v
## [1] TRUE

1 & (2 %in% v)
## [1] TRUE

These are the same and are TRUE because 1 is regarded as TRUE. It doesn't matter whether 2 %in% v is TRUE or FALSE because | is TRUE if either of the arguments is TRUE.

1 | 2 %in% v
## [1] TRUE

1 | (2 %in% v)
## [1] TRUE

This is FALSE because 4 is not in v

4 %in% v
## [1] FALSE

These are the same and are false because 4 is regarded as TRUE and 5 is not in v and & is only TRUE if both sides are TRUE.

4 & 5 %in% v
## [1] FALSE

4 & (5 %in% v)
## [1] FALSE

These are the same and are TRUE because 4 is regarded as TRUE and the second argument doesn't matter because | is TRUE if either argument is TRUE.

4 | 5 %in% v
## [1] TRUE

4 | (5 %in% v)
## [1] TRUE

These are all TRUE:

1 %in% v && 2 %in% v
## [1] TRUE

(1 %in% v) && (2 %in% v)
## [1] TRUE

all(c(1, 2) %in% v)
## [1] TRUE

1 %in% v || 4 %in% v
## [1] TRUE

(1 %in% v) || (4 %in% v)
## [1] TRUE

any(c(1, 4) %in% v)
## [1] TRUE
  •  Tags:  
  • r
  • Related