DiD avec Hétérogénéité

Module 5 — de Chaisemartin & D’Haultfoeuille (2020)

Master GPE — FERDI IHEDD

2026-03-17

Une troisième approche — intuition différente

Callaway & Sant’Anna : Estiment \(ATT(g,t)\) pour chaque cohorte et période. Comparent chaque groupe à un groupe propre (jamais traité).

de Chaisemartin & D’Haultfoeuille : Se concentrent sur les “switchers” — unités qui changent leur statut de traitement entre deux périodes.

→ Comparer les switchers à des unités avec le même traitement de base qui ne changent pas.

Reference paper :

de Chaisemartin, C., & D’Haultfoeuille, X. (2020). Two-Way Fixed Effects Estimators with Heterogeneous Treatment Effects. AER, 110(9), 2964–2996.

Problème du TWFE — rappel avec notation CdH

de Chaisemartin & D’Haultfoeuille (2020) montrent que :

\[\hat{\delta}_{TWFE} = \sum_{(i,t): D_{it} \neq D_{i,t-1}} w_{it} \cdot \Delta Y_{it}\]

Le coefficient TWFE est une moyenne pondérée des effets par paires (unité, période), mais certains poids \(w_{it}\) peuvent être négatifs !

Conséquence : Même si tous les effets individuels sont positifs, le TWFE peut donner un résultat négatif.

Les “switchers” — intuition centrale

Switchers : Unités dont le traitement change entre \(t-1\) et \(t\) : - Switch-in (\(0 \to 1\)) : passent de non-traité à traité - Switch-out (\(1 \to 0\)) : passent de traité à non-traité (si possible)

“Stayers” : Unités dont le traitement reste constant entre \(t-1\) et \(t\)

→ Les stayers servent de contrôles pour les switchers

L’estimateur \(DID_M\) :

Pour chaque paire (switcher, stayer avec même statut de base), on calcule une DiD locale.

\(DID_M\) = moyenne de ces DiD locales

L’estimateur \(DID_M\) — formule

Condition : “sharp design” — le traitement \(D_{it} \in \{0, 1\}\)

\[DID_M = \sum_{(i,t): \text{switcher}} w_{it} \left[ (Y_{it} - Y_{it-1}) - \frac{1}{|\mathcal{C}_{it}|} \sum_{j \in \mathcal{C}_{it}} (Y_{jt} - Y_{jt-1}) \right]\]

  • \(\mathcal{C}_{it}\) : ensemble des stayers avec le même statut de traitement que le switcher à \(t-1\)
  • \(w_{it}\) : poids proportionnels à la taille du groupe

Note

Cet estimateur est une généralisation directe de la DiD 2×2 : chaque terme est une DiD entre un switcher et son groupe de contrôle “propre”.

Extension dynamique — did_multiplegt_dyn

Chaisemartin & D’Haultfoeuille (2024) :

L’estimateur \(DID_M\) donne un effet moyen global. Pour un event study :

\[\ell \text{ périodes après le switch} : \delta^+_\ell\]

Estimé en comparant les switchers à \(\ell\) périodes après leur traitement aux stayers correspondants.

→ Permet de tester les tendances parallèles (\(\hat{\delta}^{pre}\)) et la dynamique post-traitement.

Les données de de Chaisemartin — favara_imbs

Le dataset Favara & Imbs (2015) est fourni directement dans le package DIDmultiplegtDYN :

Voir le code R
library(DIDmultiplegtDYN)
data(favara_imbs)
glimpse(favara_imbs)
#> Rows: 1,157
#> Columns: 7
#> $ year        <dbl> 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003…
#> $ county      <dbl> 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001…
#> $ state_n     <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
#> $ Dl_vloans_b <dbl> 0.27024763, -0.03842705, 0.16163332, 0.05652315, 0.0342358…
#> $ inter_bra   <dbl> 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1…
#> $ w1          <dbl> 0.975312, 0.975312, 0.975312, 0.975312, 0.975312, 0.975312…
#> $ Dl_hpi      <dbl> 0.003176090, 0.048912131, 0.058203205, 0.044365996, 0.0470…

Description de favara_imbs

Données : Panel de comtés américains, 1994–2005

Variables clés : - county : identifiant du comté - year : année - inter_bra : indice de déréglementation bancaire (0–4) — traitement discret - Dl_hpi : variation du prix des logements (log) - Dl_vloans_b : variation du crédit hypothécaire (log)

