In R, the operators “|” and “&” indicate the logical operations OR and AND. For example, to test if x equals 1 and y equals 2 we do the following:
> x = 1; y = 2
> (x == 1) & (y == 2)
[1] TRUE
However, if you are used to programming in C you may be tempted to write
#Gives the same answer as above (in this example...)
> (x == 1) && (y == 2)
[1] TRUE
At this point you could be lulled into a false sense of security and believe that they could be used interchangeably. Big mistake.
Let’s consider another example, this time a vector comparison:
> z = 1:6
> (z > 2) & (z < 5)
[1] FALSE FALSE TRUE TRUE FALSE FALSE
> z[(z>2) & (z<5)]
[1] 3 4
but the double “&&” gives
> (z > 2) && (z < 5)
[1] FALSE
> z[(z > 2) && (z < 5)]
integer(0)#Probably not what you want
It’s all gone a bit pear shaped! In fact it could have been worse:
> (z > 2) && (z < 5)
[1] TRUE
> z[(z > 0) && (z < 5)]
[1] 1 2 3 4 5 6
Now you’ve the wrong answer and something that would be very tricky to spot. This is because R recylces the TRUE variable.
What’s the difference?
Well from the R help page:
“The longer form evaluates left to right examining only the first element of each vector”
where the longer form refers to “&&”. So
> (z > 2) && (z < 5)
[1] FALSE
is equivalent to:
> (z[1] > 2) & (z[1] < 5)
[1] FALSE
The same concept applies to the OR operator, “|”.
As the commentators point out below, another key difference is for the longer form
“Evaluation proceeds only until the result is determined”
This concept is highlighted in the following example:
> f = function(){cat("My name is f\n");return(TRUE)}
> g = function(){cat("My name is g\n");return(FALSE)}
> f() | g()
My name is f
My name is g
[1] TRUE
> f() || g()
My name is f
[1] TRUE
This has two benefits:
- Evaluation will be faster. In the above example, the function
gisn’t evaluated (thanks to Andrew Robson and NotMe) - Also, you can use the double variety to check a property of a data structure before carrying on with your analysis, i.e.
all(!is.na(x)) && mean(x) > 0(thanks to Pat Burns for this tip)


Hi Colin,
X || Y performs sequential evaluation of X and Y.
From p. 22 of our lovely book[1] … X || Y is useful when Y is not always well-defined. Also, if Y takes a while to evaluate.
There are reasonably easy work-arounds for both conditions, but || and && provide a compact representation.
Best wishes
Andrew
[1] “Introduction to Scientific Programming and Simulation using R“, 2009, Chapman & Hall.
Comment by Andrew Robinson — December 15, 2010 @ 3:20 am
As is mentioned on ?”&&” you mainly use && in if-clauses. So something like if ((a==3) && (b==4) && (d==7)). So if (a==3) is NOT true, then R doesn’t need to look whether b==4 or d==7. Should be faster.
Comment by NotMe — December 15, 2010 @ 8:06 am
As an example of what the previous comments are talking about, you might have something like:
if(all(!is.na(x)) && mean(x) > 0) { …
The first part about missing values makes sure that you don’t run into trouble with the test on the mean (which is what you really care about).
Comment by Pat Burns — December 15, 2010 @ 9:44 am
Many thanks for your helpful comment. I’ve updated the post accordingly.
Comment by csgillespie — December 15, 2010 @ 5:03 pm