IF, ELSE, ELSE IF Statement in R

โšก Smart Summary

If Else and Else If statements in R choose which block of code runs based on a logical condition. This walkthrough covers the two-branch form, multi-branch chains, the vectorized ifelse() function, and switch() for exact matches.

  • ๐Ÿ”€ Core Syntax: if (condition) { } else { } runs one branch when the test is TRUE and the other when it is FALSE.
  • ๐Ÿ”— Multiple Branches: R writes else if as two separate words; there is no elif keyword as in Python.
  • โš ๏ธ Boundary Care: Use greater-or-equal and less-or-equal so no value falls through an unintended gap between branches.
  • โšก Vectorized Form: ifelse(test, yes, no) evaluates a whole vector at once, which if cannot do.
  • ๐Ÿ—‚๏ธ Exact Matching: switch() replaces a long chain of equality tests with a single lookup.
  • ๐Ÿงฎ Operator Choice: Single ampersand works element-wise while the double form is for a single TRUE or FALSE inside if.

If Else Else If Statement in R

The if else Statement in R

An if else statement runs one block of code when a condition is TRUE and another when it is FALSE. In R the syntax is:

if (condition) {
    Expr1 
} else {
    Expr2
}

If Else Statement

Check whether a variable named quantity is above 20. If it is, the code prints “You sold a lot!”, otherwise it prints “Not enough for today”.

# Create vector quantity
quantity <-  25
# Set the if-else statement
if (quantity > 20) {
    print('You sold a lot!')
} else {
    print('Not enough for today')  
}

Output:

## [1] "You sold a lot!"

Note: indentation does not change how R runs the code, but consistent indentation is what keeps a long chain of conditions readable. Note also that the closing brace and the else keyword must sit on the same line, otherwise R treats the if block as complete and throws an error.

The else if Statement in R

Chain further tests with else if. R has no elif keyword, that is Python; in R you write the two words separately, and you can add as many branches as you need. The syntax is:

if (condition1) { 
    expr1
    } else if (condition2) {
    expr2
    } else if  (condition3) {
    expr3
    } else {
    expr4
}

Suppose you want three outcomes: below 20 prints “Not enough for today”, between 20 and 30 prints “Average day”, and above 30 prints “What a great day!”.

You can try to change the amount of quantity.

# Create the variable quantity
quantity <-  10
# Create multiple condition statement
if (quantity < 20) {
      print('Not enough for today')
} else if (quantity >= 20 & quantity <= 30) {
     print('Average day')
} else {
      print('What a great day!')
}

Output:

## [1] "Not enough for today"

Example 2:

VAT rates differ by product category. Imagine three categories, each with its own rate:

Categories Products VAT
A Book, magazine, newspaper, etc.. 8%
B Vegetable, meat, beverage, etc.. 10%
C Tee-shirt, jean, pant, etc.. 20%

An else if chain applies the correct rate to whatever the customer bought:

category <- 'A'
price <- 10
if (category =='A'){
  cat('A vat rate of 8% is applied.','The total price is',price *1.08)  
} else if (category =='B'){
    cat('A vat rate of 10% is applied.','The total price is',price *1.10)  
} else {
    cat('A vat rate of 20% is applied.','The total price is',price *1.20)  
}

Output:

## A vat rate of 8% is applied. The total price is 10.8

The ifelse() Vectorized Function in R

The if statement handles exactly one value. Give it a vector and R 4.2 or later raises an error, because the condition must be a single TRUE or FALSE. ifelse() solves this by testing every element at once and returning a vector of the same length.

quantities <- c(10, 25, 40, 18)

# if cannot do this
result <- ifelse(quantities > 20, 'You sold a lot!', 'Not enough for today')
result

Output:

## [1] "Not enough for today" "You sold a lot!"      "You sold a lot!"      
## [4] "Not enough for today"

