Suggestion Box
Spot an error or have suggestions for improvement on these notes? Let us know!
Control Structures and Built-in Functions in R
In this section, we’ll learn how R makes decisions, repeats tasks, and performs common operations automatically.
These concepts — control structures and built-in functions — are essential for writing efficient and flexible R code.
1. What Are Control Structures?
Control structures determine the flow of your program — what happens, when, and under what conditions.
They include:
- Conditional statements (
if,else if,else) - Loops (
for,while,repeat) - Vectorized alternatives (e.g.,
ifelse())
2. Conditional Statements
Conditional statements let your code make decisions based on logical tests.
Basic if Example
x <- 10
if (x > 5) {
print("x is greater than 5")
}
If the condition inside the parentheses is TRUE, the code inside the braces runs.
You may notice this is similar to some JavaScript code we have already seen, namely:
let x = 10;
if (x > 5) {
console.log("x is greater than 5");
}
| Concept | R | JavaScript |
|---|---|---|
| Variable assignment | x <- 10 |
let x = 10; |
| Conditional statement | r<br>if (x > 5) {<br> print("x is greater than 5")<br>} |
javascript<br>if (x > 5) {<br> console.log("x is greater than 5");<br>} |
| Output function | print() prints to the R console |
console.log() prints to the browser console or Node terminal |
| Result | x is greater than 5 (appears in RStudio console) |
x is greater than 5 (appears in browser dev tools / terminal) |
if…else
x <- 3
if (x > 5) {
print("x is greater than 5")
} else {
print("x is 5 or less")
}
if…else if…else
x <- 7
if (x > 10) {
print("x is greater than 10")
} else if (x > 5) {
print("x is between 5 and 10")
} else {
print("x is 5 or less")
}
JavaScript Comparison
let x = 7;
if (x > 10) {
console.log("x is greater than 10");
} else if (x > 5) {
console.log("x is between 5 and 10");
} else {
console.log("x is 5 or less");
}
3. The ifelse() Function
ifelse() is a vectorized version of if that applies to each element of a vector.
scores <- c(95, 82, 67, 74)
grades <- ifelse(scores >= 90, "A", "Not A")
grades
Output:
[1] "A" "Not A" "Not A" "Not A"
This is much faster than looping through each element manually.
4. Loops
Loops repeat actions. They are useful for automation, simulations, or processing data step-by-step.
for Loop
for (i in 1:5) {
print(paste("Iteration:", i))
}
In this example, i takes on the values 1 through 5.
JavaScript Comparison
for (let i = 1; i <= 5; i++) {
console.log("Iteration: " + i);
}
| Concept | R | JavaScript |
|---|---|---|
| Loop variable | for (i in 1:5) automatically iterates i over the sequence 1, 2, 3, 4, 5 |
for (let i = 1; i <= 5; i++) explicitly defines a counter (start; condition; increment) |
| Printing output | print(paste("Iteration:", i)) uses paste() to combine strings |
console.log("Iteration: " + i) uses + for string concatenation |
| Loop control | for iterates over elements of a vector |
for executes a block repeatedly while the condition is true |
| Output | Iteration: 1Iteration: 2Iteration: 3Iteration: 4Iteration: 5 |
Iteration: 1Iteration: 2Iteration: 3Iteration: 4Iteration: 5 |
Looping Over a Vector
animals <- c("cat", "dog", "bird")
for (a in animals) {
print(paste("I love", a, "s!"))
}
JavaScript Comparison
let animals = ["cat", "dog", "bird"];
for (let a of animals) {
console.log(`I love ${a}s!`);
}
5. While Loops
A while loop repeats as long as a condition remains TRUE.
count <- 1
while (count <= 5) {
print(paste("Count is", count))
count <- count + 1
}
If you forget to update the counter, the loop will run forever (infinite loop), so use with care!
6. Repeat Loops
A repeat loop runs until explicitly stopped with break.
x <- 1
repeat {
print(x)
x <- x + 1
if (x > 3) break
}
This is less common but useful when the number of iterations isn’t known in advance.
7. Next and Break
You can modify loops with next and break.
next: Skip to the next iteration.break: Exit the loop entirely.
Example:
for (i in 1:5) {
if (i == 3) next
if (i == 5) break
print(i)
}
Output:
[1] 1
[1] 2
[1] 4
8. Built-in Functions in R
R has hundreds of built-in functions. These are predefined operations that simplify data analysis.
Mathematical Functions
x <- c(1, 2, 3, 4, 5)
sum(x) # 15
mean(x) # 3
median(x) # 3
sd(x) # standard deviation
max(x) # 5
min(x) # 1
String Functions
names <- c("Alice", "Bob", "Carmen")
nchar(names) # number of characters
toupper(names) # convert to uppercase
paste(names, "is great!") # combine text
Logical and Test Functions
x <- c(1, 2, 3, NA)
is.na(x) # check for missing values
any(is.na(x)) # TRUE if any are missing
all(x > 0) # TRUE if all elements are positive
9. Combining Loops and Functions
You can use loops and functions together to perform complex operations.
Example: Calculate the mean of each column in a data frame.
data <- data.frame(
a = c(1, 2, 3),
b = c(4, 5, 6),
c = c(7, 8, 9)
)
for (col in names(data)) {
m <- mean(data[[col]])
print(paste("Mean of", col, "is", m))
}
Output:
[1] "Mean of a is 2"
[1] "Mean of b is 5"
[1] "Mean of c is 8"
10. Vectorized Alternatives to Loops
Loops can be replaced by vectorized functions, which are faster and simpler.
Example using apply():
apply(data, 2, mean)
This applies the mean function to each column (2 indicates columns, 1 would indicate rows).
Other apply-family functions include:
lapply()— returns a listsapply()— simplifies result to a vectortapply()— applies a function by group
Example:
tapply(iris$Sepal.Length, iris$Species, mean)
11. Practical Example: Reaction Time Categorization
rt <- c(520, 410, 615, 450, 395)
# Categorize reaction times
category <- ifelse(rt < 500, "Fast", "Slow")
category
# Use a loop to display messages
for (i in 1:length(rt)) {
print(paste("Trial", i, "was", category[i]))
}
Example output:
[1] "Trial 1 was Slow"
[1] "Trial 2 was Fast"
[1] "Trial 3 was Slow"
[1] "Trial 4 was Fast"
[1] "Trial 5 was Fast"
12. Summary
- Use
if,else if, andelsefor conditional logic. - Use loops (
for,while,repeat) for repetition, or vectorized alternatives likeifelse()andapply(). - Use built-in functions (
sum,mean,sd,paste, etc.) to simplify computations. - Prefer vectorized operations whenever possible — they are faster and cleaner than explicit loops.