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 are`TRUE`

themselves.**OR Operator:**Denoted using the pike symbol, this operator takes two logical values and returns`TRUE`

if just one value is`TRUE`

.**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`

**:**Since`x`

is five, and`5 < 4`

is not true, this statement evaluates to`FALSE`

.`!(x < 4)`

**:**From the step above, we determined that`x < 4`

evaluates to`FALSE`

. Negating this result gives us`!FALSE`

, which is`TRUE`

.

Next, we have the right expression `!!!(y > 12)`

of the inner expression `(!(x < 4) & !!!(y > 12))`

.

`y > 12`

: Since`y`

is seven, and`7 > 12`

is not true, this expression evaluates to`FALSE`

.`!(y > 12)`

: Negating the result from step one, we get`!FALSE`

, or`TRUE`

.`!!(y > 12)`

: Negating the result from step two, we get`!TRUE`

, or`FALSE`

.`!!!(y > 12)`

: Negating the result from step three, we get`!FALSE`

, or`TRUE`

.

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.