Skip to main content
v2026.11,858 entries · CC-BY 4.0

For Loops in R: Syntax, break/next, and When to Use lapply

How for loops work in R, per the R reference: syntax, seq_along, break and next, why results must be stored, and when lapply, sapply or vapply fits better.

Written and maintained by CASRAI Editorial Board

Last updated

A for loop in R repeats a block of code once for each element of a vector or list: for (var in seq) expr. The part most tutorials skip is what R’s own reference page guarantees about it: the sequence is evaluated once, a zero-length sequence skips the body, and the loop itself returns nothing, so every result you want must be stored explicitly. This guide covers looping in R programming from that reference, then shows when lapply, sapply or vapply is the better tool.

What looping in R is used for in research

Research analysis repeats the same step many times: fit one model per variable, read one file per participant, compute one summary per group. R is a statistical programming language, and the R Core Team’s An Introduction to R says its programming language includes “conditionals, loops, user defined recursive functions and input and output facilities” (see what R programming is used for). A loop is the most direct way to express “do this for each item”, and it is the form that is easiest to read back months later when you revisit a script. For reproducible work, loops belong in a script with a pinned package environment, as described in the renv guide.

Install or access

Loops are part of the base language, so no package is needed. Install R from the Comprehensive R Archive Network (CRAN) at cran.r-project.org, the project’s official distribution site, and type the examples below at the R console or in a script. The authoritative references for everything here are the R manual pages “Control Flow” and “Apply Functions Over List or Vector”, and section 9 (“Grouping, loops and conditional execution”) of An Introduction to R; all three are linked under Sources.

Step by step: write a for loop

  1. Choose the sequence. The R reference defines the form as for(var in seq) expr, where seq is “an expression evaluating to a vector (including a list and an expression) or to a pairlist or NULL”. Here the sequence is a numeric vector: x <- c(4, 8, 15)
  2. Loop over positions with seq_along. The reference suggests seq_along to get an index vector and then extracting individual elements explicitly (it says this for classed objects, and it works for any vector): for (i in seq_along(x)) { print(x[i] * 2) } prints 8, 16 and 30.
  3. Create a container before the loop and fill it. doubled <- numeric(length(x)), then inside the loop doubled[i] <- x[i] * 2. After the loop, doubled holds 8, 16, 30.
  4. Skip or stop early when needed. Per the reference, next halts the current iteration and advances the looping index, and break transfers control to the first statement outside the innermost loop. Both apply only to the innermost of nested loops. For example, for (v in x) { if (v == 8) next; print(v) } prints 4 and 15.
  5. Loop directly over values when you do not need the position. for (v in x) print(v) visits 4, 8 and 15 in order. Use the index form from step 2 when you also need to write back into a container at the same position.

Output and how to read it

Three guarantees from the “Control Flow” reference explain most surprises:

  • The loop returns nothing useful. “for, while and repeat return NULL invisibly.” Assigning result <- for (...) ... gives NULL, so store values inside the body, as in step 3.
  • The loop variable survives. After the loop, var remains a variable holding its latest value. “for sets var to the last used element of seq, or to NULL if it was of length zero.” After the loop over x above, v equals 15.
  • The sequence is fixed at the start. “The seq in a for loop is evaluated at the start of the loop; changing it subsequently does not affect the loop.” You can assign to the loop variable inside the body, but this does not affect the next iteration.

Troubleshooting

The loop body never runs

“If seq has length zero the body of the loop is skipped.” An empty vector, an empty list or NULL therefore produces no iterations and no error. This is the usual explanation when a loop over filtered data appears to do nothing: check the length of the sequence first.

Loops over 1:length(x) misbehave on empty input

The expression 1:length(x) becomes 1:0 when x is empty, which is the two-element sequence 1, 0, so the body runs twice with invalid positions. seq_along(x) is empty for an empty x, so by the zero-length rule above the body is skipped, which is the behaviour you want.

Changing the vector inside the loop has no effect on the iterations

Because the sequence is evaluated once, appending to or shortening x inside for (v in x) does not add or remove iterations. If the number of iterations depends on what the loop discovers, use while or repeat with break.

The condition in an if inside the loop errors

The reference requires the condition to be “a length-one logical vector that is not NA”. A comparison that returns NA, or a vector of several values, stops the loop with an error; handle missing values before the test.

Only the last result is available

If you printed inside the loop but cannot reuse the values, the loop did not store them. Return to step 3 and assign into a container indexed by position.

A loop returned a list when you wanted a vector

That is usually an apply-family question, covered next: lapply always returns a list.

When to use a for loop and when to use lapply, sapply or vapply

The “Apply Functions Over List or Vector” reference describes three functions that replace the loop-plus-container pattern. They differ in what they return.

Function Signature What it returns, per the R reference
for loop for(var in seq) expr NULL invisibly; you store results yourself
lapply lapply(X, FUN, ...) “a list of the same length as X”
sapply sapply(X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE) A “user-friendly version and wrapper of lapply”, returning a vector or matrix by default; simplification happens only if X has length greater than 0 and all results share the same positive length, otherwise a list
vapply vapply(X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE) Similar to sapply but with a pre-specified return type; each result must match FUN.VALUE in length and type

A practical reading of that table: use lapply when each step returns something of its own shape (a model, a data frame). Use vapply when you want a plain vector and want an error, not a silent change of shape, if a step returns the wrong kind of value. Use a for loop when steps depend on earlier ones, or when you need break and next.

Free alternatives

Everything below ships with base R, which is free to download from CRAN.

Construct Use it for Source
for Repeating an expression once per element of a vector, list or pairlist R reference, “Control Flow”
while and repeat Repeating until a condition fails or until break; like for, they return NULL invisibly R reference, “Control Flow”
lapply Applying a function to each element and keeping a list R reference, “Apply Functions Over List or Vector”
sapply The same, simplified to a vector or matrix when shapes agree R reference, “Apply Functions Over List or Vector”
vapply The same, with a declared result type that is checked R reference, “Apply Functions Over List or Vector”

FAQ

What is looping in R programming?

Looping is running the same code repeatedly. R’s looping constructs are for, while and repeat, with break and next to control them; the apply family (lapply, sapply, vapply) expresses the same idea as a function call.

What is the difference between for, while and repeat?

for visits each element of a fixed sequence. while keeps going while a condition holds. repeat loops until a break is executed. All three return NULL invisibly.

Should I use a for loop or sapply?

If each iteration produces one value and the iterations are independent, sapply or vapply states the intent in one call and returns the result directly. If iterations depend on each other, or you need break, use a for loop. The decision table above summarises the return types.

Why does my for loop return NULL?

Because for always does. Store values in a container inside the body.

How do I loop over a list in R?

for (item in my_list) works because seq may be a list; lapply(my_list, FUN) does the same and collects the results into a list. For other R analysis guides, see the Kruskal-Wallis test in R and the Bonferroni correction in R.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about For Loops in R: Syntax, break/next, and When to Use lapply

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.