Question de recherche : La déréglementation bancaire (accroissement de la concurrence inter-états) augmente-t-elle les prix de l’immobilier via une expansion du crédit ?

Atout : Traitement continu (0–4) — parfait pour did_multiplegt_dyn !

Le package DIDmultiplegtDYN en R

Voir le code R
library(DIDmultiplegtDYN)
data(favara_imbs)

# Application sur les données de Favara & Imbs (2015)
result_fi <- did_multiplegt_dyn(
  df        = favara_imbs,
  outcome   = "Dl_hpi",    # variation log prix immobilier
  group     = "county",    # comté
  time      = "year",      # année
  treatment = "inter_bra", # indice de déréglementation (0-4)
  effects   = 5,           # 5 périodes post
  placebo   = 3,           # 3 placebos pré-traitement
  cluster   = "state_n"    # clustering au niveau état
)

Résultats de did_multiplegt_dyn

Voir le code R
summary(result_fi)
#> 
#> ----------------------------------------------------------------------
#>        Estimation of treatment effects: Event-study effects
#> ----------------------------------------------------------------------
#>              Estimate SE      LB CI    UB CI   N   Switchers
#> Effect_1     0.00123  0.00791 -0.01427 0.01674 293 70       
#> Effect_2     0.01257  0.01420 -0.01527 0.04040 225 69       
#> Effect_3     0.02645  0.01711 -0.00709 0.05998 198 69       
#> Effect_4     0.03719  0.01714 0.00359  0.07079 177 69       
#> Effect_5     0.06115  0.02293 0.01620  0.10609 177 69       
#> 
#> Test of joint nullity of the effects : p-value = 0.0000
#> ----------------------------------------------------------------------
#>     Average cumulative (total) effect per treatment unit
#> ----------------------------------------------------------------------
#>  Estimate        SE     LB CI     UB CI         N Switchers 
#>   0.02293   0.01068   0.00200   0.04387       677       346 
#> Average number of time periods over which a treatment effect is accumulated: 3.0096
#> 
#> ----------------------------------------------------------------------
#>      Testing the parallel trends and no anticipation assumptions
#> ----------------------------------------------------------------------
#>              Estimate SE      LB CI    UB CI   N   Switchers
#> Placebo_1    0.00358  0.00826 -0.01260 0.01976 196 67       
#> Placebo_2    -0.01480 0.02917 -0.07198 0.04237 81  27       
#> Placebo_3    -0.03739 0.05448 -0.14417 0.06939 48  21       
#> 
#> Test of joint nullity of the placebos : p-value = 0.1305
#> 
#> 
#> ----------------------------------------------------------------------
#>     Warnings
#> ----------------------------------------------------------------------
#> - The F-test that all effects are equal to zero may not be reliable, because the variance of the effects is close to not being invertible (the ratio of its largest and smallest eigenvalues is larger than 1000). This can for instance happen when you compute many effects estimators, or when your effects are very strongly correlated.
#> - The F-test that all placebos are equal to zero may not be reliable, because the variance of the placebos is close to not being invertible (the ratio of its largest and smallest eigenvalues is larger than 1000). This can for instance happen when you compute many placebo estimators, or when your placebos are very strongly correlated.
#> 
#> The development of this package was funded by the European Union.
#> ERC REALLYCREDIBLE - GA N. 101043899

Graphique event study — did_multiplegt_dyn

Voir le code R
# Le graphique est accessible via l'élément $plot de l'objet résultat
result_fi$plot +
  ggplot2::labs(
    title = "Event Study — Favara & Imbs (2015)",
    subtitle = "Impact de la déréglementation bancaire sur les prix immobiliers",
    x = "Périodes relatives au changement de déréglementation",
    y = "Effet estimé (variation log prix)"
  )

Astuce

Le graphique affiche automatiquement : - Les effets post-traitement \(\delta^+_1, \ldots, \delta^+_\ell\) avec intervalles de confiance - Les placebos pré-traitement \(\delta^{pre}_{-1}, \ldots\) (doivent être ≈ 0) - Un ATT global agrégé

Comparaison des trois approches

Voir le code R
# TWFE
twfe_est <- feols(lemp ~ treat_tv | countyreal + year, data = mpdta, cluster = ~countyreal)

# CS simple
att_gt_res <- att_gt(yname = "lemp", tname = "year", idname = "countyreal",
                     gname = "first.treat", data = mpdta,
                     control_group = "nevertreated", print_details = FALSE)
cs_est <- aggte(att_gt_res, type = "simple")

# Résultats CdH sur favara_imbs (ATT agrégé moyen)
chm_att <- result_fi$results$ATE[1]  # Première valeur = estimateur ATT

# Tableau de comparaison (note : CdH utilise des données différentes ici)
tibble(
  Méthode    = c("TWFE (mpdta)", "Callaway-Sant'Anna (mpdta)", "de Chaisemartin (favara_imbs)"),
  Estimateur = c(round(coef(twfe_est)["treat_tv"], 4),
                 round(cs_est$overall.att, 4),
                 round(chm_att, 4)),
  Données    = c("mpdta", "mpdta", "favara_imbs"),
  Contexte   = c("Salaire min → emploi jeunes", "Salaire min → emploi jeunes",
                 "Déréglementation bancaire → prix immo")
) |> knitr::kable(digits = 4)
Méthode Estimateur Données Contexte
TWFE (mpdta) -0.0365 mpdta Salaire min → emploi jeunes
Callaway-Sant’Anna (mpdta) -0.0400 mpdta Salaire min → emploi jeunes
de Chaisemartin (favara_imbs) 0.0229 favara_imbs Déréglementation bancaire → prix immo

Quelle méthode choisir ?

TWFE : - ✅ Simple et rapide - ✅ Extensions multiples (covariables, IV…) - ❌ Biaisé si traitement échelonné + hétérogénéité - 📌 Quand : Traitement simultané ou très homogène

Callaway & Sant’Anna : - ✅ Robuste à l’hétérogénéité - ✅ Event study propre par cohorte - ✅ Flexible sur les covariables - 📌 Quand : Traitement échelonné, hétérogénéité attendue

de Chaisemartin & D’Haultfoeuille : - ✅ Robuste à l’hétérogénéité - ✅ Traitement binaire et continu - ✅ Switch-in et switch-out - ✅ Correction automatique des poids négatifs - 📌 Quand : Traitement continu ou variation complexe

En pratique : Utilisez les trois et comparez. Des résultats cohérents renforcent la validité.

Recommandations pratiques

  1. Toujours visualiser les données avant d’estimer : distribution du traitement, timing, covariables

  2. Tester les pré-tendances systématiquement (graphique event study)

  3. Utiliser les erreurs standard groupées au niveau de l’unité de traitement

  4. Présenter plusieurs estimateurs (TWFE + CS ou CdH) et discuter les différences

  5. Vérifier l’hypothèse de traitement irréversible — si possible switch-out, CdH est préféré

  6. Interpréter les ATT conditionnellement à l’hypothèse de tendances parallèles (qui doit être justifiée théoriquement)

Ressources pour aller plus loin

Packages R essentiels : - did : Callaway & Sant’Anna — bcallaway11.github.io/did - DIDmultiplegtDYN : de Chaisemartin — CRAN - fixest : TWFE et Sun & Abraham — lrberge.github.io/fixest - bacondecomp : Décomposition Goodman-Bacon - HonestDiD : Sensibilité aux violations des tendances parallèles (Rambachan & Roth, 2023)

Revues de littérature : - Roth et al. (2023). What’s Trending in Difference-in-Differences? Journal of Econometrics. - de Chaisemartin & D’Haultfoeuille (2022). Two-Way Fixed Effects and Differences-in-Differences with Heterogeneous Treatment Effects: A Survey. NBER WP.

Tutoriels pratiques : - Callaway & Sant’Anna vignette : vignette("did-basics", package = "did") - de Chaisemartin handbook : github.com/chaisemartinPackages

Récapitulatif général du cours

Ce que vous avez appris en 6 heures :

Module Contenu Compétence R
1 Cadre causal, biais de sélection Base R + visualisation
2 DiD 2×2, tendances parallèles lm(), ggplot2
3 TWFE, effets fixes, event study fixest::feols()
4 Staggered DiD, ATT(g,t), CS did::att_gt()
5 DID_M, switchers, CdH DIDmultiplegtDYN

Astuce

La DiD est un outil puissant, mais ses résultats dépendent entièrement de la validité de l’hypothèse de tendances parallèles — justifiez-la toujours par la théorie et les données.