EconWorkbench
From idea to referee-ready — an open workbench for empirical research.
EconWorkbench is a toolkit for the empirical-research workflow: literature, data, design, estimation, verification, and reporting. Research judgment stays with you — the workbench makes each step faster and the numbers trustworthy.
v1.0 ships the core: crosscheck/ — run the same model in R, Python, and Stata, then diff the results automatically. If the numbers agree, your code is (almost certainly) right. If they don't, you stop interpreting — before a reviewer (or a referee report) stops you.
Live screenshot: Callaway & Sant'Anna (2021) staggered DiD on mpdta, run independently in R (did), Python (StatsPAI), and Stata (csdid). All three report Overall ATT = -0.0399513.
Why
AI agents write most of our econometrics code now. But an LLM that writes the wrong vcov in two languages — consistently — will hand you confident nonsense. The fix is older than LLMs: independent implementations of the same estimator should agree.
- R's
did(Callaway et al.), Stata'scsdid(Sant'Anna et al.), and Python ports are written by different teams. Same data + same model + same numbers = implementation is clean. - One run, one number, no cross-check = you cannot tell a result from a bug.
This is the "double-entry bookkeeping" for regressions — inspired by a 2026 lecture series on AI agents for social-science research (where the speaker, priced out of Stata licenses, could only cross-check R vs Python), and by the StatsPAI parity index, which grades its own estimators against R/Stata references.
Quick start
Core is zero-dependency (pure stdlib):
pip install econworkbench # or: pip install .[report] for tables
# 1. Run the same model in R / Python / Stata; each script writes a 4-column CSV:
# term, estimate, se, pvalue
Rscript my_model.R # -> r_results.csv
python my_model.py # -> py_results.csv
"C:\Program Files\Stata19\StataSE-64.exe" /e do my_model.do # -> stata_results.csv
# 2. Diff them (first CSV is the reference):
econ-crosscheck r_results.csv py_results.csv stata_results.csv
Output:
term r_resultsvspy_resultsr_resultsvsstata_results
--------------------------------------------------------------------
g2004_t2004 bit-exact aligned
...
overall_simple bit-exact aligned
--------------------------------------------------------------------
r_results vs py_results: bit-exact 8 | aligned 0 | FAIL 0
r_results vs stata_results: bit-exact 0 | aligned 8 | FAIL 0
RESULT: PASS (aligned) — exit code 0
Verdicts
| Verdict | Meaning | Default tolerance |
|---|---|---|
bit-exact |
Machine-precision agreement | Δ ≤ 1e-10 |
aligned |
Agreement within tolerance | Δcoef ≤ 1e-6, ΔSE/SE ≤ 1e-4, Δp ≤ 1e-4 |
FAIL |
Significance flips or tolerance breached | — exit code 1 |
Exit codes make it gate-able: wire it into CI, a Makefile, or your SDD pipeline as a release gate.
Example: Callaway & Sant'Anna (2021) replication
examples/cs2021_mpdta/ replicates the canonical staggered-DiD application (minimum-wage effects on teen employment, 2,500 county-year obs) three ways:
| Implementation | Authors' own package | |
|---|---|---|
| R 4.6.1 | did::att_gt() + aggte() |
Callaway & Sant'Anna |
| Python 3.14 | StatsPAI.callaway_santanna() |
port with its own parity evidence |
| StataNow 19.5 | csdid + csdid_estat simple |
Sant'Anna, Goodman-Bacon & Pedro |
Result: R ↔ Python bit-exact on all 8 quantities (7 post-period ATT(g,t) + overall); R ↔ Stata aligned (Δ ≈ 1e-7, different DR-IPW optimizers). Overall ATT = -0.0399 matches the published paper.
Run it yourself: each folder contains the three scripts, the shared dataset (mpdta_data.csv — one source of truth, all three languages read the same file), and the three result CSVs.
From estimates to tables (report/, v1.2)
The same CSVs that feed crosscheck also feed report — one command from estimates to a journal-ready three-line table:
econ-report r_results.csv py_results.csv stata_results.csv --title "Table 1" --out table1
# -> table1.tex (booktabs) + table1.docx (Word three-line) + table1.png (preview)
Significance stars, SEs in parentheses, top/mid/bottom rules — in all three formats. Column labels sit at the bottom, esttab-style.
What it does not do
- It cannot validate your identification strategy — two implementations of a wrong model agree perfectly. (The companion
REVIEWER_CHECKLIST.mdin the parent project covers clustering levels, staggered-DiD pitfalls, pre-trends, etc.) - It is not a paper factory. Judgment stays with the researcher.
Related work
- StatsPAI — agent-native Stata/R replacement with a queryable parity index (a superset of this idea, inside one library).
- Sakana AI-Scientist, Agent Laboratory — end-to-end "AI scientist" pipelines (the opposite bet: automation over verification).
License
MIT
Metadata
Release files for econworkbench 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| econworkbench-1.2.0.tar.gz | 12.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| econworkbench-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.1 kB
Release files / econworkbench-1.2.0.tar.gz
| Download URL | econworkbench-1.2.0.tar.gz |
|---|---|
| Size | 12.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
656367b38e475ab1bd7f3203e99c79555d17c39679da7d40d322dcc91229ffaf
|
|
BLAKE2b-256 checksum How to use checksums |
82fbfb7f11e3db98849eba079a7de714841b0c84bf72099f2b436298019c6fa4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|
Release files / econworkbench-1.2.0-py3-none-any.whl
| Download URL | econworkbench-1.2.0-py3-none-any.whl |
|---|---|
| Size | 10.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
277fdcccd4ecfdced317126b95bb42885867e3337d1741d277f8dec739eae7ce
|
|
BLAKE2b-256 checksum How to use checksums |
243ac80655ac9554d052ed8aebc18bfa5ceee6b002c1feec84ef432569561261
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|