271

According to the R language definition, the difference between & and && (correspondingly | and ||) is that the former is vectorized while the latter is not.

According to the help text, I read the difference akin to the difference between an "And" and "AndAlso" (correspondingly "Or" and "OrElse")... Meaning: That not all evaluations if they don't have to be (i.e. A or B or C is always true if A is true, so stop evaluating if A is true)

Could someone shed light here? Also, is there an AndAlso and OrElse in R?

matt
  • 447,615
  • 74
  • 748
  • 977
SFun28
  • 32,209
  • 43
  • 123
  • 233
  • Also see similar questions at http://stackoverflow.com/q/6933598/210673 and http://stackoverflow.com/q/7953833/210673 (now closed as a duplicate). – Aaron left Stack Overflow Oct 22 '12 at 14:27
  • 3
    I think && and || are badly implemented in R. In other languages they the conditional AND and OR operators, they perform a logical AND or OR boolean operations, but only evaluate its second operand if necessary. In R don't do anything useful. – skan Nov 28 '16 at 18:51
  • 1
    @skan: I think your claim that `&&` and `||` behaves differently than unspecified "other languages" which do not evaluate a second argument when the first is determinate is simply FALSE. – IRTFM Feb 12 '21 at 22:01

3 Answers3

368

The shorter ones are vectorized, meaning they can return a vector, like this:

