3.2 Logical vectors

So far we looked at integerand numeric vectors. In this section, we will take a closer look at logical vectors.

Logical vectors contain FALSE and TRUE values. We call FALSE and TRUE booleans (or bools), which is a data type that has only 2 values, i.e. false and true.

We can assign a bool to a variable just like before with numbers: a <- TRUE; b <- FALSE. However, logical vectors are usually generated through conditions. For example

> x <- 1 < 2
> x
[1] TRUE
> y <- 2 < 1
> y
[1] FALSE

sets x and y as a vector of length 1 with values FALSE corresponding where the condition is not met and TRUE where it is. Logical operators, <, <=, >, >=, == and !=, are used for such conditions:

> 1 < 2
[1] TRUE
> 1 <= 2
[1] TRUE
> 1 > 2
[1] FALSE
> 1 >= 2
[1] FALSE
> 1 == 2
[1] FALSE
> 1 != 2
[1] TRUE

Here, ==corresponds to “equal” and != corresponds to “not equal”. If you have not programmed before, you maybe find the use of == rather that = strange to test for equality. But in most programming languages the = is reserved for assignments - including in R even if its use is discouraged.

> a <- 5
> a == 7
[1] FALSE
> a = 7
> a
[1] 7

In addition, two logical vectors can be compared with the logical operators & (intersection, “and”), | (union, “or”) and ! (negation, “not”):

> x <- TRUE
> y <- FALSE
> x & y
[1] FALSE
> x | y
[1] TRUE
> !y
[1] TRUE

& returns true if both conditions are true; | returns true if at least one condition is true; and ! simply returns the opposite of the value.

Of course, a logical vector can have more than just one element. In this case, when comparing two logical vectors with & and |, comparison goes element-by-element.

> x <- 1:10 > 4
> x
 [1] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
> y <- 1:10 <= 6
> y
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
> x & y
 [1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
> x | y
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> !y
 [1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

You will sometimes encounter the logical operators && and ||. In the most recent R versions (> 4.3.0), && and || can only be used to compare a single element (a scalar), otherwise an error is thrown.

> x <- 1 > 4
> y <- 1 <= 6
> x && y
[1] FALSE
> x || y
[1] TRUE

We can use logical vectors for accessing elements of other vectors. Values corresponding to TRUE in the logical vector are selected and those corresponding to FALSE are omitted.

> x <- 1:5
> x[c(TRUE, FALSE, TRUE, FALSE, TRUE)]
[1] 1 3 5
> x[rep(c(TRUE, FALSE), length.out = 5)]
[1] 1 3 5

This is particularly helpful to select only elements matching a certain condition.

> x <- 1:10
> sum(x[x>5])
[1] 40

Logical vectors may also be turned into index vectors using the function which() that returns a vector of all indexes that are TRUE.

> x <- 1:20
> which(x %% 3 == 0)
[1]  3  6  9 12 15 18

To check if a certain value is present in a vector, the %in% operator can be used. It checks if the element on the left is present in the object on the right:

> x <- 1:20
> 5 %in% x
[1] TRUE
> 30 %in% x
[1] FALSE

The %in% operator can also evaluate multiple elements:

> x <- 1:20
> y <- c(3, 5, 18, 30)
> y %in% x
[1]  TRUE  TRUE  TRUE FALSE

This returns a logical vector with the same numbers of elements as the vector on the left, each of which indicating whether the element is present or absent in the vector on the right.

Finally, arithmetic functions can also be applied to logical vectors. In this case, logical vectors are coerced to integer vectors with FALSE interpreted as 0 and TRUE as 1.

> as.integer(c(FALSE, TRUE))
[1] 0 1
> x <- c(TRUE, FALSE, TRUE, FALSE, TRUE)
> y <- c(TRUE, TRUE, FALSE, FALSE, FALSE)
> x + y
[1] 2 1 1 0 1
> sum(x)
[1] 3

You can explicitly coerce vectors to type logical using the function as.logical that converts 0 to FALSEand all other values to TRUE.

> as.logical(-2:5)
[1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
> as.logical(c(0.0, 0.000001, 10000))
[1] FALSE  TRUE  TRUE

3.2.1 Exercises: Logical vectors

See Section 18.0.7 for solutions.

  1. Given x <- seq(-20, 20, length.out = 41) and y <- seq(-40, 40, length.out = 41), calculate the number of pairs(x[i], y[i]) where y[i] > x[i].

  2. Replace all even numbers of x by 1 (hint: use the modulus operator).

  3. Extract all elements of x that are larger or equal zero and are odd numbers.

  4. Extract all elements of x that are smaller than -10 or larger than 13.

  5. Use a logical vector to replace every fourth element of x by 1.