Método de Diferencias en Diferencias (DiD)

Author

Carlos Pineda

Published

November 6, 2025

Introducción

El método de Diferencias en Diferencias (DiD) se utiliza para evaluar el efecto causal de una intervención o política pública cuando no se dispone de un experimento aleatorizado.

La idea principal es comparar la diferencia temporal en el grupo tratado antes y después de la intervención, con la diferencia correspondiente en un grupo de control.

Formulación teórica

Sea:

  • \(Y_{it}\): resultado (por ejemplo, ingreso, salud, gasto)
  • ( \(D_i\) = 1 ) si el individuo pertenece al grupo tratado, ( \(D_i\) = 0 ) si es control
  • ( \(Post_t\) = 1 ) después de la intervención, ( 0 ) antes

El modelo lineal básico de DiD es:

\[ Y_{it} = \alpha + \beta D_i + \gamma Post_t + \delta (D_i \times Post_t) + \epsilon_{it} \]

Donde:

  • ( \(\delta\) ): efecto de tratamiento promedio (ATT), es la estimación de interés.

Ejemplo numérico simple

Grupo Antes Después Diferencia
Tratado 50 70 +20
Control 45 50 +5

DiD = (70 - 50) - (50 - 45) = 15

Interpretación: el programa incrementó el resultado promedio en 15 unidades adicionales respecto al grupo de control.

Simulación de datos

Vamos a simular datos de dos programas sociales:

  • Programa A (tratado): intervención a partir del año 2
  • Programa B (control): sin intervención
Code
set.seed(123)

n <- 200
data <- tibble(
  id = 1:n,
  grupo = rep(c("Tratado", "Control"), each = n/2),
  year = rep(rep(c(1, 2), each = n/4), 2)
)

# Generamos el outcome con efecto del programa solo en tratados después del año 2
data <- data %>%
  mutate(
    post = ifelse(year == 2, 1, 0),
    treat = ifelse(grupo == "Tratado", 1, 0),
    y = 50 + 5*treat + 3*post + 10*(treat*post) + rnorm(n, 0, 5)
  )

head(data)
# A tibble: 6 × 6
     id grupo    year  post treat     y
  <int> <chr>   <dbl> <dbl> <dbl> <dbl>
1     1 Tratado     1     0     1  52.2
2     2 Tratado     1     0     1  53.8
3     3 Tratado     1     0     1  62.8
4     4 Tratado     1     0     1  55.4
5     5 Tratado     1     0     1  55.6
6     6 Tratado     1     0     1  63.6

Visualización descriptiva

Code
data %>%
  group_by(grupo, year) %>%
  summarise(promedio = mean(y)) %>%
  ggplot(aes(x = year, y = promedio, color = grupo, group = grupo)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  labs(title = "Evolución del resultado promedio por grupo",
       x = "Año", y = "Valor promedio del outcome",
       color = "Grupo") +
  theme_minimal(base_size = 14)

Estimación con modelo DiD

Code
modelo_did <- lm(y ~ treat + post + treat:post, data = data)
summary(modelo_did)

Call:
lm(formula = y ~ treat + post + treat:post, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-12.2779  -3.0311  -0.4157   2.7838  16.0112 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  48.7305     0.6636  73.437  < 2e-16 ***
treat         6.4415     0.9384   6.864 8.59e-11 ***
post          4.4635     0.9384   4.756 3.81e-06 ***
treat:post    9.0965     1.3271   6.854 9.09e-11 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.692 on 196 degrees of freedom
Multiple R-squared:  0.7207,    Adjusted R-squared:  0.7164 
F-statistic: 168.6 on 3 and 196 DF,  p-value: < 2.2e-16
Code
#tidy(modelo_did)

pander::pander(tidy(modelo_did))
term estimate std.error statistic p.value
(Intercept) 48.73 0.6636 73.44 1.462e-144
treat 6.442 0.9384 6.864 8.592e-11
post 4.464 0.9384 4.756 3.814e-06
treat:post 9.096 1.327 6.854 9.088e-11

Interpretación

  • El coeficiente estimado de treat:post10, lo cual coincide con el efecto verdadero simulado.
  • Esto significa que, en promedio, el programa social aumentó el resultado en 10 unidades más respecto al cambio observado en el grupo control.
  • Los demás coeficientes indican:
    • treat: diferencia base entre grupos antes de la intervención.
    • post: cambio temporal general para ambos grupos.

Visualización del efecto DiD

Code
promedios <- data %>%
  group_by(grupo, post) %>%
  summarise(media = mean(y))

ggplot(promedios, aes(x = post, y = media, color = grupo, group = grupo)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  geom_vline(xintercept = 0.5, linetype = "dashed") +
  annotate("text", x = 1.5, y = 70, label = "Efecto DiD", color = "black", size = 5) +
  labs(title = "Representación gráfica del efecto Diferencias en Diferencias",
       x = "Periodo (0=Antes, 1=Después)",
       y = "Media del outcome") +
  theme_minimal(base_size = 14)

Conclusiones

  • El método DiD permite aislar el efecto causal bajo el supuesto de tendencias paralelas.
  • Es ampliamente utilizado en políticas públicas, economía de la salud y evaluación de programas sociales.
  • Puede extenderse a modelos de panel, múltiples periodos y heterogeneidad de efectos.

📚 Referencias

  • Angrist, J. & Pischke, J. (2009). Mostly Harmless Econometrics.
  • Abadie, A. (2005). Semiparametric Difference-in-Differences Estimators.
  • Bertrand, Duflo & Mullainathan (2004). How Much Should We Trust Differences-in-Differences Estimates?