I hope the question is not too foolish.
Is there a built-in R function that returns TRUE when all the cases are FALSE?
Similar to any() or all() but when, in the case of a logical vector of 2, TRUE TRUE returns FALSE, TRUE FALSE returns FALSE and FALSE FALSE returns TRUE.
I would call it none().
We can use ! with any
!any(c(FALSE, FALSE))
Negate(any) ?
> none <- Negate(any)
> none(c(TRUE,TRUE))
[1] FALSE
> none(c(TRUE,FALSE))
[1] FALSE
> none(c(FALSE,FALSE))
[1] TRUE
Or all:
all(!vec)
Or using sum:
sum(vec)==0
where vec is your vector.
Related
How could I get a single boolean value that is TRUE if all values in vector are TRUE and FALSE otherwise? For instance:
> grepl("ABC",c("ABC","ABC","123ABC"))
[1] TRUE TRUE TRUE
my desired result:
[1] TRUE
Another example:
> grepl("ABC",c("ABC","ABC","123ABA"))
[1] TRUE TRUE FALSE
my desired result:
[1] FALSE
I know that it could be possibly solved with FOR loop, but this would be a time consuming method. Perhaps there is another, ready and simple solution. Please advise.
Use all :
all(grepl("ABC",c("ABC","ABC","123ABC")))
#[1] TRUE
all(grepl("ABC",c("ABC","ABC","123ABA")))
#[1] FALSE
drives_DF$block_device == ""
[1] TRUE TRUE TRUE FALSE TRUE
How do I reduce this down to a single FALSE like doing an AND() in Excel?
How do I reduce this down to a single TRUE like doing an OR() in Excel?
Wrapping your code with all() will return TRUE if all evaluated elements are TRUE
all(drives_DF$block_device == "")
[1] FALSE
Wrapping your code with any() will return TRUE if at least one of the evaluated elements is TRUE
any(drives_DF$block_device == "")
[1] TRUE
You can use any and all functions available in R to get the required like this:
#Considering a vector of boolean values
boolVector = c(F,T,F,T,F)
print(all(boolVector, na.rm = FALSE)) #AND OPERATION
print(any(boolVector, na.rm = FALSE)) #OR OPERATION
The output of the print statements are:
[1] FALSE
[1] TRUE
I'm trying to understand the ! operator better in R, and I'm confused as to how it applies to numbers. What does the following code signify, and why are the two equality queries not the same?
> !5 == 7
[1] TRUE
> 5 == !7
[1] FALSE
> !5
[1] FALSE
Thanks!
First of all: the ! operator coerces non-logicals to logical, then reverses them. Anything other than 0 evaluates to a logical TRUE, then the ! operator flips it to FALSE
The rest has to do with order of operations.
!5 == 7
Evaluates to
!(5==7)
Which is equivalent to
!(FALSE)
Which returns TRUE
Whereas
5 == !7
Evaluates to
5 == FALSE
Which returns FALSE
The equivalent to 5 == !7 would be (!5) == 7 (Both return FALSE)
The ! coerces its argument to a logical, thus:
as.logical(-3L:3L)
# [1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE
as.logical(seq(-2,2, by = 0.5))
# [1] TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE
As you can see, 0 is FALSE, everything else is TRUE.
To get an even better sense of this, see that ! is - like everything in R - a function:
> `!`
function (x) .Primitive("!")
So, you're applying the ! function to numeric arguments, which are coerced to logical, as above.
When you compare a logical to a numeric value using ==, the numeric value is also coerced to logical.
In your first example (!5 == 7) is due to precedence ordering; == is higher precedence than !.
When passing only a single vector to the logical and/or operator, the operator negates the argument:
> x = c(F,T,T)
> `&`(x)
[1] TRUE FALSE FALSE
> `|`(x)
[1] TRUE FALSE FALSE
To make the logical operator work as idempotent, one needs to pass a single element vector as the second argument:
> `&`(x,T)
[1] FALSE TRUE TRUE
> `|`(x,F)
[1] FALSE TRUE TRUE
Why do the logical operators negate their argument when there is only one argument passed?
This was modified in R 3.2.1 as a result of a bug report. As you've pointed out, the previous behavior made little sense:
If there are multiple boolean expressions as arguments to the which function, are they evaluated lazily?
For example:
which(test1 & test2)
If test1 returns false, then test2 is not evaluated as the compound expression will be false anyway.
With if there can be efficiency gains as a result of that behavior. It is documented to work that way, and I don't think it is due to lazy evaluation. Even if you "force()-ed" that expression it would still only evaluate a series of &'s until it had a single FALSE. See this help page:
?Logic
#XuWang probably deserved the credit for emphasizing the difference between "&" and "&&". The "&" operator works on vectors and returns vectors. The "&&" operator acts on scalars (actually vectors of length==1) and returns a vector of length== 1. When offered a vector or length >1 as either side of the arguments, it will work on only the information in the first value of each and emit a warning. It is only the "&&" version that does what is being called "lazy" evaluation. You can see that hte "&" operator is not acting in a "lazy fashion with a simepl test:
fn1 <- function(x) print(x)
fn2 <- function(x) print(x)
x1 <- sample(c(TRUE, FALSE), 10, replace=TRUE)
fn1(x1) & fn2(x1) # the first two indicate evaluation of both sides regardless of first value
# [1] FALSE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE
# [1] FALSE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE
# [1] FALSE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE