Skip to content

Commit 54e9433

Browse files
Release v0.2.0: Post-estimation, output tables, inference modules
New features: - Post-estimation: margins (AME/MEM), test (Wald), lincom - Output: sumstats, balance_table, tab (cross-tabulation) - Inference: wild cluster bootstrap, AIPW - All tables export to Word (.docx), Excel (.xlsx), LaTeX, HTML - result.to_docx() on all result objects - PSM King & Nielsen (2019) warning - Updated README to statsmodels-style PyPI page 280 tests passing, 78% coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 08fbfa4 commit 54e9433

16 files changed

Lines changed: 2501 additions & 144 deletions

File tree

README.md

Lines changed: 168 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,199 +1,227 @@
1-
# StatsPAI
1+
# StatsPAI: The Causal Inference & Econometrics Toolkit for Python
22

3-
[![PyPI version](https://badge.fury.io/py/StatsPAI.svg)](https://badge.fury.io/py/StatsPAI)
3+
[![PyPI version](https://badge.fury.io/py/StatsPAI.svg)](https://pypi.org/project/StatsPAI/)
44
[![Python versions](https://img.shields.io/pypi/pyversions/StatsPAI.svg)](https://pypi.org/project/StatsPAI/)
5-
[![License](https://img.shields.io/github/license/brycewang-stanford/statspai.svg)](https://github.com/brycewang-stanford/statspai/blob/main/LICENSE)
6-
[![Build Status](https://github.com/brycewang-stanford/statspai/workflows/CI%2FCD%20Pipeline/badge.svg)](https://github.com/brycewang-stanford/statspai/actions)
7-
[![codecov](https://codecov.io/gh/brycewang-stanford/statspai/branch/main/graph/badge.svg)](https://codecov.io/gh/brycewang-stanford/statspai)
5+
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/brycewang-stanford/statspai/blob/main/LICENSE)
6+
[![Tests](https://github.com/brycewang-stanford/statspai/workflows/CI%2FCD%20Pipeline/badge.svg)](https://github.com/brycewang-stanford/statspai/actions)
7+
[![Downloads](https://static.pepy.tech/badge/statspai/month)](https://pepy.tech/project/statspai)
88

9-
**The AI-powered Statistics & Econometrics Toolkit for Python**
9+
StatsPAI is a Python package for causal inference and applied econometrics. It provides a unified, Stata-style API covering the complete empirical research workflow — from estimation to publication-ready tables in Word, Excel, and LaTeX.
1010

11-
StatsPAI bridges the gap between user-friendly syntax and powerful econometric analysis, making advanced techniques accessible to researchers and practitioners.
11+
It brings R's [Causal Inference Task View](https://cran.r-project.org/web/views/CausalInference.html) (fixest, did, rdrobust, gsynth, DoubleML, MatchIt, CausalImpact) into a single, consistent Python package.
1212

13-
## Features
13+
> Built by the team behind [CoPaper.AI](https://copaper.ai) · Stanford REAP Program
1414
15-
### Core Econometric Methods
16-
- **Linear Regression**: OLS, WLS with robust standard errors
17-
- **Instrumental Variables**: 2SLS estimation
18-
- **Panel Data**: Fixed Effects, Random Effects models
19-
- **Causal Inference**: Causal Forest implementation (inspired by EconML)
15+
---
2016

21-
### User Experience
22-
- **Formula Interface**: Intuitive R/Stata-style syntax `"y ~ x1 + x2"`
23-
- **Excel Export**: Professional output tables via `outreg2` (Stata-inspired)
24-
- **Flexible API**: Both formula and matrix interfaces supported
25-
- **Rich Output**: Detailed summary statistics and diagnostic tests
17+
## Main Features
2618

27-
### Technical Excellence
28-
- **Robust Implementation**: Based on proven econometric theory
29-
- **Performance Optimized**: Efficient algorithms for large datasets
30-
- **Well Tested**: Comprehensive test suite ensuring reliability
31-
- **Type Hints**: Full type annotation for better development experience
19+
**Regression Models:**
3220

33-
## Installation
21+
- Ordinary Least Squares with robust / clustered / HAC standard errors
22+
- Instrumental Variables / Two-Stage Least Squares (2SLS), with first-stage F, Sargan, and Hausman tests
23+
- Panel data: Fixed Effects, Random Effects, Between, First Differences (via linearmodels)
24+
- High-dimensional Fixed Effects (via pyfixest)
3425

35-
```bash
36-
# Latest stable version
37-
pip install StatsPAI
26+
**Causal Inference — Difference-in-Differences:**
3827

39-
# Development version
40-
pip install git+https://github.com/brycewang-stanford/statspai.git
41-
```
28+
- Classic 2x2 DID estimator
29+
- Staggered DID with heterogeneous treatment effects (Callaway & Sant'Anna 2021)
30+
- Event study plots and pre-trend tests
4231

43-
### Requirements
44-
- Python 3.8+
45-
- NumPy, SciPy, Pandas
46-
- scikit-learn (for Causal Forest)
47-
- openpyxl (for Excel export)
32+
**Causal Inference — Regression Discontinuity:**
4833

49-
## Quick Start
34+
- Sharp and Fuzzy RD with local polynomial estimation
35+
- MSE-optimal bandwidth selection (CCT 2014)
36+
- Robust bias-corrected confidence intervals
37+
- RD plots with binned scatter and polynomial fit
5038

51-
### Basic Regression Analysis
52-
```python
53-
import pandas as pd
54-
from statspai import reg, outreg2
39+
**Causal Inference — Matching:**
5540

56-
# Load your data
57-
df = pd.read_csv('data.csv')
41+
- Propensity Score Matching (logit-based PSM)
42+
- Mahalanobis distance matching
43+
- Coarsened Exact Matching (CEM)
44+
- Balance diagnostics with standardized mean differences
5845

59-
# Run OLS regression
60-
result1 = reg('wage ~ education + experience', data=df)
61-
print(result1.summary())
46+
**Causal Inference — Synthetic Control:**
6247

63-
# Add control variables
64-
result2 = reg('wage ~ education + experience + age + gender', data=df)
48+
- Abadie-Diamond-Hainmueller SCM
49+
- Penalized / ridge SCM for many donors
50+
- Placebo (permutation) inference with MSPE ratios
51+
- Donor weight tables and gap plots
6552

66-
# Export results to Excel
67-
outreg2([result1, result2], 'regression_results.xlsx',
68-
title='Wage Regression Analysis')
69-
```
53+
**Causal Inference — Machine Learning Methods:**
7054

71-
### Instrumental Variables
72-
```python
73-
# 2SLS estimation
74-
iv_result = reg('wage ~ education | mother_education + father_education',
75-
data=df, method='2sls')
76-
print(iv_result.summary())
77-
```
55+
- Double/Debiased Machine Learning: Partially Linear (PLR) and Interactive (IRM) models with cross-fitting (Chernozhukov et al. 2018)
56+
- Causal Forest for heterogeneous treatment effects (HTE)
57+
- Compatible with any scikit-learn estimator as first-stage ML model
7858

79-
### Panel Data Analysis
80-
```python
81-
# Fixed effects model
82-
fe_result = reg('y ~ x1 + x2', data=df,
83-
entity_col='firm_id', time_col='year',
84-
method='fixed_effects')
85-
```
59+
**Causal Inference — Other Methods:**
8660

87-
### Causal Forest for Heterogeneous Treatment Effects
88-
```python
89-
from statspai import CausalForest
61+
- Causal Impact: Bayesian structural time-series intervention analysis (Brodersen et al. 2015)
62+
- Causal Mediation Analysis: ACME / ADE decomposition with bootstrap inference (Imai et al. 2010)
63+
- Shift-Share / Bartik IV with Rotemberg weight diagnostics (GPSS 2020)
9064

91-
# Initialize Causal Forest
92-
cf = CausalForest(n_estimators=100, random_state=42)
65+
**Post-Estimation:**
9366

94-
# Fit model: outcome ~ treatment | features | controls
95-
cf.fit('income ~ job_training | age + education + experience | region + year',
96-
data=df)
67+
- Marginal effects (AME / MEM) with delta-method standard errors, equivalent to Stata's `margins, dydx(*)`
68+
- Wald test for linear restrictions, equivalent to Stata's `test`
69+
- Linear combinations of coefficients with inference, equivalent to Stata's `lincom`
9770

98-
# Estimate individual treatment effects
99-
individual_effects = cf.effect(df)
71+
**Diagnostics:**
10072

101-
# Get confidence intervals
102-
effects_ci = cf.effect_interval(df, alpha=0.05)
73+
- Oster (2019) coefficient stability / selection-on-unobservables bounds
74+
- McCrary (2008) density manipulation test for RD validity
10375

104-
# Export results
105-
cf_summary = cf.summary()
106-
outreg2([cf_summary], 'causal_forest_results.xlsx')
107-
```
76+
**Publication-Quality Output:**
10877

109-
## Advanced Usage
78+
- Multi-model comparison tables (equivalent to R's `modelsummary` / Stata's `esttab`)
79+
- Coefficient forest plots across models
80+
- Summary statistics tables (equivalent to Stata's `tabstat`)
81+
- Balance tables for matching / DID / RCT papers
82+
- Cross-tabulation with chi-squared / Fisher's exact test (equivalent to Stata's `tab, chi2`)
83+
- **Export to Word (.docx), Excel (.xlsx), LaTeX (.tex), HTML** — all tables, all formats
84+
- Every result object has `.summary()`, `.plot()`, `.to_latex()`, `.to_docx()`, `.cite()`
11085

111-
### Robust Standard Errors
112-
```python
113-
# Heteroskedasticity-robust standard errors
114-
result = reg('y ~ x1 + x2', data=df, robust=True)
86+
---
11587

116-
# Clustered standard errors
117-
result = reg('y ~ x1 + x2', data=df, cluster='firm_id')
118-
```
88+
## Installation
11989

120-
### Model Comparison
121-
```python
122-
from statspai import compare_models
90+
```bash
91+
pip install statspai
92+
```
12393

124-
models = [
125-
reg('y ~ x1', data=df),
126-
reg('y ~ x1 + x2', data=df),
127-
reg('y ~ x1 + x2 + x3', data=df)
128-
]
94+
With optional dependencies:
12995

130-
comparison = compare_models(models)
131-
print(comparison.summary())
96+
```bash
97+
pip install statspai[plotting] # matplotlib, seaborn
98+
pip install statspai[fixest] # pyfixest for high-dimensional FE
13299
```
133100

134-
### Custom Output Formatting
101+
**Requirements:** Python >= 3.9
102+
103+
**Core dependencies:** NumPy, SciPy, Pandas, statsmodels, scikit-learn, linearmodels, patsy, openpyxl, python-docx
104+
105+
---
106+
107+
## Quick Example
108+
135109
```python
136-
outreg2(results, 'output.xlsx',
137-
title='Regression Results',
138-
add_stats={'Observations': lambda r: r.nobs,
139-
'R-squared': lambda r: r.rsquared},
140-
decimal_places=4,
141-
star_levels=[0.01, 0.05, 0.1])
110+
import statspai as sp
111+
112+
# --- Estimation ---
113+
r1 = sp.regress("wage ~ education + experience", data=df, robust='hc1')
114+
r2 = sp.ivreg("wage ~ (education ~ parent_edu) + experience", data=df)
115+
r3 = sp.did(df, y='wage', treat='policy', time='year', id='worker')
116+
r4 = sp.rdrobust(df, y='score', x='running_var', c=0)
117+
r5 = sp.match(df, y='outcome', treat='treated', covariates=['age', 'edu'])
118+
r6 = sp.dml(df, y='wage', treat='training', covariates=['age', 'edu', 'exp'])
119+
120+
# --- Post-estimation ---
121+
me = sp.margins(r1, data=df) # Marginal effects
122+
sp.test(r1, "education = experience") # Wald test: beta_edu = beta_exp?
123+
sp.lincom(r1, "education + experience") # Linear combination
124+
125+
# --- Tables (to Word / Excel / LaTeX) ---
126+
sp.modelsummary(r1, r2, output='table2.docx')
127+
sp.outreg2(r1, r2, r3, filename='results.xlsx')
128+
sp.sumstats(df, vars=['wage', 'education', 'age'], output='table1.docx')
129+
sp.balance_table(df, treat='treated', covariates=['age', 'edu'], output='balance.docx')
130+
sp.tab(df, 'treatment', 'outcome', output='crosstab.docx')
142131
```
143132

144-
## Documentation
133+
---
145134

146-
- **[User Guide](docs/user_guide.md)**: Comprehensive tutorials and examples
147-
- **[API Reference](docs/api_reference.md)**: Detailed function documentation
148-
- **[Theory Guide](docs/theory_guide.md)**: Mathematical foundations
149-
- **[Examples](examples/)**: Jupyter notebooks with real-world applications
135+
## API Summary
150136

151-
## Contributing
137+
| Category | Functions | Description |
138+
| --- | --- | --- |
139+
| **Regression** | `regress`, `ivreg`, `panel`, `fixest.feols` | OLS, IV/2SLS, Panel (FE/RE/FD/BE), High-dimensional FE |
140+
| **DID** | `did`, `did_2x2`, `callaway_santanna` | Classic 2x2, Staggered (C&S 2021), Event study |
141+
| **RD** | `rdrobust`, `rdplot` | Sharp/Fuzzy RD, CCT robust inference, RD plots |
142+
| **Matching** | `match` | PSM, CEM, Mahalanobis, Balance diagnostics |
143+
| **Synth** | `synth` | Abadie SCM, Penalized SCM, Placebo inference |
144+
| **ML Causal** | `dml`, `causal_forest` | Double ML (PLR/IRM), Causal Forest (HTE) |
145+
| **Other Causal** | `causal_impact`, `mediate`, `bartik` | Intervention analysis, Mediation, Shift-share IV |
146+
| **Post-estimation** | `margins`, `marginsplot`, `test`, `lincom` | Marginal effects, Wald tests, Linear combinations |
147+
| **Diagnostics** | `oster_bounds`, `mccrary_test` | Coefficient stability, Density manipulation |
148+
| **Tables** | `modelsummary`, `outreg2`, `sumstats`, `balance_table`, `tab` | Multi-model tables, Summary stats, Balance, Cross-tabs |
149+
| **Plots** | `coefplot`, `marginsplot`, `rdplot`, `result.plot()` | Coefficient, Margins, RD, Event study plots |
150+
| **Export** | `.to_docx()`, `.to_latex()`, `output='*.xlsx'` | Word, Excel, LaTeX, HTML — all tables, all formats |
152151

153-
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) for details.
152+
All causal methods return a unified **`CausalResult`** object:
154153

155-
### Development Setup
156-
```bash
157-
# Clone repository
158-
git clone https://github.com/brycewang-stanford/statspai.git
159-
cd statspai
154+
```python
155+
result.estimate # Point estimate
156+
result.se # Standard error
157+
result.pvalue # P-value
158+
result.ci # Confidence interval
159+
result.summary() # Formatted text summary
160+
result.plot() # Appropriate visualization
161+
result.to_latex() # LaTeX table
162+
result.to_docx() # Word document
163+
result.cite() # BibTeX citation for the method
164+
```
160165

161-
# Install in development mode
162-
pip install -e ".[dev]"
166+
---
163167

164-
# Install pre-commit hooks
165-
pre-commit install
168+
## Comparison with Stata and R
166169

167-
# Run tests
168-
pytest
169-
```
170+
| Task | Stata | R | StatsPAI |
171+
| --- | --- | --- | --- |
172+
| OLS with robust SE | `reg y x, r` | `feols(y ~ x, vcov="HC1")` | `sp.regress("y ~ x", robust='hc1')` |
173+
| IV regression | `ivregress 2sls y (x = z)` | `feols(y ~ 1 \| x ~ z)` | `sp.ivreg("y ~ (x ~ z)")` |
174+
| Staggered DID | `csdid y, ivar(id) time(t) gvar(g)` | `att_gt(y ~ 1, ...)` | `sp.did(df, y, treat, time, id)` |
175+
| RD design | `rdrobust y x, c(0)` | `rdrobust(Y, X, c=0)` | `sp.rdrobust(df, y, x, c=0)` |
176+
| PSM matching | `psmatch2 treat x1 x2` | `matchit(treat ~ x1+x2)` | `sp.match(df, y, treat, covs)` |
177+
| Double ML || `DoubleML$new(...)` | `sp.dml(df, y, treat, covs)` |
178+
| Marginal effects | `margins, dydx(*)` | `margins(model)` | `sp.margins(result, data=df)` |
179+
| Wald test | `test x1 = x2` | `linearHypothesis(...)` | `sp.test(result, "x1 = x2")` |
180+
| Export to Word | `outreg2 using r.doc, word` | `modelsummary(output="t.docx")` | `sp.outreg2(r, filename="r.docx")` |
181+
| Summary stats | `tabstat y x, s(mean sd)` | `datasummary(...)` | `sp.sumstats(df, vars=[...])` |
170182

171-
## License
183+
---
172184

173-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
185+
## About
174186

175-
## Acknowledgments
187+
**StatsPAI Inc.** is the research infrastructure company behind [CoPaper.AI](https://copaper.ai) — the AI co-authoring platform for empirical research, born out of Stanford's [REAP](https://reap.fsi.stanford.edu/) program.
176188

177-
- Inspired by Stata's `outreg2` command for output formatting
178-
- Causal Forest implementation based on Wager & Athey (2018)
179-
- Built on the shoulders of NumPy, SciPy, and scikit-learn
189+
**CoPaper.AI** — Upload your data, set your research question, and produce a fully reproducible academic paper with code, tables, and formatted output. Powered by StatsPAI under the hood. [copaper.ai](https://copaper.ai)
180190

181-
## Contact
191+
**Team:**
182192

183-
- **Author**: Bryce Wang
184-
- **Email**: brycew6m@gmail.com
185-
- **GitHub**: [brycewang-stanford](https://github.com/brycewang-stanford)
193+
- **Bryce Wang** — Founder. Economics, Finance, CS & AI. Stanford REAP.
194+
- **Dr. Scott Rozelle** — Co-founder & Strategic Advisor. Stanford Senior Fellow, author of *Invisible China*.
186195

187-
## Citation
196+
---
188197

189-
If you use StatsPAI in your research, please cite:
198+
## Contributing
199+
200+
```bash
201+
git clone https://github.com/brycewang-stanford/statspai.git
202+
cd statspai
203+
pip install -e ".[dev,plotting,fixest]"
204+
pytest
205+
```
206+
207+
---
208+
209+
## Citation
190210

191211
```bibtex
192-
@software{wang2024statspai,
193-
title={StatsPAI: The AI-powered Statistics & Econometrics Toolkit for Python},
212+
@software{wang2025statspai,
213+
title={StatsPAI: The Causal Inference & Econometrics Toolkit for Python},
194214
author={Wang, Bryce},
195-
year={2024},
215+
year={2025},
196216
url={https://github.com/brycewang-stanford/statspai},
197217
version={0.1.0}
198218
}
199219
```
220+
221+
## License
222+
223+
MIT License. See [LICENSE](LICENSE).
224+
225+
---
226+
227+
[GitHub](https://github.com/brycewang-stanford/statspai) · [PyPI](https://pypi.org/project/StatsPAI/) · [Documentation](https://statspai.readthedocs.io/) · [CoPaper.AI](https://copaper.ai)

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "StatsPAI"
7-
version = "0.1.0"
8-
description = "The AI-powered Statistics & Econometrics Toolkit for Python"
7+
version = "0.2.0"
8+
description = "The Causal Inference & Econometrics Toolkit for Python"
99
readme = "README.md"
1010
license = {text = "MIT"}
1111
authors = [

0 commit comments

Comments
 (0)