Day 12 of 30·Functions & Macro-like Behavior
Control Structures: if, for, while and the Vectorized Alternative
When to loop, and when R's vectorization makes loops unnecessary.
Learning objectives
- 1Write if/else, for and while constructs in R.
- 2Recognize when vectorization replaces an explicit loop.
- 3Avoid the common 'grow a vector in a loop' performance trap.
- 4Map DO loops to for loops and to seq_along().
Key SAS® → R comparison
| Task | SAS® | R |
|---|---|---|
| Conditional | if/then/else (DATA step) | if (cond) {...} else {...} |
| Iterate | do i=1 to n; | for (i in seq_len(n)) {...} |
| While | do while(cond); | while (cond) {...} |
| Row-wise calc | implicit DATA step loop | vectorized: x + y (no loop) |
Code examples
SAS®
data out; set in;
chg = aval - base; /* implicit loop */
run;R
# No loop needed — operates on whole columns:
out <- in |> mutate(chg = aval - base)Note: What feels like a row loop in SAS is usually a single vectorized expression in R, and far faster.
Explanation
R has the usual control structures, but the DATA step's implicit row loop is replaced by vectorization: arithmetic and most functions operate on entire columns at once. Reaching for an explicit for loop where a vectorized expression would do is the most common performance mistake new R users make.
When you do need a loop — iterating over files or datasets — pre-allocate the container and use seq_along() or seq_len() to index safely, rather than growing an object each iteration.
Practice exercise
Rewrite a row-by-row change-from-baseline calculation as a single vectorized mutate(), then write an explicit for loop that reads and row-binds several CSVs from a folder.