SuperAPI AI Directory

alterlab-causal-inference

Data & analytics

View repository

Updated 10-15 19:56

About this skill

Causal Inference — Name the Assumption, Estimate, Then Try to Break It

Skill type: ANALYSIS MODULE. Estimates a causal effect from data that was not fully randomized. The discipline is not the estimator — it is the identifying assumption the estimator relies on, stated before the fit and stress-tested after. If the design is not yet fixed, that belongs upstream in alterlab-ssci-design-gate.

Core Mission

EVERY CAUSAL ESTIMATE INHERITS AN ASSUMPTION. STATE IT, ESTIMATE UNDER IT, THEN REFUTE IT.

When to Use This Skill

  • "Estimate the effect with difference-in-differences / an event study."
  • "I have an instrument for the treatment — run instrumental variables / 2SLS."
  • "There's a cutoff score — run a regression discontinuity."
  • "Panel data with unit and time fixed effects — estimate the treatment effect."
  • "Give me the heterogeneous treatment effect / CATE across subgroups."

Does NOT Trigger

The request is really about… Route to Why not this skill
Choosing the design & its identifying assumption alterlab-ssci-design-gate Design routing precedes estimation.
Plain OLS / descriptive or inferential stats (no causal identification) alterlab-statistical-analysis / alterlab-statsmodels No treatment-effect identification problem.
Latent-variable / SEM / factor structure alterlab-sem-psychometrics Measurement model, not treatment effect.
Auditing whether the final claim is licensed alterlab-ssci-inference-gate Claim audit, downstream.

Estimator map (verified libraries, pinned)

Design Identifying assumption Estimator (verified API)
DiD / event study parallel trends pyfixest (v0.60): `pf.feols("y ~ i(year, treat, ref=2018)
Panel fixed effects no time-varying confounders linearmodels (v7): PanelOLS.from_formula("y ~ 1 + x + EntityEffects + TimeEffects", panel).fit(cov_type='clustered', cluster_entity=True).
Instrumental variables exclusion restriction + relevance linearmodels IV2SLS.from_formula("y ~ 1 + exog + [treat ~ z1 + z2]", df).fit(); check first-stage F (weak instrument).
Regression discontinuity continuity at the cutoff (no sorting) rdrobust (v2): rdrobust(y, x, c=cutoff), rdbwselect, rdplot; McCrary/density check for manipulation.
Selection-on-observables conditional ignorability DoWhy (v0.14): CausalModel(df, treatment, outcome, graph).identify_effect() → estimate_effect(method_name="backdoor.propensity_score_matching") → refute_estimate(..., method_name="random_common_cause").
Heterogeneous effects (CATE) (as above) + overlap EconML (v0.17): LinearDML() / CausalForestDML() .fit(Y, T, X=X, W=W) then .effect(X).

A stdlib router that maps the design to the estimator + its assumption + the verified call: scripts/estimator_router.py. Fuller worked patterns and diagnostics: references/estimators.md.

The mandatory two steps around every estimate

  1. Before: write the identifying assumption in one sentence and how you will defend it (pre-trend plot for DiD, first-stage F and an exclusion argument for IV, density/McCrary test for RDD, overlap/common-support for PSM). No assumption, no causal estimate.
  2. After: run a refutation/robustness check — DoWhy.refute_estimate (random common cause, placebo treatment, data subset), a pre-trend/event-study plot, a bandwidth-sensitivity for RDD, or an E-value / sensitivity analysis for unmeasured confounding. Report it next to the estimate.

Output Template

DESIGN + ASSUMPTION: <e.g. DiD; parallel trends, defended by the pre-2019 event-study plot>
ESTIMATOR:           <library.call(...), pinned version>
ESTIMATE:            <point estimate, 95% CI, clustered SE — never a bare p-value>
DIAGNOSTIC:          <first-stage F / density test / pre-trends / overlap>
REFUTATION:          <placebo / random-common-cause / bandwidth sensitivity result>
CLAIM SCOPE:         causal IFF the assumption + diagnostics hold; else associational

Quality Standards

  • Report effect sizes with confidence intervals and the SE structure (clustered where relevant).
  • Never present a causal estimate without its diagnostic and at least one refutation.
  • Hand the final estimate + assumption to alterlab-ssci-inference-gate for the claim audit.
  • No fabricated flags: every call above is verified against the library's current docs; if a flag is unverified in your installed version, check --help/docs, do not guess.

References

  • references/estimators.md — per-design worked calls, diagnostics, and refutation menu.
  • scripts/estimator_router.py — stdlib design→estimator+assumption router.

Part of the AlterLab Academic Skills suite.