Step 1 of 5 · Reading · ~1 min
Learn
Control Flow
R has standard loops, but idiomatic R avoids them. Vectorized operations and apply-family functions are faster and clearer.
for loop:
for (i in 1:5) {
cat(i, "\n")
}
while:
n <- 1
while (n < 100) {
n <- n * 2
}
But consider this - instead of:
result <- numeric(10)
for (i in 1:10) result[i] <- i * i
Write:
result <- (1:10)^2 # vectorized - faster, clearer
The vectorized form is not just shorter. Its inner loop runs in compiled code rather than in the interpreter, and it states the intent in one expression instead of spreading it over an allocation, a counter and a subscript.
The sapply function applies a function to each element and simplifies the result:
sapply(1:5, function(x) x^2) # 1 4 9 16 25
Loop control, and the 1:length(x) trap
break leaves the innermost loop; next skips to the next iteration. R spells it next, not continue.
1:length(x) reads like "every index of x", and it is - right up until x is empty. 1:0 is not an empty range, it is the two-element vector c(1, 0), so the loop body runs twice with indices that do not exist:
x <- c()
1:length(x) # 1 0 - two iterations, both wrong
seq_len(length(x)) # integer(0) - zero iterations
seq_along(x) # integer(0) - same thing, shorter
Reach for seq_along(x) whenever you are walking a vector.
Use loops when there is genuine sequential state (Newton's method, simulations). Use vectorization for everything else.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…