In R, there is the more general & and | that applies over a vector.
If you use && or ||, you will be exposed to bugs. So I can't think of a reason why we would use either of these.
In R, there is the more general & and | that applies over a vector.
If you use && or ||, you will be exposed to bugs. So I can't think of a reason why we would use either of these.
I feel like this is implicitly covered by Boolean operators && and || , but:
A && B, B is only evaluated if it needs to be; if A is FALSE then we know the result will be FALSE without evaluating B
B would throw an error if A is FALSE (if we wanted to do this with & we would have to include some kind of try()/tryCatch() to handle that case)I agree that the evaluation rule that &&/||
evaluate[s] left to right examining only the first element of each vector
(without even throwing a warning)
seems odd and prone to produce unwanted/surprising results, i.e. if you accidentally use a vector of length>1 as part of a control statement. It would seem more natural to throw a warning or error in this case (e.g., the way that if() does if you give it a vector of length>1).
According to this tweet
It's a design bug in R; should really give error. There's work since R 3.6.0 (2019) to fix it. Until fixed, set
_R_CHECK_LENGTH_1_LOGIC2_=truein your~/.Renvironto get "Error in c(TRUE, TRUE) && c(TRUE, TRUE) : 'length(x) = 2 > 1' in coercion to 'logical(1)'"
(See this commit from 2018; this flag is used in CRAN checks.)
I don't know whether there is an (to me) obscure use case where this is convenient, or if it's for S compatibility. From Becker et al. 1988 The New S Language (via Google Books):
Frustratingly, this does not explicitly define what happens if either cond1 or cond2 has length > 1 ...
The longer forms are intended for control statements where only a single logical value is allowed (even though more then one value is accepted with a warning). However, the longer forms only evaluate until the result is clear. Consider the following.
TRUE || FALSE
In this case, the FALSE does not have to be considered because the result is already clear from the TRUE. Consequently, the FALSE is not even evaluated. This is particularly useful if your second condition relies on the first condition being true because it would throw an error otherwise.
x <- "a"
if (is.numeric(x) & x/2 > 5) print(x)
if (is.numeric(x) && x/2 > 5) print(x)
The first case throws an error because you can't divide a character by a number. The second case will do just fine.