Reputation: 15338
So, how does the "conditional or" (also called "short-circuit or"), written as ||
operator work in R?
Querying ?Logic
reveals:
& and && indicate logical AND and | and || indicate logical OR. The shorter form performs elementwise comparisons in much the same way as arithmetic operators. The longer form evaluates left to right examining only the first element of each vector. Evaluation proceeds only until the result is determined. The longer form is appropriate for programming control-flow and typically preferred in if clauses.
Sounds standard.
> library(dplyr)
> as_tibble(mtcars) %>% filter(between(hp,50,70))
# A tibble: 5 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
2 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
3 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2
4 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
5 27.3 4 79 66 4.08 1.94 18.9 1 1 4 1
Ok.
> as_tibble(mtcars) %>% filter(between(hp,80,90))
# A tibble: 0 x 11
# … with 11 variables: mpg <dbl>, cyl <dbl>, disp <dbl>, hp <dbl>, drat <dbl>, ...
# carb <dbl>
Ok. Let's try the standard or |
, which is equivalent to set union here:
> as_tibble(mtcars) %>% filter(between(hp,50,70) | between(hp,80,90))
# A tibble: 5 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
2 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
3 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2
4 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
5 27.3 4 79 66 4.08 1.94 18.9 1 1 4 1
Ok. Let's try the conditional or ||
, which should give the same result (||
should never change semantics, only computation efficiency, except in the border case of partial function etc.):
> as_tibble(mtcars) %>% filter(between(hp,50,70) || between(hp,80,90))
# A tibble: 0 x 11
# … with 11 variables: mpg <dbl>, cyl <dbl>, disp <dbl>, hp <dbl>, drat <dbl>, ...
# carb <dbl>
What is this weirdness? between(hp,50,70) || between(hp,80,90)
yields TRUE nowhere?
Upvotes: 6
Views: 341
Reputation: 11898
The ||
operator only compares the first elements of vectors, and returns a single logical result, while |
compares vectors elementwise, and returns a vector result. See, e.g.:
x <- c(FALSE, TRUE)
y <- c(FALSE, FALSE)
x | y
#> [1] FALSE TRUE
x || y
#> [1] FALSE
This is actually also mentioned in the help text you quoted: “The longer form evaluates left to right examining only the first element of each vector.” [emphasis added]
Created on 2019-10-15 by the reprex package (v0.3.0)
Upvotes: 4