R: R Control Flow
Last updated: 2026-08-26
In the previous lesson, we learned about operators, and our R programs can now "determine whether something is true or false." But simply being able to make such determinations isn't enough—programs also need to be able to repeat tasks (loops) and make branching decisions (conditions). In this lesson, we'll learn about "control flow" in R: if/else conditions, for/while loops, and the repeat statement.
Control flow in R is a bit different from Python: R encloses code blocks in {} (instead of using indentation), and the entire if/else statement is a single expression. In this lesson, we’ll learn these differences.
1. What You'll Learn
- if / else / else if conditional branching
- Use a for loop to iterate through a vector or list
- while loop
- repeat: infinite loop (use break to exit)
- ifelse() vectorized conditional evaluation
- next: Skip this round; break: Exit the loop
- Key Differences in Control Flow Between R and Python
2. A Story About Data Filtering
(1) Pain Point: Manual Categorization
Xiao Zhao is a data analyst. His manager asked him to segment 100 customers by age:
- Under 18: Minors
- Ages 18–30: Young adults
- Ages 31–50: Middle-aged
- 51 years of age and older: elderly
If you use Excel, you’d have to write four nested IF formulas; if you use Python, you’d have to write loops and if-else statements. But R has ifelse(), which is specifically designed for vectors—
(2) Solution using R
# 5 The age of each customer
ages <- c(15, 22, 35, 50, 65)
# Done in one line of code 4 File Categories(Vectorization ifelse)
labels <- ifelse(ages < 18, "Minor",
ifelse(ages < 31, "Youth",
ifelse(ages < 51, "Middle Age", "Old Age")))
cat("Customer Segmentation:\n")
print(data.frame(Age = ages, Category = labels))
Solve a 4-class classification problem with just 3 lines of code. This is the "vectorized" advantage of R's control flow—in short, a single statement is a decision vector.
3. if/else: Conditional Branching
(1) Basic Syntax of the if Statement
# R uses { } to enclose a code block (Python uses indentation)
if (Conditions) {
Execute when the condition is true
}
age <- 18
if (age >= 18) {
cat("You're an adult now.\n")
}
# Output:You're an adult now.
(2) if-else: Binary Choice
if (Conditions) {
Execute when the condition is true
} else {
Execute when the condition is false
}
score <- 45
if (score >= 60) {
cat("Passed!\n")
} else {
cat("Fail,Need to take a makeup exam\n")
}
# Output:Fail,Need to take a makeup exam
(3) if-else if-else: Multi-branch
if (Conditions1) {
Branch1
} else if (Conditions2) {
Branch2
} else {
Other
}
score <- 85
if (score >= 90) {
cat("Excellent\n")
} else if (score >= 80) {
cat("Good\n")
} else if (score >= 60) {
cat("Passing Grade\n")
} else {
cat("Fail\n")
}
# Output:Good
(4) Key Differences Between R and Python
| Feature | R | Python |
|---|---|---|
| Code block | {} Curly braces |
Indentation (4 spaces) |
| if syntax | if (x > 0) { ... } |
if x > 0: |
| Overall Expression | if/else is an expression (assignable) | if/else is a statement (not assignable) |
| Ternary Operations | ifelse() Special Functions |
x if x > 0 else -x |
# R Special Usage of:ifelse It is an expression
result <- if (score >= 60) "Passing Grade" else "Fail"
result
# [1] "Passing Grade"
else on the same line (if treated as a single expression). If it is split across two lines, R will report a syntax error.
4. ifelse(): Vectorized Decision-Making
(1) Why do we need ifelse()?
The standard if can only evaluate a single value, but in R, you often need to evaluate an entire vector. In that case, use ifelse():
graph LR
A["x = 1, 2, 3, 4, 5"] --> B["ifelse x > 3 yes no"]
B --> C["no no no yes yes"]
style A fill:#cce5ff
style C fill:#d4edda
# Regular if It will throw an error(Only accept lengths 1)
x <- c(1, 2, 3, 4, 5)
if (x > 3) "L" else "S" # Error: condition has length > 1
# Use ifelse() to resolve
ifelse(x > 3, "L", "S")
# [1] "S" "S" "S" "L" "L"
(2) ifelse() Syntax
ifelse(Conditions, The value when the condition is true, Value when the condition is false)
(3) Nested ifelse(): Multi-level Classification
ages <- c(15, 22, 35, 50, 65)
# 4 File Categories
labels <- ifelse(ages < 18, "Minor",
ifelse(ages < 31, "Youth",
ifelse(ages < 51, "Middle Age", "Old Age")))
print(data.frame(Age = ages, Category = labels))
Output:
Age Category
1 15 Minor
2 22 Youth
3 35 Middle Age
4 50 Middle Age
5 65 Old Age
ifelse() If you have more than 3 levels of nesting, we recommend using dplyr::case_when() (covered in Lesson 10) for greater clarity.
5. for Loop: Iterating Through Elements
(1) Basic Syntax of the "for" Loop
for (Variable in Vector) {
Code executed in each iteration
}
(2) Iterating Through a Vector
# Iteration 1:5
for (i in 1:5) {
cat("Iteration", i, "of the loop\n")
}
# Output:
# Iteration 1 of the loop
# Iteration 2 of the loop
# Iteration 3 of the loop
# Iteration 4 of the loop
# Iteration 5 of the loop
# Iterating Through a Character Vector
fruits <- c("Apple", "Banana", "Cherries")
for (fruit in fruits) {
cat("I like to eat", fruit, "\n")
}
(3) Cumulative Sum (Classic Example)
# 1+2+3+...+100
total <- 0
for (i in 1:100) {
total <- total + i
}
total
# [1] 5050
(4) ⚠️ R has poor performance in loops
R's for loops are 10 to 100 times slower than Python's. R encourages the use of vectorized operations instead of loops:
# Slow (Loop)
system.time({
total <- 0
for (i in 1:1e6) {
total <- total + i
}
})
# User System Passing
# 0.40 0.00 0.40 ← 0.4 s
# Fast (Vectorization)
system.time({
total <- sum(1:1e6)
})
# User System Passing
# 0.01 0.00 0.01 <- 0.01 s (40x faster)
sum() mean() ifelse(), don't write a loop.
6. while Loop: Conditional Loop
(1) while Syntax
while (Conditions) {
Execute repeatedly when the condition is true
}
(2) Classic Example: The "Guess the Number" Game
# Target Number
target <- 42
guess <- 0
attempts <- 0
while (guess != target) {
guess <- sample(1:100, 1) # Guess at Random
attempts <- attempts + 1
if (attempts > 1000) break # More than 1000 Second attempt
}
cat("Used", attempts, "Second guess\n")
(3) Differences from for
| Feature | for | while |
|---|---|---|
| Purpose | Loops with a known number of iterations | Unknown number of iterations, triggered by conditions |
| Termination | End of vector traversal | Termination due to false condition |
| Applicable | Iterate through data | Wait for events, polling |
7. repeat and break: Infinite Loops
(1) repeat Syntax
repeat {
Code
if (Conditions) break # Must have break,Otherwise, an infinite loop
}
(2) Hands-On: Menu Selection
choice <- 0
repeat {
cat("\n=== Main Menu ===\n")
cat("1. Check the weather\n")
cat("2. Look up stocks\n")
cat("0. Exit\n")
choice <- as.integer(readline("Please select:"))
if (choice == 0) {
cat("Goodbye!\n")
break
} else if (choice == 1) {
cat("It's sunny today,25°C\n")
} else if (choice == 2) {
cat("Shanghai Stock Exchange 3000 pt\n")
} else {
cat("Invalid input\n")
}
}
repeat must be used in conjunction with break; otherwise, an infinite loop will occur (the program will hang).
8. next and break: Loop Control
| Keyword | Function | Scenario |
|---|---|---|
next |
Skip this round and proceed to the next | Skip certain items |
break |
Exit the entire loop | Exit immediately upon finding the target |
# next:Skip even numbers
for (i in 1:10) {
if (i %% 2 == 0) next
cat(i, " ")
}
# Output:1 3 5 7 9
cat("\n")
# break:Find the first one 7 Just log out
for (i in 1:10) {
if (i == 7) break
cat(i, " ")
}
# Output:1 2 3 4 5 6
9. Common Pitfalls
(1) Pitfalls of Floating-Point Comparisons
# Seemingly equal,The actual values are not equal
0.1 + 0.2 == 0.3
# [1] FALSE ← Actually, it is 0.30000000000000004
# The Correct Way to Do It:Comparison of Tolerances
abs(0.1 + 0.2 - 0.3) < 1e-9
# [1] TRUE
(2) The else statement must be on a new line or on the same line
# ❌ Error:else Traveling Alone
if (TRUE) {
cat("yes")
}
else {
cat("no")
}
# Error: unexpected 'else' in "else"
# Correct: else must follow if block }
if (TRUE) {
cat("yes")
} else {
cat("no")
}
# Output:yes
} else { on the same line to avoid parsing ambiguities.
(3) if does not print automatically
# In R, if has no "Automatic Printing" (Not like a function call)
if (TRUE) "yes"
# No output ← Do not print
# Resolve: Use cat() or print() for explicit output
if (TRUE) cat("yes\n")
# Output:yes
10. Complete Example: Customer Tier Management
Below is an example of a complete workflow that ties together all the control flows from this lesson.
▶ Example: Customer Segmentation and Marketing Strategies
# ============================================
# Customer Segmentation and Marketing Strategies
# Features:By age+Classify Customers by Spending Amount
# ============================================
# 1. Preparation 6 Customer Data
customers <- data.frame(
name = c("Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"),
age = c(15, 22, 35, 50, 65, 28),
spend = c(100, 500, 2000, 5000, 10000, 800)
)
# 2. Use ifelse() Batch Grading (Vectorization)
customers$tier <- ifelse(customers$spend < 500, "Regular",
ifelse(customers$spend < 3000, "Silver Card",
ifelse(customers$spend < 8000, "Gold Card", "Diamond")))
# 3. Go through the customer list,Output Marketing Strategy(for Loop)
cat("=== Customer Segmentation and Marketing Strategies ===\n\n")
for (i in 1:nrow(customers)) {
name <- customers$name[i]
age <- customers$age[i]
spend <- customers$spend[i]
tier <- customers$tier[i]
# Skip Diamond Members(Optimized)
if (tier == "Diamond") {
cat(name, "(", tier, "):", spend, "USD,Existing Customers,Priority Maintenance\n")
next
}
# Exit Conditions(Demo break)
if (spend > 5000) {
cat(name, ": High-spending customers! Enter VIP Process\n")
}
# Age-Based Marketing Recommendations
if (age < 18) {
cat(name, "(", tier, "):Minor,Recommended Parent Card\n")
} else if (age < 30) {
cat(name, "(", tier, "):Youth,New Product Releases\n")
} else if (age < 50) {
cat(name, "(", tier, "):Middle Age,Promote Family Plans\n")
} else {
cat(name, "(", tier, "):Middle-Aged and Older Adults,Promote Health Products\n")
}
}
Expected Output (Excerpt):
=== Customer Segmentation and Marketing Strategies ===
Alice( Regular ):Minor,Recommended Parent Card
Bob( Regular ):Youth,New Product Releases
Charlie( Silver Card ):Middle Age,Promote Family Plans
Diana( Gold Card ):Middle Age,Promote Family Plans
Eve( Diamond ):10000 USD,Existing Customers,Priority Maintenance
Frank( Silver Card ):Youth,New Product Releases
❓ FAQ
{} (while Python uses indentation); R’s if/else is an expression (which can be assigned to a variable), whereas Python’s is a statement; R’s else must be on the same line as }.if and ifelse?if to evaluate a single value; use ifelse() to evaluate an entire vector. A regular if statement will throw an error if the condition involves a length greater than 1.sum() mean() ifelse(), don’t write a for loop. R loops are 10 to 100 times slower than Python, so use them with caution when working with more than 100,000 elements.while instead of for?while when the number of iterations is unknown (e.g., waiting for an event, a number-guessing game), and use for when the number of iterations is known (e.g., iterating over a vector). Use repeat + break for "infinite loops with early termination."next and break?next skips the current iteration and proceeds to the next one (in R, continue is called next); break exits the entire loop. next is used for filtering, while break is used to exit early.📖 Summary
- if/else/else if conditional branching: In R, enclose the code block in
{}(do not indent) ifelse()is a vectorized conditional statement that can evaluate an entire vector; a regularifstatement can only evaluate a single value.- A
forloop iterates a known number of times; awhileloop iterates an unknown number of times; arepeatloop is an infinite loop and must be used with abreakstatement. - next: Skip this round; break: Exit the entire loop
- R encourages vectorization first—for loops are 10–100 times slower than in Python; for big data, use
sum()andifelse()instead. - Use the tolerance for floating-point comparisons (
abs(x - y) < 1e-9); do not use==directly. elseMust be used in conjunction with}(to avoid ambiguity in parsing)
📝 Exercises
-
Basic Problem: Write an R script using
if/else if/elseto implement the following: Given a scorescore, output the grade (90+: Excellent, 80+: Good, 60+: Pass, otherwise: Fail). Test the script with four scores: 95, 75, 60, and 40, and save a screenshot of the output. -
Basic Problem: Use
ifelse()to divide the vectorc(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)into odd and even elements, and output the result. -
Basic Problem: Use
forto calculate 5! (5 factorial = 5 × 4 × 3 × 2 × 1) in a loop, and save screenshots of the process and the result. -
Advanced Exercise: Write a "Guess the Number" game: ① Use
sample(1:100, 1)to generate a random number between 1 and 100 as the target; ② Usewhileto loop through user inputs (readline); ③ Display the hint "Too high" or "Too low"; ④ When the number is guessed correctly, output "Congratulations! It took N attempts." Run and test the program. -
Challenge: Write a script that processes integers from 1 to 100 as follows: ① Skip multiples of 3 (
next); ② Exit when it reaches 50 (break); ③ Sum the remaining numbers. Verify the result (it should be 1+2+4+5+7+8+...+49 = ?). Save a screenshot of your code and the output.