> 3 & 0
[1] FALSELogical operators
The functions
Here, we have to use logical operators to combine different filter conditions:
X & Y: this meansXandYare both trueX && Y: this meansXandYare both true, but ifXisFALSE, then R won’t evaluateY; this is called short-circuited evaluation, and it can be very usefulX | Y: this means eitherXorYor both are trueX || Y: this means eitherXorYor both are true, but ifXisTRUE, then R won’t evaluateY; as you might guess, this is also called short-circuit evaluationany(aVector): this means if any term inaVectorisTRUE, then this isTRUEall(aVector): this means for this to be true, then all terms inaVectormust be trueaValue %in% aVector: this returnsTRUEifaValueis one of the terms withinaVector
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] TRUERecall, 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 message:
In any(3, 0) : coercing argument of type 'double' to logicalNotice 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 message:
In any(c(3, 0)) : coercing argument of type 'double' to logical
> any(list(3, 0))
[1] TRUE
Warning message:
In any(list(3, 0)) : coercing argument of type 'list' to logicalHowever, 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] TRUEIt 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 messages:
1: In all(3, 2, 5, 3, 1, 0) :
coercing argument of type 'double' to logical
2: In all(3, 2, 5, 3, 1, 0) :
coercing argument of type 'double' to logical
3: In all(3, 2, 5, 3, 1, 0) :
coercing argument of type 'double' to logical
4: In all(3, 2, 5, 3, 1, 0) :
coercing argument of type 'double' to logical
5: In all(3, 2, 5, 3, 1, 0) :
coercing argument of type 'double' to logical
6: In all(3, 2, 5, 3, 1, 0) :
coercing argument of type 'double' to logicalNote a couple of things:
- It returns
FALSEbecause the last argument,0, is false. The functionall(), again, only returnsTRUEif 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] FALSEThe 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] FALSEOne 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 FALSEThe 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] 2We 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 message:
In any(vals) : coercing argument of type 'double' to logical
> all(vals)
[1] FALSE
Warning message:
In all(vals) : coercing argument of type 'double' to logicalAs before, you can use suppressWarnings() to stop R from displaying warning messages:
> suppressWarnings(any(vals))
[1] TRUEFinally, 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] TRUEIn this statement, once it evaluates the first clause to be TRUE, it stops evaluating and returns TRUE:
> "Lindsey" %in% names || 900 >= min_score
[1] TRUEClearly, the computational savings of this is quite minimal, but the benefit would accrue over multiple terms and millions of repetitions.