The three arguments are the test, the value returned where the test is TRUE, and the value returned where it is FALSE. All three are recycled to the same length.

Nesting ifelse() reproduces an else if chain across a whole vector:

ifelse(quantities < 20, 'Not enough for today',
    ifelse(quantities <= 30, 'Average day', 'What a great day!'))

Two limits are worth knowing. ifelse() drops attributes such as factor levels and Date class from the result, and it evaluates both branches for every element, so it is wasteful when one branch is expensive. The dplyr alternative case_when() avoids the nesting entirely and keeps types intact:

library(dplyr)
case_when(
    quantities < 20  ~ 'Not enough for today',
    quantities <= 30 ~ 'Average day',
    TRUE             ~ 'What a great day!'
)

The switch() Statement in R

When every branch tests the same variable for equality, a long else if chain becomes hard to read. switch() replaces it with a single lookup.

category <- 'A'
price <- 10

vat <- switch(category,
    'A' = 1.08,
    'B' = 1.10,
    'C' = 1.20,
    1.20)          # the unnamed last value is the default

cat('The total price is', price * vat)

Three rules govern its behaviour:

  • With a character argument, switch() matches the name exactly. There is no partial matching and no pattern matching.
  • An unnamed final element acts as the default. Without one, an unmatched value returns NULL invisibly, which is a common source of silent bugs.
  • With an integer argument, switch() selects by position instead: switch(2, “a”, “b”, “c”) returns “b”.

Use switch() for exact matches against a fixed set of values, and keep else if for ranges and compound conditions, which switch() cannot express. To apply a condition repeatedly over a sequence, combine it with a for loop or a while loop.

Logical Operators in R Conditions

The operators that build a condition behave differently from one another, and the difference matters.

Operator Meaning Use it in
& Element-wise AND ifelse(), filter(), whole vectors
&& Single-value AND, short-circuits if () and while ()
| Element-wise OR ifelse(), filter(), whole vectors
|| Single-value OR, short-circuits if () and while ()
! NOT, negates the test Anywhere
%in% Is the value in this set? Replaces long OR chains

Why short-circuiting matters. The double form stops as soon as the answer is settled, so the right-hand side is never evaluated when the left already decides the outcome. That makes it safe to write a guard clause:

# Safe: length() is checked before x[1] is touched
if (length(x) > 0 && x[1] > 10) print('ok')

Comparing against several values. Reach for %in% rather than chaining equality tests, which is both shorter and harder to mistype:

if (category %in% c('A', 'B')) {
    print('Reduced VAT rate applies')
}

One final warning: a single equals sign assigns a value, it does not compare. Always write == inside a condition.

Conditional Statements in R: Quick Reference

Every construct used in this tutorial is listed below:

Objective Code
Two branches
if (cond) { a } else { b }
Multiple branches
if (c1) { a } else if (c2) { b } else { c }
Vectorized condition
ifelse(test, yes, no)
Multi-branch on a vector
case_when(c1 ~ a, c2 ~ b, TRUE ~ c)
Exact match lookup
switch(x, "A" = 1, "B" = 2, 0)
Membership test
if (x %in% c("A", "B")) { }

FAQs

if handles a single TRUE or FALSE and controls which block of code runs. ifelse() is a vectorized function that tests every element of a vector and returns a vector of results.

Use the double form inside if and while, where the condition must be one value and short-circuiting protects the right-hand side. Use the single form for element-wise tests on whole vectors.

Since R 4.2 an if condition must be exactly one TRUE or FALSE; longer vectors now raise an error rather than a warning. Use ifelse(), any(), or all() depending on what you meant.

Conditions drive feature engineering rules, early-stopping checks during training, and threshold decisions on model output. Vectorized forms such as case_when() are preferred because they scale to whole datasets.

Yes. AI assistants can spot gaps such as a boundary value falling through every branch, or a single equals sign used for comparison. Test the corrected chain on the boundary values yourself.

Summarize this post with: