I know that "||" means "or" in most programming languages, including R. But sometimes I see people using "|". And I am not entirely sure what it means. How is it different from "||" ?
Thanks
I know that "||" means "or" in most programming languages, including R. But sometimes I see people using "|". And I am not entirely sure what it means. How is it different from "||" ?
Thanks
To get to the help for the logical operators in R you have to do
?`|`
or
?`||`
Both of which take you to the appropriate help page http://stat.ethz.ch/R-manual/R-patched/library/base/html/Logic.html
You won't notice a difference until you either put a vector in, or something that doesn't evaluate properly:
> T|F
[1] TRUE
> T||F
[1] TRUE
But when you use a vector:
> c(T,T,F,F) || c(T,F,T,F)
[1] TRUE
> c(T,T,F,F) | c(T,F,T,F)
[1] TRUE TRUE TRUE FALSE
Similarly with &
and &&
:
> c(T,T,F,F) & c(T,F,T,F)
[1] TRUE FALSE FALSE FALSE
> c(T,T,F,F) && c(T,F,T,F)
[1] TRUE
So |
and &
compare elements in corresponding positions in the two vectors and uses that to populate a new logical vector. If one vector is shorter than the other, its elements get "recycled" from the start:
> c(T, F, T, F) | c(T, T, F, F, T, F) #first 2 elements of left vector recycled
[1] TRUE TRUE TRUE FALSE TRUE FALSE
Warning message:
In c(T, F, T, F) | c(T, T, F, F, T, F) :
longer object length is not a multiple of shorter object length
> c(T, F, T, F, T, F) | c(T, T, F, F, T, F) #what actually got evaluated
[1] TRUE TRUE TRUE FALSE TRUE FALSE
Note that ||
and &&
only look at the first element of the vectors, so for instance:
> c(T,T,T,T) && c(F,T,T,T) #only does T & F
[1] FALSE
> c(F,T,T,T) || c(F,T,T,T) #only does F | F
[1] FALSE
> c(T,F,F,F) && c(T,F,F,F) #only does T & T
[1] TRUE
> c(T,F,F,F) || c(F,F,F,F) #only does F | F
[1] TRUE
For inputs that can't be evaluated, ||
and &&
are cleverer: they "shortcircuit" from left to right. If the left-hand input of ||
is TRUE
(so the result must be TRUE
) or the left-hand input of &&
is FALSE
(so the result must be FALSE
) then right-hand input need not be evaluated.
> x
Error: object 'x' not found
> exists("x")
[1] FALSE
> F & x # evaluates right input, fails
Error: object 'x' not found
> F && x # skips right input, already knows result F
[1] FALSE
> T && x # can't skip right input, so fails
Error: object 'x' not found
> T | x
Error: object 'x' not found
> T || x # skips right input, already knows result T
[1] TRUE
This is useful if you want to check something safely:
> (x > 20)
Error: object 'x' not found
> exists("x") & (x > 20) # still evaluated right input, fails
Error: object 'x' not found
> exists("x") && (x > 20) # safe
[1] FALSE
There are three relevant differences between the operators &&
/||
and &
/|
, which are explained in the official documentation. Here’s a summary:
&
and |
are vectorisedThis means that if you want to perform element-wise logical operations on vectors you should use &
and |
:
a = c(TRUE, TRUE, FALSE, FALSE)
b = c(TRUE, FALSE, TRUE, FALSE)
a | b
# [1] TRUE TRUE TRUE FALSE
a || b
# [1] TRUE
For &&
/||
all elements after the first are discarded. Recent versions of R generate a helpful warning when using &&
/||
on vectors longer than 1:
In a || b : 'length(x) = 4 > 1' in coercion to 'logical(1)'
&&
and ||
are short-circuitedShort-circuiting means that the right-hand side of the expression is only evaluated if the left-hand side does not already determine the outcome. Pretty much every programming language does this for conditional operations, since it leads to handy idioms when writing if
conditions, e.g.:
if (length(x) > 0L && x[1L] == 42) …
This code relies on short-circuiting: without it, the code would fail if x
is empty, since the right-hand side attempts to access a non-existent element. Without short-circuiting, we would have to use nested if
blocks, leading to more verbose code:
if (length(x) > 0L) {
if (x[1L] == 42) …
}
As a general rule, inside a conditional expression (if
, while
) you should always use &&
and ||
, even if short-circuiting isn’t required: it’s more idiomatic, and leads to more uniform code.
&
and |
can perform bitwise arithmeticIn many (most?) programming languages, &
and |
actually perform bitwise arithmetic instead of Boolean arithmetic. That is, for two integers a
and b
, a & b
calculates the bitwise and, and a | b
calculates the bitwise or. For Boolean values there’s no difference between bitwise and logical operations; but for arbitrary integers, the result differs. For instance, 1 | 2 == 3
in most programming languages.
However, this is not true for R: R coerces numeric arguments of &
and |
to logical values and performs Boolean arithmetic.
… except when both arguments are of type raw
:
c(1, 3) | c(2, 4)
# [1] TRUE TRUE
as.raw(c(1, 3)) | as.raw(c(2, 4))
# [1] 03 07
It is worth noting that the operations !
(logical negation) and xor
also perform bitwise arithmetic when called with raw
arguments.