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
| is vectorised, || isn’t (it only looks at the first element):
> a = c(TRUE, TRUE, FALSE, FALSE)
> b = c(TRUE, FALSE, TRUE, FALSE)
> a | b
[1] TRUE TRUE TRUE FALSE
> a || b
[1] TRUE
In addition, || and | preserve the respective properties they have in other languages, meaning ||’s evaluation is short-circuited while |’s isn’t:
> f = function() { cat('f\n'); TRUE }
> f() || f()
f
[1] TRUE
> f() | f()
f
f
[1] TRUE