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:
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
&& 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
%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