There are only two logical values, `TRUE`

and `FALSE`

. They can be interpreted as yes/no, on/off, satisfied/not satisfied, or any option corresponding to a binary choice. In R, if desired, we can abbreviate `TRUE`

with `T`

and `FALSE`

with `F`

.

Logicals often indicate if a given condition is true or false. For example, a logical could characterize whether or not for a given car, its miles per gallon is greater than eighteen. If we suppose that the miles per gallon for a given car has been stored in a one-element vector named `mpg`

, we could write this condition as `mpg > 18`

. As such, depending on the value of `mpg`

, the expression `mpg > 18`

will evaluate to either a `TRUE`

or a `FALSE`

. Similar to how "`+`

", "`-`

","`*`

", and "`/`

" are all considered to be **arithmetic operators** as they combine two given numerical values and produce a numerical value, we call "`>`

" a **relational operator**, because it combines two numerical values and produces a logical value.

The table below summarizes some of the relational operators available for use in R:

operator | interpretation |
---|---|

`==` | Equal to |

`!=` | Not equal to |

`>` | Greater than |

`<` | Less than |

`<=` | Less than or equal to |

`>=` | Greater than or equal to |

How these relational operators work should not be terribly surprising, but the below gives some examples of their use:

> a = 1 > b = 2 > b >= a [1] TRUE > c(1,2,3,4,5) < c(5,4,3,2,1) [1] TRUE TRUE FALSE FALSE FALSE > c(1,2,3,4,5) == c(5,4,3,2,1) [1] FALSE FALSE TRUE FALSE FALSE

One can also combine logical values to produce other logical values. Not surprisingly, operators that do this are called **logical operators**. The table below summarizes some of these operators.

operator | interpretation | results |
---|---|---|

`!` | NOT | `! TRUE == FALSE` `! FALSE == TRUE` |

`&` | AND (element-wise) |
`TRUE & TRUE == TRUE` `TRUE & FALSE == FALSE` `FALSE & TRUE == FALSE` `FALSE & FALSE == FALSE` |

`&&` | AND (single comparison) |
Same as `&` above |

`|` | OR (element-wise) |
`TRUE | TRUE == TRUE` `TRUE | FALSE == TRUE` `FALSE | TRUE == TRUE` `FALSE | FALSE == FALSE` |

`||` | OR (single comparison) |
Same as `|` above |

The difference between element-wise and single comparison can be seen in the examples below. The former results in a vector of logical values -- one for each pair of logicals combined. The latter compares only the first two elements of the vectors involved, and consequently returns a single logical value.

> c(TRUE,TRUE,FALSE,FALSE) | c(TRUE,FALSE,FALSE,TRUE) [1] TRUE TRUE FALSE TRUE > c(TRUE,TRUE,FALSE,FALSE) || c(TRUE,FALSE,FALSE,TRUE) [1] TRUE

There are many functions that produce logical values or vectors of logical values as well.

To decide if a vector of logical values contains any `TRUE`

values, we can use the `any()`

function:

> v = c(FALSE, FALSE, FALSE, TRUE, TRUE, FALSE) > any(v) [1] TRUE > w = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) > any(w) [1] FALSE

To decide if all of the logical values contained by a vector are true, we can use the `all()`

function:

> v = c(FALSE, FALSE, FALSE, TRUE, TRUE, FALSE) > all(v) [1] FALSE > w = c(TRUE, TRUE, TRUE, TRUE) > all(w) [1] TRUE

To decide if any element in a vector is a duplicate of an earlier element in that vector, one can use the `duplicated`

function:

> duplicated(c(1,3,5,5,7,2,3)) [1] FALSE FALSE FALSE TRUE FALSE FALSE TRUE

Usefully, `TRUE`

and `FALSE`

are associated with the numerical values of $1$ and $0$. As such, summing a bunch of `TRUE/FALSE`

"values" gives the number of `TRUE`

values present. This can be very helpful in counting elements of a vector with a given property. For example, to count how many values have duplicates in a vector we might use something similar to the following:

> sum(duplicated(c(1,3,5,5,7,2,3))) [1] 2

One of the more important aspects of logical values in R lies in their ability to be used to subset elements. For example, suppose you had a vector of data values and you wanted to throw out any values greater than 10 or less than 5. With this in mind, consider the following:

> data = c(2,3,6,6,9,8,7,1,3,7,6,9,5,10,10,12,4,5,6,0,19) > dataAfterRemoval = data[(data >= 5) & (data <= 10)] > dataAfterRemoval [1] 6 6 9 8 7 7 6 9 5 10 10 5 6

Related to this, you can also ask R which elements of a given vector adhere to a given condition using the `which()`

function, as the next example demonstrates:

> data = c(2,3,6,6,9,8,7,1,3,7,6,9,5,10,10,12,4,5,6,0,19) > positionsOfThoseLessThanFive = which(data<5) [1] 1 2 8 9 17 20

One condition in which we are often interested is whether a given value is contained in a given vector. The `%in%`

operator makes this condition easy to check as demonstrated below:

> v = c(1,3,5,7,9) > 3 %in% v [1] TRUE > 4 %in% v [1] FALSE

The other really big application of logical values is related to their use in conditional statements. We delay the full discussion of conditional statements for the moment, but give an example of $\textrm{ifelse}(v, x, y)$, a related function.
This function results in a vector the same length as $v$, whose $i^{th}$ element is determined by $x$ if the $i^{th}$ element of $v$ is `TRUE`

, and by $y$ otherwise.

As an example, consider the following (recall that `a %% 2`

is the remainder upon division of $a$ by $2$, so the condition seen below of `a %% 2 == 0`

is `TRUE`

when $a$ is even and `FALSE`

otherwise).

> a = c(1,2,3,4,5,6,7,8,9) > ifelse(a %% 2 == 0, a / 2, 3*a+1) [1] 4 1 10 2 16 3 22 4 28