30-Day Course
Clinical SAS → R
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

TaskSAS®R
Conditionalif/then/else (DATA step)if (cond) {...} else {...}
Iteratedo i=1 to n;for (i in seq_len(n)) {...}
Whiledo while(cond);while (cond) {...}
Row-wise calcimplicit DATA step loopvectorized: x + y (no loop)

Code examples

Prefer vectorization
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.