((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE  TRUE FALSE FALSE

The longer form evaluates left to right examining only the first element of each vector, so the above gives

((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE

As the help page says, this makes the longer form "appropriate for programming control-flow and [is] typically preferred in if clauses."

So you want to use the long forms only when you are certain the vectors are length one.

You should be absolutely certain your vectors are only length 1, such as in cases where they are functions that return only length 1 booleans. You want to use the short forms if the vectors are length possibly >1. So if you're not absolutely sure, you should either check first, or use the short form and then use all and any to reduce it to length one for use in control flow statements, like if.

The functions all and any are often used on the result of a vectorized comparison to see if all or any of the comparisons are true, respectively. The results from these functions are sure to be length 1 so they are appropriate for use in if clauses, while the results from the vectorized comparison are not. (Though those results would be appropriate for use in ifelse.

One final difference: the && and || only evaluate as many terms as they need to (which seems to be what is meant by short-circuiting). For example, here's a comparison using an undefined value a; if it didn't short-circuit, as & and | don't, it would give an error.

a
# Error: object 'a' not found
TRUE || a
# [1] TRUE
FALSE && a
# [1] FALSE
TRUE | a
# Error: object 'a' not found
FALSE & a
# Error: object 'a' not found

Finally, see section 8.2.17 in The R Inferno, titled "and and andand".

MichaelChirico
  • 31,197
  • 13
  • 98
  • 169
Aaron left Stack Overflow
  • 34,320
  • 5
  • 72
  • 135
  • I'm comparing logicals of length 1. The documentation is not clear about why its preferred for control-flow. Is that because it uses the "short-circuit" from @Theo's answers and thus has better performance? – SFun28 Jul 02 '11 at 19:21
  • nope. Just use the short form '&' -- the short-circuit answers are incorrect. – M. Tibbits Jul 02 '11 at 19:25
  • 1
    No, because it guarantees to have only a single TRUE/FALSE answer. The shorter forms could result in `c(TRUE, FALSE)`, and the `if` statement wouldn't be clear. If you are certain everything has length 1, then yes, either would do, and you are correct that the "short-circuit" is the reason for preferring one. A word of warning though, make sure you are 100% sure they can only be length one. You can get really goofy bugs otherwise. – Aaron left Stack Overflow Jul 02 '11 at 19:28
  • 10
    @SFun28: Yes, short-circuiting is the reason it preferred for flow control. As well as better performance, you may not want to evaluate all arguments. The canonical example is given in `?is.R` for checking whether you are running R or S-Plus. `if(exists("is.R") && is.function(is.R) && is.R())`. If `is.R` doesn't exist, then you don't want to evaluate `is.function(is.R)` since it will throw an error. Likewise if `is.R` isn't a function, you don't want to call it as though it is. – Richie Cotton Jul 04 '11 at 12:49
  • 2
    In the current version of the R inferno, the relevant section is now 8.2.17 "and and andand" – Silverfish Mar 07 '14 at 14:49
38

The answer about "short-circuiting" is potentially misleading, but has some truth (see below). In the R/S language, && and || only evaluate the first element in the first argument. All other elements in a vector or list are ignored regardless of the first ones value. Those operators are designed to work with the if (cond) {} else{} construction and to direct program control rather than construct new vectors.. The & and the | operators are designed to work on vectors, so they will be applied "in parallel", so to speak, along the length of the longest argument. Both vectors need to be evaluated before the comparisons are made. If the vectors are not the same length, then recycling of the shorter argument is performed.

When the arguments to && or || are evaluated, there is "short-circuiting" in that if any of the values in succession from left to right are determinative, then evaluations cease and the final value is returned.

> if( print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(FALSE && print(1) ) {print(2)} else {print(3)} # `print(1)` not evaluated
[1] 3
> if(TRUE && print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(TRUE && !print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 3
> if(FALSE && !print(1) ) {print(2)} else {print(3)}
[1] 3

The advantage of short-circuiting will only appear when the arguments take a long time to evaluate. That will typically occur when the arguments are functions that either process larger objects or have mathematical operations that are more complex.

IRTFM
  • 240,863
  • 19
  • 328
  • 451
  • "short-circuiting" is a new term to me, but it seems to me that the answer describing it agrees with what you say about `&&` and `||`. – Aaron left Stack Overflow Jul 02 '11 at 19:22
  • @DWin - in the case of operatoring over length 1 logicals, they are equivalent right? I'm trying to understand why they are preferred in control-flow as the documentation states. Also, does R have a "short-circuit" construct? – SFun28 Jul 02 '11 at 19:23
  • They are **NOT** equivalent for vectors of length > 1 – M. Tibbits Jul 02 '11 at 19:26
  • 2
    It is true that if the arguments to `&&` are functions and the first one is false, then the second one will not be evaluated. That is not true for either `&` or `ifelse` which will evaluate both arguments. – IRTFM Jul 02 '11 at 19:29
  • Isn't that what Theo's answer about short-circuiting says too? – Aaron left Stack Overflow Jul 02 '11 at 19:36
  • @DWin, you have just said that `&&` is short circuiting, but in your answer you say that they are not, make up your mind. – Theo Jul 02 '11 at 19:36
  • @Theo. I was misinterpreting your answer. I wasn't the only one so I hope my revised explanation is better. – IRTFM Jul 02 '11 at 19:40
  • Another example along the same lines: `if (!print(1) & print(2)) print(3)` returns 1 and 2 while `if (!print(1) && print(2)) print(3)` returns 1. – papgeo Aug 29 '18 at 09:35
  • "if any of the values in succession from left to right are determinative, then evaluations cease". I understand this in principle, but why then do the 3rd & 4th examples return 1? TRUE (first value) is determinative thus shouldn't it jump to the first `expr` and return 2 in both cases? Or is this an odd case due to use of `print` as a logically-evaluable condition? – dez93_2000 Feb 11 '21 at 18:05
  • 1
    @dez93 TRUE is not determinative when it precedes "&&". And those are not really returning 1 but rather 1 is being printed as a side-effect of the evaluation of the `print` function before the 2 and 3 are returned respectively. The 1 is being printed as a sign that the TRUE' were not determinative at that point. There was no 1 printed to the console in the 5th instance because the FALSE was determinative for the "&&" expression since the value of a second argument would not matter. If I had assigned the result of the if clause to a named variable we could have seen the situation more clearly. – IRTFM Feb 11 '21 at 21:52
  • Right, sorry yeah: so because the whole COND needs to evaluate TRUE to trigger the first EXPR, COND1=FALSE is determinitive (COND can't be TRUE) but COND1=TRUE isn't (because COND2 could still be FALSE). Cheers. – dez93_2000 Feb 12 '21 at 03:26
28

&& and || are what is called "short circuiting". That means that they will not evaluate the second operand if the first operand is enough to determine the value of the expression.

For example if the first operand to && is false then there is no point in evaluating the second operand, since it can't change the value of the expression (false && true and false && false are both false). The same goes for || when the first operand is true.

You can read more about this here: http://en.wikipedia.org/wiki/Short-circuit_evaluation From the table on that page you can see that && is equivalent to AndAlso in VB.NET, which I assume you are referring to.

Theo
  • 125,348
  • 20
  • 140
  • 181
  • 3
    This should be proof enough that it is short circuiting: `f – Theo Jul 02 '11 at 19:32
  • 2
    Theo, yes, you are correct that `&&` and `||` short-circuit. But that's really a fairly minor point in comparisons between the short form and the long form; it's much more important to understand what each does when the inputs are vectors. – Aaron left Stack Overflow Jul 02 '11 at 19:37
  • 2
    @MTibbits In fact this is not a complete answer, but the statement about short circuiting **is correct**. Try `F & {message("Boo!");T}` and `F && {message("Boo!");T}`. – mbq Jul 02 '11 at 19:39