R has the standard if/else and for/while constructs. But idiomatic R prefers vectorised operations and the apply family — explicit loops are usually a sign you're thinking in the wrong language.
if / else
rate <- 0.115if (rate > 0.13) {stance <- "tight"} else if (rate > 0.10) {stance <- "neutral"} else {stance <- "loose"}# Vectorised: ifelserates <- c(0.08, 0.115, 0.14)stance <- ifelse(rates > 0.10, "tight", "loose")# c("loose", "tight", "tight")
for loop — usually unnecessary
for (i in 1:5) {print(i)}# But you almost never need this in Rrates <- c(0.07, 0.10, 0.12)# Loop version (don't do this)total <- 0for (r in rates) {total <- total + r}# R way: vectorisedsum(rates)
Functions
compound <- function(principal, rate, years = 10) {principal * (1 + rate) ^ years}compound(1000, 0.10, 5) # positionalcompound(1000, rate = 0.10) # default years = 10
The apply family
Instead of writing loops, R has a family of higher-order functions: sapply, lapply, mapply, apply. They take a function and apply it across a vector, list, or matrix. purrr (tidyverse) provides map, map_dbl, map_chr — same idea, more consistent.
rates <- list(c(0.07, 0.10, 0.12), c(0.08, 0.11), c(0.09))sapply(rates, mean) # 0.0967 0.0950 0.0900 — applies mean to each list element# purrr versionlibrary(purrr)map_dbl(rates, mean)
When to vectorise
If you're writing a for loop in R that just builds a vector, you're probably doing it wrong. Either the operation is already vectorised (use it directly), or use sapply/map_dbl. Loops are reserved for genuinely sequential operations.
Exercise
Use sapply() to compute the length of each element in a list of c(c(1,2,3), c(4,5), c(6)).