2.4 More on Logical Vectors

Consider the following expression:

13 < 20
## [1] TRUE

We constructed it with the “less-than” operator <. You can think of it as saying that 13 is less than 20, which is a true statement, and sure enough, R evaluates the expression 13 < 20 as TRUE.

When you think about it, we’ve seen lots of expressions so far. Here are just a few of them:

  • sqrt(64)
  • heights
  • heights[1:3]
  • 13 < 20

When we type any one of them into the console, it evaluates to a particular value. In the examples above, the value was always a vector.

Expressions like 13 < 20 that evaluate to a logical vector are often called Boolean expressions.2

2.4.1 Boolean Operators

Let’s look further into Boolean expressions. Define the following two vectors:

a <- c(10, 13, 17)
b <- c(8, 15, 12)

Now let’s evaluate the expression a < b:

a < b
## [1] FALSE  TRUE FALSE

The < operator, when applied to vectors, always works element-wise; that is, it is applied to corresponding elements of the vectors on either side of it. R’s evaluation of a < b involves evaluation of the following three expressions:

  • 10 < 8 (evaluates to FALSE)
  • 13 < 15(evaluates to TRUE)
  • 17 < 12(evaluates to FALSE)

The result is a logical vector of length 3.

The < operator is an example of a Boolean operator in R. Table 2.4.1 shows the available Boolean operators.

Table 2.1: The Boolean Operators
Operation What It Means
< less than
> greater than
<= less than or equal to
>= greater than or equal to
== equal to
& and
| or
&& and (scalar version)
|| or (scalar version)
! not

2.4.1.1 Inequalities

The “numerical-looking operators” (<, <=, >, >=) have their usual meanings when one is working with numerical vectors3 When applied to character vectors they evaluate according to an alphabetical order:

a<- c("Dorothy", "toto", "Boq")
b <- c("tinman", "Toto", "2017")
a < b
## [1]  TRUE  TRUE FALSE

The reasons for the evaluation above are as follows:

  • D comes before t in the alphabet;
  • lowercase t comes before uppercase T, according to R;
  • characters for numbers come before letter-characters, according to R.

2.4.1.2 Equality

The equality (==) operator indicates whether the expressions being compared evaluate to the same value. Note that it’s made with two equal-signs, not one! It’s all about evaluation to the same value, not strict identity. The following examples will help to clarify this.

a <- c(Dorothy = 1,Toto = 2) # a named vector
b <- c(Glinda = 1, Tinman = 2)
a == b
## Dorothy    Toto 
##    TRUE    TRUE

(Note that the resulting logical vector inherits the names of a, the vector on the left.).

But a and b aren’t identical. We can see this because R has the function identical() to test for identity:

identical(a, b)
## [1] FALSE

Corresponding elements of a and b have the same values, but the two vectors don’t have the same set of names, so they aren’t considered identical.

Here’s another way to see that “evaluating to the same value” is not the same as “identity”:

TRUE == 1
## [1] TRUE

When TRUE (itself oftype logical) is being compared with something numerical (type integer or double) it is coerced into the numerical vector 1. (In the same situation FALSE would be coerced to 0.) But clearly TRUE and 1 are not identical:

identical(TRUE, 1)
## [1] FALSE

2.4.1.3 And, Or, Not

We consider an “and” statement to be true when both of its component statements are true; otherwise it is counted as false. The & Boolean operator accords with our thinking:

a <- c(TRUE, TRUE, FALSE, FALSE)
b <- c(TRUE, FALSE, TRUE, FALSE)
a & b
## [1]  TRUE FALSE FALSE FALSE

In logic and mathematics, an “or” statement is considered to be true when at least one of its component statements are true. (This is sometimes called the “inclusive” use of the term “or.”) R accords with this line of thinking:

a <- c(TRUE, TRUE, FALSE, FALSE)
b <- c(TRUE, FALSE, TRUE, FALSE)
a | b
## [1]  TRUE  TRUE  TRUE FALSE

The && and || operators follow the “and” and “or” logic respectively, but are applied only to the first elements of the vectors being compared:

a <- c(TRUE, TRUE)
b <- c(TRUE, TRUE)
a && b
## [1] TRUE
a <- c(TRUE, FALSE)
b <- c(FALSE, FALSE)
a || b
## [1] TRUE

These operators will come in handy later on, when we study conditionals.

The final Boolean operator is !, which works like “not”:

a <- c(TRUE, FALSE)
!a
## [1] FALSE  TRUE
e <- c(2, 5, 6)
f <-  c(3, 1, 2)
e > f
## [1] FALSE  TRUE  TRUE
!(e > f)
## [1]  TRUE FALSE FALSE

  1. So-called after George Boole, a nineteenth century British logician.↩︎

  2. A vector is said to be numerical if it is of type integer or double.↩︎