If I have a number of logical statements (logical vectors in general), like
x>1
y!=1
sin(x)<0
AND
AND(x>1, y!=1, sin(x)<0)
x>1 & y!=1 & sin(x)<0
As mentioned by @r2evans, if we only work with scalar rather than vector, we can use all
safely:
all(1 < 4, 5 > 7, 6 == 6)
My answer below addresses the case when you work with several logical vectors, and would like to take parallel / element-wise all
. As a reproducible example, suppose we have logical vectors:
set.seed(0)
a1 <- sample(c(TRUE, FALSE), 5, replace = TRUE)
# [1] FALSE TRUE TRUE FALSE FALSE
a2 <- sample(c(TRUE, FALSE), 5, replace = TRUE)
# [1] TRUE FALSE FALSE FALSE FALSE
a3 <- sample(c(TRUE, FALSE), 5, replace = TRUE)
# [1] TRUE TRUE TRUE FALSE TRUE
We aim for a solution that are not subject to the number of logical vectors.
Option 1
We can use Reduce
and "&"
:
## define a function
AND1 <- function (...) Reduce("&", list(...))
AND1(a1, a2, a3)
# [1] FALSE FALSE FALSE FALSE FALSE
The binary operator "&"
only works with two inputs, so we can do
"&"(a1, a2)
but not
"&"(a1, a2, a3)
Reduce
is here to help, by iteratively applying "&"
:
tmp <- "&"(a1, a2)
"&"(a2, a3)
The following two options first collect all logical vectors into a matrix. Then option 2a uses row-wise all
, while option 2b uses rowSums
.
Option 2a
AND2a <- function (...) {
X <- do.call(cbind, list(...))
base::apply(X, 1L, all)
}
AND2a (a1, a2, a3)
# [1] FALSE FALSE FALSE FALSE FALSE
Option 2b
AND2b <- function (...) {
X <- do.call(cbind, list(...))
## `TRUE` is 1 and `FALSE` is 0 when doing arithmetic sum
## all `TRUE` is as same as row sums equal to `ncol(X)` or `dim(X)[2]`
base::rowSums(X) == dim(X)[2L]
}
AND2b (a1, a2, a3)
# [1] FALSE FALSE FALSE FALSE FALSE