Stata Loops: foreach and forvalues Tutorial with 20 Practical Examples
Stop writing the same command 50 times. Here are 20 real-world loop patterns โ from basic iteration to nested loops and automated tables.
You are copying the same command 40 times with different variable names, and one typo breaks the entire do-file.
This guide gives you reusable loop patterns that reduce manual edits and make automation testable.
All examples tested in Stata 18 SE. Compatible with Stata 15+.
Quick Answer
- Use `foreach` for variable lists, file names, and category labels.
- Use `forvalues` for sequential numbers such as years and bins.
- Combine loops with local macros to keep command templates readable.
- Print loop state with `display` when debugging.
Write Loop Code That You Can Still Read Next Month
Automate repetitive summary and cleaning tasks
Looping is not about clever syntax. It is about reducing manual variation that causes subtle bugs in production analysis.
Build variable lists once, then iterate with predictable names and explicit checks so each step is reproducible.
If you are extending this pipeline, also review How to Structure a Stata Project and Clustered Standard Errors in Stata.
1clear all2set obs 3003gen firm_id = ceil(_n/3)4gen year = 2010 + mod(_n,10)5gen wage = 10 + rnormal(20,4)6gen education = 8 + floor(runiform()*10)7gen tenure = floor(runiform()*25)89foreach v in wage education tenure {10 quietly summarize `v'11 display "Variable: `v' | mean=" %6.2f r(mean)12}1314foreach v in wage education tenure {15 replace `v' = . if `v' < 016}Variable: wage | mean= 30.15 Variable: education | mean= 12.36 Variable: tenure | mean= 11.98
Iterate over years for regression and export
forvalues is ideal when your loop index is numeric and sequential, such as annual models, placebo windows, or bootstrap batches.
Store estimates per iteration and compare outputs together; this catches drift in yearly coefficients.
1clear all2set obs 3003gen firm_id = ceil(_n/3)4gen year = 2010 + mod(_n,10)5gen wage = 10 + rnormal(20,4)6gen education = 8 + floor(runiform()*10)7gen tenure = floor(runiform()*25)89foreach v in wage education tenure {10 quietly summarize `v'11 display "Variable: `v' | mean=" %6.2f r(mean)12}1314foreach v in wage education tenure {15 replace `v' = . if `v' < 016}1718* ---- Section-specific continuation ----19tempname handle20postfile `handle' year b_education using yearly_effects.dta, replace2122forvalues y = 2014/2019 {23 quietly regress wage education tenure if year == `y'24 post `handle' (`y') (_b[education])25}26postclose `handle'2728use yearly_effects.dta, clear29list +-------------------------+
| year b_education |
|-------------------------|
1. | 2014 .8123419 |
2. | 2015 .7765032 |
3. | 2016 .8014477 |
4. | 2017 .8340198 |
5. | 2018 .7899301 |
6. | 2019 .8062245 |
+-------------------------+Common Errors and Fixes
"invalid syntax"
Loop macros are usually misquoted. One missing apostrophe prevents macro expansion and causes parser failure.
Add `display` statements and run `macro list` before the failing line to inspect macro expansion.
invalid syntax r(198);
forvalues y = 2014/2019 { regress wage education if year == 'y'}forvalues y = 2014/2019 { regress wage education if year == `y'}1set trace on2forvalues y = 2014/2019 {3 display "running year `y'"4 regress wage education if year == `y'5}6set trace offrunning year 2014 running year 2015 running year 2016 running year 2017 running year 2018 running year 2019
Command Reference
foreach / forvalues
Stata docs โExecutes repeated command blocks over token lists or integer ranges.
foreach var of varlistIterate directly over existing variablesforvalues i = 1/10Integer loop with automatic incrementquietlySuppress per-iteration output for faster logscontinue, breakExit loops under explicit conditionsHow Sytra Handles This
Sytra can expand loop logic from plain language, then annotate macro expansions so debugging stays transparent.
A direct natural-language prompt for this exact workflow:
Create a Stata loop that runs regress wage education tenure for each year from 2014 to 2019, stores _b[education] in a postfile, and outputs a table by year.Sytra catches these errors before you run.
Sytra can expand loop logic from plain language, then annotate macro expansions so debugging stays transparent.
Join the Waitlist โFAQ
When should I use foreach instead of forvalues?
Use foreach for variable names, file names, or arbitrary token lists; use forvalues when iterating over integer ranges like years or deciles.
How do I debug loops in Stata quickly?
Insert `display` statements inside the loop and run with `set trace on` when syntax errors appear in macro expansion.
Can loops make Stata code slower?
Yes if each iteration repeatedly scans large data. Precompute groups with egen or collapse when possible, then loop over compact objects.
Related Guides
- Stata Macros: local, global, and Extended Functions Explained
- Stata egen Functions: Complete Reference with Examples for Every Function
- Stata 'variable already defined': Why gen Fails and How to Fix It
- Stata preserve/restore and tempvar: Safe Data Manipulation Patterns
- Explore the workflow pillar page
- Open the full workflow guide index
- Browse all Stata & R guides on the blog index
- Browse all Stata pillars
We build practical, reproducible workflows for Stata and R teams working on real empirical research pipelines.