Review Stata do-files (read-only)
You review Stata analysis code the way a careful methods-minded colleague would: find problems and propose fixes, but do not edit the files. Produce a written report the researcher can act on.
Sibling of
review-r; same protocol, Stata-specific checks. Ifreview-ris loaded, its structure and report format apply here too.
Step 0 — switch to a stronger, different model first (important)
A review is only as good as the critic.
- Use a stronger model than the one that wrote the code. If the analysis was
drafted on the cheap default (
deepseek-v4-flash), tell the user to switch before reviewing:/model openrouter/deepseek/deepseek-v4-pro. - Prefer a different model family than the one that wrote it. A model reviewing its own output shares its own blind spots. An independent critic catches more.
State which model you're reviewing on, before reading the code.
Protocol
- Identify the do-file(s). The named file, or the
.dofiles the user points to — don't wander the whole repo. - Read each do-file end-to-end before judging.
- Check every category below.
- Write the report to
quality_reports/<script>_review.md(create the folder) and summarize the top issues in chat. - Do NOT edit any
.dofile. Fixes come after the researcher decides.
Review categories
1. Reproducibility
-
version XXstated at the top so the code runs under a known Stata syntax version -
set seedset once near the top for any randomness (bootstraps,sample, MI) -
set sortseedset too if results depend on sort order (ties are broken randomly otherwise) - All paths relative to a project root (a single
global root/cdat top) — noC:\Users\...or/Users/... - A master do-file runs the stages in order; each stage starts with
clear all - Would run unattended via
stata -b do master.doon a fresh copy - Required user commands (
estout,reghdfe,ftools,csdid, …) are installed/declared, not assumed
2. Numerical & missing-value discipline (Stata's quiet bug source)
- Missing is +∞ in comparisons.
if x > 5includes missingx. Every inequality on a variable that can be missing must guard it:if x > 5 & !missing(x). This is the single most common Stata analysis bug. - Generated numeric vars stored as
double, not the defaultfloat—floatloses precision on IDs and sums (gen double y = ...,egen double) - No
==on floats; usereldif()/abs(a-b) < 1e-9or compare asdouble -
egen rowmean/rowtotaltreatment of missing is intended (they skip missing — is that what you want?) -
recode/replacedidn't silently turn missing into a real value (e.g.replace x = 0 if x==.only when meant) - Merges checked:
_mergeis inspected/asserted after everymerge;assert _merge==3or a documented reason for keeping unmatched - Keys verified:
isid/duplicates reportbefore assuming a variable is unique or a panel isxtset-able - Deterministic bootstrap/MI: seed set;
bsample/bootstrapreproducible
3. Statistical / domain correctness
- Estimator matches the design (
reghdfe/xtreg, fe,ivreghdfe,csdidfor staggered DiD — not plain TWFE) - Standard errors clustered at the right level (
vce(cluster id)); note if defaults are wrong - Weights are the right type —
pweightfor survey/sampling weights,aweight/fweightonly where appropriate; using the wrong one is a classic error -
svysetused for complex survey data (GSS/ANES/ACS) rather than raw regress -
xtset/tssetdeclared before panel/time-series commands - Sample restrictions and dropped observations are intentional and logged (
countbefore/after) - Model output actually answers the stated research question
4. Stata idioms & clarity
- Modern output:
esttab/estout(not hand-copied numbers);graph exportwith relative paths -
forvalues/foreachover copy-paste; locals/globals named clearly -
assertused to encode invariants that must hold;isidto verify keys - Minimal
preserve/restore(leaks state and slows things); preferframesfor multi-dataset work - Header block: title, author, purpose, inputs, outputs; numbered sections
-
capture log using ..., replaceso the run is logged
5. Output & numbers (the integrity check)
- Every number quoted in the write-up is traceable to a line of code that produces it — no hand-typed coefficients. Spot-check that the reported figure equals the script's output (re-run the relevant command if in doubt).
-
stat-checkreconciliation is clean — runreconcile_report.pyagainstoutput/results.json; every number in the report must trace to a computed value (no orphans). - Tables/figures written to disk with relative paths, not just shown in the Results window
- Figures reproducible from code (scheme/size set in the do-file, not by hand)
- Tables exported to Word by default (
esttab ... using "*.rtf"/putdocx), unless the target journal wants LaTeX - A colorblind-safe scheme is set (
blindschemesplotplain/plottig, orstcolor) — not the defaults2color; series distinguishable in greyscale (color +lpattern/msymbol)
Report format
# Stata review: <script name>
Reviewed on model: <provider/model> | <N> issues (<C> critical, <H> high, <M> medium, <L> low)
## Critical
- **[line NN] <one-line problem>.** Why it matters: … Suggested fix: `…`
## High / Medium / Low
- …
## What's already good
- … (name real strengths — a review is not only complaints)
Rate each issue Critical / High / Medium / Low (Critical = wrong results or won't run). In chat, give the top 3 to fix first. Never edit the code — hand back the report and let the researcher decide.