Suppose we want to change or compare the results of the comparisons made using relational operators. How would we go about doing that?
R does this using the AND, OR and NOT operators.
Logical Operators in R
- AND Operator: Represented using an ampersand, this operator takes two logical values and returns
TRUE
only if both values areTRUE
themselves. - OR Operator: Denoted using the pike symbol, this operator takes two logical values and returns
TRUE
if just one value isTRUE
. - NOT Operator: Represented using an exclamation mark, this operator negates the logical value it’s used on.
AND Operator “&”
The AND
operator takes two logical values and returns TRUE
only if both values are TRUE
themselves. This means that TRUE & TRUE
evaluates to TRUE
, but that FALSE & TRUE
, TRUE & FALSE
and FALSE & FALSE
evaluates to FALSE
.
Instead of using logical values, we can use the results of comparisons. Suppose we have a variable x
that is equal to 12. To check if this variable is greater than five but less than 15, we can use x
greater than five and x
less than 15.
x <- 12
x > 5 & x < 15
The first part, x > 5
, will evaluate to TRUE
because 12 is greater than five. The second part, x < 15
, will also evaluate to TRUE
because 12 is also less than 15. So, the result of this expression is TRUE
since TRUE & TRUE
is TRUE
. This makes sense, because 12 lies between five and 15.
However, if x
were 17, the expression x > 5 & x < 15
would simplify to TRUE & FALSE
, which would result in the expression being FALSE
.
AND Operator Example Problem
Consider the following vector and variable:
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
last <- tail(linkedin, 1)
The linkedin
vector represents the number of LinkedIn views your profile has gotten in the last seven days. The last variable represents the last
value of the linkedin
vector.
Determine whether the last
variable is between 15 and 20, excluding 15 but including 20.
Example 1 Solution
# We are looking for the R equivalent of 15 < last <= 20
last > 15 & last <= 20
AND Operator Example Problem 2
Consider the following vectors:
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)
The linkedin
vector represents the views on your LinkedIn profile from the past seven days, and the facebook
vector represents the views on your Facebook profile from the past seven days.
Determine when LinkedIn views
exceeded 10 and Facebook views failed to reach 10 for a particular day. Use the linkedin
and facebook
vectors.
Example 2 Solution
# linkedin exceeds 10 but facebook below 10
linkedin > 10 & facebook < 10
AND Operator Example Problem 3
Consider the following matrix:
views <- matrix(c(linkedin, facebook), nrow = 2, byrow = TRUE)
The linkedin
and facebook
variable corresponds to the same vectors in the previous example.
The first and second rows in the matrix views
corresponds to the linkedin
and facebook
vectors, respectively.
Determine when the views
matrix equals a number between 11 and 14, excluding 11 and including 14.
Example 3 Solution
# When is views between 11 (exclusive) and 14 (inclusive)?
views > 11 & views <= 14
OR Operator “|”
The OR operator |
works similarly to the AND operator &
, but the difference is that only one of the logical values needs to be equal to TRUE
for the entire OR operation to evaluate to TRUE
.
This means that TRUE | TRUE
equals TRUE
, but also, TRUE | FALSE
and FALSE | TRUE
evaluates to TRUE
. When both logicals are FALSE
in an OR operation, FALSE | FALSE
, the result is FALSE
. Remember, the OR operation is not an exclusive OR operation, so TRUE | TRUE
equals TRUE
as well.
With the AND operator, only TRUE & TRUE
makes a TRUE
, anything else is FALSE
. With the OR operator, only FALSE | FALSE
makes a FALSE
, anything else is TRUE
.
Just as in AND operations, we can use comparisons together with the OR operator. Suppose we have a variable y
that equals four. To see if this variable is less than five or greater than 15, we can use the following expression:
y <- 4
y < 5 | y > 15
R will first carry out the comparisons, resulting in TRUE | FALSE
, which in turn, results in TRUE
.
Now, suppose y
is 14. The expression y < 5 | y > 15
now evaluates to FALSE | FALSE
. Neither one of the comparisons are TRUE
, so the result is FALSE
.
OR Operator Example Problem 1
Using the same variables from the “AND operator example problem 3,” determine if last
is under five or above 10.
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
last <- tail(linkedin, 1)
Example 1 Solution
# Is last under 5 or above 10?
last < 5 | last > 10
OR Operator Example Problem 2
Consider the same linkedin
and facebook
vectors from the previous example.
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)
Determine when one or both social profiles were visited at least 12 times.
Example 2 Solution
# When were one or both visited at least 12 times?
linkedin >= 12 | facebook >= 12
NOT Operator “!”
The NOT operator, represented by an exclamation mark !
, simply negates the logical value it’s used on. That is, !TRUE
evaluates to FALSE
, while !FALSE
evaluates to TRUE
.
Just like the OR and AND operators, we can use the NOT operator in combination with logical operators. This is not always necessary. For example, !(x < 5)
is the same as x >= 5
.
However, there are cases in R where the NOT operator is especially handy. For example, the built-in R function, is.numeric()
checks if an R object is a numeric. There is no respective built-in function that checks if it isn’t a numeric. To check, we would have to negate the result (!is.numeric()
). So, is.numeric(5)
evaluates to TRUE
, as five is a numeric. If we negate this result using the NOT operator (!is.numeric(5)
), we get FALSE
. If, however, we use is.numeric("hello")
we get FALSE
. Negating this result (!is.numeric("hello")
) gives us TRUE
.
Logical Operators and Vectors
Now, how do logical operators work with vectors and matrices? Just as relational operators, they perform the operations element-wise. Consider theses two vectors:
c(TRUE, TRUE, FALSE) & c(TRUE, FALSE, FALSE)
The AND operation on these two vectors, results in a vector with the elements TRUE
, FALSE
and FALSE
.
TRUE FALSE FALSE
The first elements in both vectors are TRUE
, so the first element of the resulting vector contains TRUE
. The same holds true for the second elements, where TRUE & FALSE
result in FALSE
, and in the third elements, where FALSE & FALSE
give FALSE
.
A similar thing happens with the OR operator:
c(TRUE, TRUE, FALSE) | c(TRUE, FALSE, FALSE)
TRUE | TRUE
gives TRUE, TRUE | FALSE
also gives TRUE
, and FALSE | FALSE
gives FALSE
. So, we would get the result:
TRUE TRUE FALSE
The NOT operator also works on every element on the vector:
!c(TRUE, TRUE, FALSE)
TRUE
are converted to FALSE
, and FALSE
are converted to TRUE
. So, we would get the result:
FALSE FALSE TRUE
Logical Operators and Vectors Example Problem
What would the following set of R expressions return:
x <- 5
y <- 7
!(!(x < 4) & !!!(y > 12))
Solution
FALSE
To find the answer, it’s helpful to break the query down to smaller expressions.
We first have the left expression !(x < 4)
of the inner expression (!(x < 4) & !!!(y > 12))
.
x < 4
: Sincex
is five, and5 < 4
is not true, this statement evaluates toFALSE
.!(x < 4)
: From the step above, we determined thatx < 4
evaluates toFALSE
. Negating this result gives us!FALSE
, which isTRUE
.
Next, we have the right expression !!!(y > 12)
of the inner expression (!(x < 4) & !!!(y > 12))
.
y > 12
: Sincey
is seven, and7 > 12
is not true, this expression evaluates toFALSE
.!(y > 12)
: Negating the result from step one, we get!FALSE
, orTRUE
.!!(y > 12)
: Negating the result from step two, we get!TRUE
, orFALSE
.!!!(y > 12)
: Negating the result from step three, we get!FALSE
, orTRUE
.
So, for the inner expression (!(x < 4) & !!!(y > 12))
, it evaluates to TRUE & TRUE
, which equals TRUE
.
The outer NOT operator !
negates this TRUE
making !(!(x < 4) & !!!(y > 12))
equal to !TRUE
or FALSE
.
Single vs. Double Operators “&” vs “&&”, “|” vs “||”
What is the difference between a single and a double ampersand or vertical bar? In R, you can use both the single sign version or the double sign version, but the result of the logical operation you’re carrying out can be different. The biggest difference occurs when you use the two types of operations on vectors.
c(TRUE, TRUE, FALSE) & c(TRUE, FALSE, FALSE)
As we’ve seen before, the above expression evaluates to a vector:
TRUE FALSE FALSE
However, if we use &&
, we simply get TRUE
.
c(TRUE, TRUE, FALSE) && c(TRUE, FALSE, FALSE)
This is because the double AND operation only examines the first element of each vector. In this case, the first elements are TRUE
and TRUE
, so the expression returns TRUE
.
You can see similar things happening with the OR operator. The single sign version |
returns an entire vector. The double sign version ||
returns the result of the OR operator on the first element of each vector.
So pay attention when doing logical operations on vectors. You will likely want to use the single sign version for most actions.