Skip to content
Lesson 5 of 9

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.

Up nextDefining FunctionsFunctions

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…