Skip to content

jsr-p/idid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

idid: instrumented difference-in-differences

idid implements instrumented difference-in-differences (IDiD) estimators for cohort-time local average treatment effects on the treated, $LATT(e,t)$. The package covers both balanced panel data and repeated cross-sections, and includes the doubly robust (DR) and double machine learning (DML) estimators developed in the paper. It also provides tools for aggregating cohort-time effects into event-study and summary parameters, together with plotting utilities for inspecting the aggregated effects.

Links:

Installation

uv pip install git+https://github.com/jsr-p/idid

or from PyPi:

uv pip install idid-py

Try it out

With uv run the following:

uv run --with "git+https://github.com/jsr-p/idid" python -i -c '
import idid
import polars as pl

res = idid.estimate(
    data=(data := idid.sim_stag_panel(n=10_000, T=5, E_cohorts=[0, 2, 3, 4, 5])),
    cohort="E",
    time="t",
    outcome="Y_t",
    treatment="D_t",
    unit="id",
    covariates=["X"],
    control="never",
    method="dr",
    balanced=True,
    verbose=False,
)
print(res)
res.summary()
'

and inspect the results in the interactive shell.

Minimal Example

import idid

data = idid.sim_stag_panel(n=10_000, T=5, E_cohorts=[0, 2, 3, 4, 5])
print(data.head())
shape: (5, 6)
┌─────┬─────┬─────┬──────────┬─────┬──────────┐
│ id  ┆ E   ┆ t   ┆ X        ┆ D_t ┆ Y_t      │
│ --- ┆ --- ┆ --- ┆ ---      ┆ --- ┆ ---      │
│ i64 ┆ i64 ┆ i64 ┆ f64      ┆ i64 ┆ f64      │
╞═════╪═════╪═════╪══════════╪═════╪══════════╡
│ 0   ┆ 2   ┆ 1   ┆ 0.496714 ┆ 1   ┆ 1.429874 │
│ 0   ┆ 2   ┆ 2   ┆ 0.496714 ┆ 1   ┆ 1.89475  │
│ 0   ┆ 2   ┆ 3   ┆ 0.496714 ┆ 0   ┆ 0.573911 │
│ 0   ┆ 2   ┆ 4   ┆ 0.496714 ┆ 0   ┆ 2.3326   │
│ 0   ┆ 2   ┆ 5   ┆ 0.496714 ┆ 1   ┆ 4.496302 │
└─────┴─────┴─────┴──────────┴─────┴──────────┘
res = idid.estimate(
    data,
    cohort="E",
    time="t",
    outcome="Y_t",
    treatment="D_t",
    unit="id",
    covariates=["X"],
    control="never",
    method="dr",
    balanced=True,
    verbose=False,
)
res.summary()
Cohort-Time Local Average Treatment Effects on the Treated:
 E   t    AET(e, t)   LATT(e, t)   Std. Error   [95% Pointwise.   Conf. Band]
 2   2       0.1950       1.2059       0.2793            0.6586        1.7533  *
 2   3       0.1918       0.9700       0.2806            0.4201        1.5200  *
 2   4       0.2445       1.0540       0.2245            0.6141        1.4940  *
 2   5       0.2147       1.3310       0.2582            0.8249        1.8371  *
 3   3       0.2117       0.5478       0.2551            0.0478        1.0478  *
 3   4       0.2447       0.7353       0.2188            0.3063        1.1642  *
 3   5       0.2260       0.7074       0.2401            0.2368        1.1781  *
 4   4       0.2656       0.9291       0.2026            0.5320        1.3261  *
 4   5       0.2661       1.0409       0.2047            0.6397        1.4420  *
 5   5       0.2261       0.8852       0.2399            0.4151        1.3554  *
---
Signif. codes: `*' confidence band does not cover 0
Control group: Never treated
Estimation Method: Doubly Robust
dynamic = idid.agg_latt(res, method="dynamic")
dynamic.summary()
Overall summary of ATT's based on event-study/dynamic aggregation:
  LATT    Std. Error    [95%      Conf. Band]
1.0047        0.1281    0.7537         1.2557  *

Dynamic effects:
  Event time    Estimate    Std. Error    [95% Pointwise    Conf. Band]
           0      0.8868        0.0946            0.7013         1.0723  *
           1      0.9157        0.1215            0.6775         1.1539  *
           2      0.8853        0.1631            0.5656         1.2051  *
           3      1.3310        0.2582            0.8249         1.8371  *
---
Signif. codes: `*' confidence band does not cover 0
Control group: Never treated
Estimation Method: Doubly Robust

Documentation

For the user guide, see the documentation, in particular the quickstart.

Replication of simulation experiments from paper

Run just replication.

See the Justfile and scripts/sim_exps.py.

Notes

  • When control="never", the never-exposed cohort must be coded as E = 0 (compared to the $E = \infty$ notation in the paper).

Citation

If you use idid, please cite Raaschou-Pedersen (2026).

About

idid: instrumented difference-in-differences

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages