Why talk about problem decomposition?
- Up to now we’ve focused on specific Stata commands:
sum,gen,merge,graph, etc. - Real tasks in applied economics rarely look like “run a single command”
- Clean multiple raw data files
- Merge them together
- Construct variables
- Check that code runs on another computer
- Produce a table or figure for a paper
- These are multi-step problems. If you try to solve them in one shot, you’ll get stuck and frustrated.
- Problem decomposition is the skill of:
- Slowing down
- Thinking before you code
- Breaking a big problem into small, testable steps

Three-step problem decomposition workflow
We’ll use a simple three-step workflow adapted from the Data Carpentry R materials but implemented in Stata:
- Understand the problem
- Restate the problem in your own words
- Determine the inputs and outputs
- Ask for clarification
- Break the problem down
- Write down the pieces, on paper or as comments in a file
- Break complicated pieces down until all pieces are small and manageable
- Code one small piece at a time
- Test it on it’s own
- Fix any problems before proceeding
We’ll keep referring back to ideas from Code Execution (order matters) and Check That Your Code Runs (reproducibility).
Understand the problem
Before you touch Stata:
- Restate the problem in your own words
- If an assignment says:
- “Use
eth_allrounds_final.dtato create a household-level dataset with mean plot yield and total nitrogen use per household.”
- “Use
- Restate as:
- “I need to go from plot-year data to household-level data, with two new variables: average yield per household and total nitrogen used by that household.”
- If an assignment says:
- Determine the inputs and outputs
- Inputs
- The starting dataset(s)
- Variables you’ll need
- Any assumptions (e.g., one manager per plot)
- Outputs
- What dataset should exist at the end?
- What variables should it have?
- Do you need a graph or table?
- Inputs
- Ask for clarification
- Do we have to follow house style? (Yes!)
- Are we allowed to modify raw data? (No!)
- Where should output be saved (which folder/globals)?
Break the problem into pieces
Once you understand the goal, don’t jump straight into writing complex code. Instead:
- Write down the pieces
- On paper
- In a text editor
- Or as comments and headings in a
.dofile using house style
For the example, we might start a .do file like:
**********************************************************************
**# 1 - household-level yield and nitrogen
**********************************************************************
* load plot-level data
use "$data/eth_allrounds_final.dta", clear
* check structure of data
* create household id
* compute plot-level yield (if needed)
* aggregate to household-level means/totals
* save final household-level file
- Break complicated pieces into smaller steps
Take one bullet and break it down again. For example, “aggregate to household-level means/totals”:
* aggregate to household level
* 1. make sure household id uniquely identifies households (`isid`)
* 2. collapse plot-level variables to household level (`collapse`)
* 3. label new variables (`var lab`)
If any line feels fuzzy (“create household id”, “compute yield”), keep breaking it down until each item is something you could reasonably code in 2–4 lines.
Code and test one small piece at a time
A common pattern when students get stuck:
- They write 30 lines of new code
- Run all of it
- Something breaks… and they don’t know where
Instead:
- Implement one sub-step
- Run just that part
- Check that it did what you expected
- Only then move on
Example: From plot-level to household-level
Continuing the example, suppose we’ve broken our plan into:
- Load data
- Check the structure
- Construct household id (if needed)
- Collapse to household-level
- Label and save
We can code each step and test:
**********************************************************************
**# 1 - household-level yield and nitrogen
**********************************************************************
* 1. load plot-level data
use "$data/eth_allrounds_final.dta", clear
* 2. check structure of data
describe
sum yield_kg nitrogen_kg hh_id
*** hh_id exists and looks like a household identifier
* 3. verify uniqueness of hh_id
isid hh_id
*** if this fails, we need to think more about the key
* 4. collapse to household level
collapse (mean) yield_kg ///
(sum) nitrogen_kg, by(hh_id)
* 5. label variables
lab var yield_kg "Mean plot yield (kg) for household"
lab var nitrogen_kg "Total nitrogen (kg) for household"
* 6. save final data set
save "$export/eth_household_yield_nitrogen.dta", replace
At each step:
- Run just that block (e.g., highlight and Ctrl+D)
- Use
describe,sum,list, orbrowseto check that your expectations match what Stata did - If something is wrong, fix it before adding more code
Start simple and iteratively refine
Once you have the basic pieces:
- Experiment
- Try a quick version on a subset of the data:
in 1/100, or using only one region
- Try a quick version on a subset of the data:
- Write a simpler version
- Don’t start with all the options and graphs
- Get the core logic working first
- Make sure it works
- Run from the top of the file
- Make sure you understand it
- If you can’t explain what each line does in words, you don’t understand it yet
- Then make it more complicated
- Add extra variables to
collapse - Add more
by()groups - Beautify the graph
- Wrap in a loop, etc.
- Add extra variables to
Using house style as decomposition scaffolding
Our house style is a great tool for problem decomposition:
- Use numbered headings to match big pieces of the problem:
**# 1 - load and clean data**# 2 - merge in household data**# 3 - construct analysis variables**# 4 - produce graphs/tables
- Use subheadings (
**##) for sub-parts of each step - Use comments (
*) to state the sub-problem above each code block - Use comments (
***) to record the outcomes of a code block
Example skeleton for a more complex task:
**********************************************************************
**# 1 - prepare plot-level data
**********************************************************************
**## 1.1 - load and inspect data
* load plot data
use "$data/eth_allrounds_final.dta", clear
* basic checks
describe
sum yield_kg nitrogen_kg
*** 63,450 observations
*** mean yield 1,230; sd 4,320
*** mean fert 10; st 120
**## 1.2 - construct key variables
* create plot id
gen plot_id = hh_id + " " + string(plotnum)
lab var plot_id "unique plot identifier"
isid plot_id
*** new plot-level unique ID
When you’re stuck, often the fastest way forward is:
Add more structure and comments before adding more Stata commands.
Summary
- Break massive applied tasks down into granular, actionable, testable steps.
- Thinking and planning before coding saves hours of disorganized debugging.
- Test individual components before attempting the fully integrated pipeline.