In this second lecture on programming fundamentals we’ll build on macros and focus on automation:
- Writing loops to repeat tasks safely and quickly
- Using
forvaluesandforeachfor different kinds of lists - Understanding Stata’s
whileloop - Using the programming
ifcommand (different from theifqualifier) - Using
continueandcontinue, breakto control loop flow
We’ll again mostly use sysuse auto and small examples so that the focus stays on the logic.
Implicit vs explicit looping
Stata already loops over observations for you:
gen logincome = log(income)
This line computes the log of income for all observations — there is no explicit loop, but Stata is looping behind the scenes. It takes the log of the first observation, then the second, then the third, and continues until the last observation in the data set.
You only need explicit loops when you’re repeating a pattern over:
- A sequence of numbers (e.g., years 2000 to 2025)
- A list of variables
- A list of arbitrary words or tokens
Looping over numbers with forvalues
Syntax:
forvalues i = 1/5 {
display "`i'"
}
Key pieces:
forvalues– loop commandi– name of a local macro that will take each value in the sequence1/5– the sequence of numbers (1, 2, 3, 4, 5){ ... }– the body of the loop; everything inside runs once per value ofi
Stata will execute:
display "1"
display "2"
display "3"
display "4"
display "5"
You can specify sequences in two main ways:
* from min to max in steps of 1
forvalues i = 1/3 {
display "`i'" // 1, 2, 3
}
* from first to last in steps of five
forvalues j = 10(5)30 {
display "`j'" // 10, 15, 20, 25, 30
}
You can use these macros inside expressions and variable names:
* create 5 dummy variables x1, x2, ..., x5
clear
set obs 10
forvalues k = 1/5 {
gen x`k' = runiform()
}
Stata will execute commands like gen x1 = runiform(), gen x2 = runiform(), …, gen x5 = runiform().
Looping over lists with foreach
foreach is the other main loop workhorse in Stata. It loops over lists of things: words, variables, numbers, or macro contents.
Syntax:
foreach animal in cats dogs cows {
display "`animal'"
}
This prints:
cats
dogs
cows
Stata sets the local macro animal to each word in the list in turn.
More useful example – irregular year list:
foreach year in 2000 2005 2010 2020 {
display "Processing year `year'"
}
Most often in data work you want to loop over variables:
sysuse auto, clear
* summary stats for multiple variables
foreach v of varlist price mpg weight {
sum `v'
}
You can use all of Stata’s varlist shorthand inside foreach:
* any variable whose name starts with "turn" or "gear"
foreach v of varlist turn* gear* {
sum `v'
}
Putting loops and macros together: cleaning variables
This is where loops and macros really shine together:
* define macro with list of controls
local controls price mpg weight
* loop over the words in that macro
foreach x of local controls {
sum `x'
}
Here foreach x of local controls means:
- Look up the macro
controls - Split its contents into words
- Loop over those words as
x
Example: Suppose we have several variables that should be logged:
sysuse auto, clear
* vars to take logs of
local logvars price weight length
* loop over them
foreach v of local logvars {
gen ln_`v' = ln(`v')
lab var ln_`v' "log of `v'"
}
This generates ln_price, ln_weight, and ln_length with consistent labels, using 3 lines instead of copy-pasting (and possibly messing up) 9 lines.
Specialized loops
foreach for number lists
If you want to loop over an irregular sequence of numbers and want Stata to check that they’re valid numbers, you can use numlist:
foreach year of numlist 1980 1985 1995 {
display "`year'"
}
You can mix explicit numbers with ranges:
foreach year of numlist 1980 1985 1990(5)2010 {
display "`year'"
}
Looping with Conditions
Stata also has a while loop:
while condition {
... commands ...
}
- The loop runs as long as
conditionis true (non-zero) - You must make sure something inside the loop eventually makes
conditionfalse, or you’ll have an infinite loop
Simple example:
local i = 1
while `i' <= 5 {
display "i = `i'"
local i = `i' + 1
}
This prints i = 1, i = 2, …, i = 5 and then stops.
while loops are most useful when the number of iterations isn’t known in advance, e.g., iterative estimation until convergence. For most data tasks in this course, forvalues and foreach are clearer and safer.
The if qualifier
Very important distinction:
-
ifqualifier (what you’ve used so far) restricts which observations a command runs on:sum wage if female == 1 -
Programming
ifin Stata is a command that decides whether to run some code at all, based on a logical expression:if expression { ... commands ... } else { ... optional other commands ... }
Example – guard code based on sample size:
* check if we have enough observations before running a regression
count if !missing(price, mpg, weight)
local N = r(N)
if `N' < 50 {
display as error "Not enough complete observations (`N') – skipping regression."
}
else {
reg price mpg weight
}
The programming if does not loop over observations; it uses whatever scalar result you give it (here N).
A simple debugging workflow for loops
Loops can be harder to debug because one or two bad iterations are buried in many repetitions. Some tips:
- Start small
- Test the body of the loop for a single value first (e.g., just for year 2000).
- Once it works, wrap it in a loop.
- Display what’s going on
- Sprinkle
displaystatements inside the loop to print the current macro values.
foreach v of varlist price mpg weight { display "Working on `v'" sum `v' } - Sprinkle
- Use
set trace onwhen you’re really stuck- Stata will print every step it executes, including macro substitutions.
- Turn it off with
set trace offas soon as you’re done.
- Check that the loop boundaries are what you think
- Off-by-one errors (
1/10vs0/9) are common. - Use small ranges while you’re testing.
- Off-by-one errors (
Summary
- Loops (‘foreach’, ‘forvalues’) safely automate repetitive blocks of code.
- ‘while’ loops execute conditionally as long as an expression remains true.
- Loop logic streamlines tasks that must be scaled across numerous variables or files.