R Logical Operators

Logical operators combine or invert TRUE/FALSE values, and R makes an important distinction between the element-wise & and | and the single-value && and ||.

AND, OR, and NOT

! flips a logical value, & requires both sides to be TRUE, and | requires at least one side to be TRUE. These building blocks let you combine multiple conditions into a single test.

OperatorMeaningExample
!NOT — flips TRUE to FALSE and back!TRUE
&Element-wise ANDc(TRUE, FALSE) & c(TRUE, TRUE)
|Element-wise ORc(TRUE, FALSE) | c(FALSE, FALSE)
&&Single-value AND (short-circuit)TRUE && FALSE
||Single-value OR (short-circuit)TRUE || FALSE

Basic Logic

!TRUE
TRUE & FALSE
TRUE | FALSE

Element-wise vs Single-Value Operators

& and | compare every element of two vectors and return a vector of results, which is exactly what you want when filtering rows of data. && and || instead look only at the first element of each side and return one single TRUE or FALSE, which is what if() and while() expect their condition to be.

Vector vs Single Comparison

x <- c(TRUE, FALSE, TRUE)
y <- c(TRUE, TRUE, FALSE)
x & y
x[1] && y[1]

Short-Circuit Evaluation

&& and || are short-circuiting: && stops as soon as it hits a FALSE, and || stops as soon as it hits a TRUE, without even looking at the right-hand side. This is more than an optimization — it lets you safely guard a risky check behind a simpler one.

Using Short-Circuiting Safely

v <- c()
if (length(v) > 0 && v[1] == 5) {
  print("match")
} else {
  print("no match or empty vector")
}
Note: Use && and || inside if() and while() conditions, and reserve & and | for combining logical vectors when filtering data. As of recent R versions, passing a vector longer than one to & or | inside if() is an error rather than just a warning — another reason to keep the two families of operators for their intended jobs.

Exercise: R Operators

What does the %% operator return in R?