> 3 & 0
1] FALSE [
Logical operators
1 The functions
Here, we have to use logical operators to combine different filter conditions:
X & Y
: this meansX
andY
are both trueX && Y
: this meansX
andY
are both true, but ifX
isFALSE
, then R won’t evaluateY
; this is called short-circuited evaluation, and it can be very usefulX | Y
: this means eitherX
orY
or both are trueX || Y
: this means eitherX
orY
or both are true, but ifX
isTRUE
, then R won’t evaluateY
; as you might guess, this is also called short-circuit evaluationany(aVector)
: this means if any term inaVector
isTRUE
, then this isTRUE
all(aVector)
: this means for this to be true, then all terms inaVector
must be trueaValue %in% aVector
: this returnsTRUE
ifaValue
is one of the terms withinaVector
2 Examples
Now, let’s take a look at some examples of how we might use these logical operators in conjunction with the comparison operators above. We continue to use the variables that we defined above.
First, let’s look at these most basic logical operators:
Okay, that was simple: “are both 3
and 0
true? And then answer is no since 0
is false. The only way for x & y
to be true is for every single argument to be true.
Here are a couple more examples:
> 3 | 0
1] TRUE
[> 3 || 0
1] TRUE [
Recall, from our previous definitions, that 0
is equivalent to FALSE
and all other numerical values are equivalent to TRUE
. Thus, these examples (both of which can be translated as is 3 or 0 true?) must be TRUE
(since 3
is true). The difference between the two is that the second one is more computationally efficient since it stops evaluating after it sees that the first argument, 3
, is true.
The any()
function is equivalent to the or
operator. This checks if any of the arguments to the function are true; if so, then it returns TRUE
:
> any(3, 0)
1] TRUE
[:
Warning messageany(3, 0) : coercing argument of type 'double' to logical In
Notice this warning message. The function is still returning a value but R is telling you that it has had to coerce an argument from type double
to type logical
. That’s fine, and what we expected. It also does so if the argument to any()
is either a vector or a list:
> any(c(3, 0))
1] TRUE
[:
Warning messageany(c(3, 0)) : coercing argument of type 'double' to logical
In > any(list(3, 0))
1] TRUE
[:
Warning messageany(list(3, 0)) : coercing argument of type 'list' to logical In
However, what if we don’t want it to print out this warning message? Well, you can get rid of this message by surrounding the function with the suppressWarnings()
function, as this shows:
> suppressWarnings(any(3, 0))
1] TRUE [
It returns the value from any()
as before, but now it does not print out the warning.
Now, let’s look at the all()
function. This reports on whether or not all of its arguments are true:
> all(3, 2, 5, 3, 1, 0)
1] FALSE
[:
Warning messages1: In all(3, 2, 5, 3, 1, 0) :
'double' to logical
coercing argument of type 2: In all(3, 2, 5, 3, 1, 0) :
'double' to logical
coercing argument of type 3: In all(3, 2, 5, 3, 1, 0) :
'double' to logical
coercing argument of type 4: In all(3, 2, 5, 3, 1, 0) :
'double' to logical
coercing argument of type 5: In all(3, 2, 5, 3, 1, 0) :
'double' to logical
coercing argument of type 6: In all(3, 2, 5, 3, 1, 0) :
'double' to logical coercing argument of type
Note a couple of things:
- It returns
FALSE
because the last argument,0
, is false. The functionall()
, again, only returnsTRUE
if every argument is true. - Six separate warnings are returned because all six arguments are of type
double
, and each of them has to be coerced to typelogical
.
As before, we can use the suppressWarnings()
function to stop R from showing the warning messages:
> suppressWarnings(all(3, 2, 5, 3, 1, 0))
1] FALSE [
The following are examples of how to use the %in%
operator that tests if a value can be found in a vector or list:
> "Dave" %in% names
1] TRUE
[> "Melinda" %in% names
1] FALSE [
One nice feature of R is that you can also test if a vector or list of values can be found in a vector or list. For example:
> c("Scott", "Melinda") %in% names
1] TRUE FALSE [
The following is a nice example of the power of the composition of functions in R. Here we count (using sum()
) the number of values in the list()
are found in names
:
> sum(list("Dave", "Scott", "Melinda") %in% names)
1] 2 [
We can see that two of the items in the list()
that are found in names
.
You can also use either any()
or all()
on an existing variable (in this case vals
):
> any(vals)
1] TRUE
[:
Warning messageany(vals) : coercing argument of type 'double' to logical
In > all(vals)
1] FALSE
[:
Warning messageall(vals) : coercing argument of type 'double' to logical In
As before, you can use suppressWarnings()
to stop R from displaying warning messages:
> suppressWarnings(any(vals))
1] TRUE [
Finally, here are a few examples that demonstrate the or operators. Recall that 900 >= min_score
is FALSE
while "Lindsey" %in% names
is TRUE
. Thus, in the first statement, R determines that it is equivalent to FALSE | TRUE
which is TRUE
. In the second statement, R determines that the first clause is FALSE
, and then it evaluates the second clause to be TRUE
, and thus it returns TRUE
; this is the short-circuit form of or so it will stop evaluating the statement as soon as it determines the answer.
> 900 >= min_score | "Lindsey" %in% names
1] TRUE
[> 900 >= min_score || "Lindsey" %in% names
1] TRUE [
In this statement, once it evaluates the first clause to be TRUE
, it stops evaluating and returns TRUE
:
> "Lindsey" %in% names || 900 >= min_score
1] TRUE [
Clearly, the computational savings of this is quite minimal, but the benefit would accrue over multiple terms and millions of repetitions.