Skip to main content

idid: instrumented difference-in-differences

Project description

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).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

idid_py-0.1.1.tar.gz (47.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

idid_py-0.1.1-py3-none-any.whl (51.1 kB view details)

Uploaded Python 3

File details

Details for the file idid_py-0.1.1.tar.gz.

File metadata

  • Download URL: idid_py-0.1.1.tar.gz
  • Upload date:
  • Size: 47.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for idid_py-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8ec3178e32954ab552d1597fa2d45063be8f57e3d04b3c391696bea2ff1da479
MD5 dcd6246ac55f0aff958015ed835d37b0
BLAKE2b-256 a2cb33afe29f33fafb42c3b49a978033678fae6b86618a2214dea1b4f24a70aa

See more details on using hashes here.

File details

Details for the file idid_py-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: idid_py-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 51.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for idid_py-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9b09509201a35d59f9c54b7f060a64360c72da322886dd32ef7d7599b6937722
MD5 9f1a2d6092372af9f238acd4bc3eb7d2
BLAKE2b-256 858e9fd514ce71db16817642ad2b9f4f03e13e1d4cdc172b0db72294fa264df4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page