Kohei Kawaguchi, Hong Kong University of Science and Technology
\[ \begin{split} \tau_{DID} &= [\mathbb{E}(Y_i| G_i = 1, T_i = 1) - \mathbb{E}(Y_i| G_i = 1, T_i = 0)] \\ &- [\mathbb{E}(Y_i| G_i = 0, T_i = 1) - \mathbb{E}(Y_i| G_i = 0, T_i = 0)]. \end{split} \]
\[ \begin{split} \tau_{DID} &= [\mathbb{E}(Y_i| G_i = 1, T_i = 1) - \mathbb{E}(Y_i| G_i = 1, T_i = 0)]\\ &- [\mathbb{E}(Y_i| G_i = 0, T_i = 1) - \mathbb{E}(Y_i| G_i = 0, T_i = 0)]\\ &= [\mathbb{E}(Y_i(1)| G_i = 1, T_i = 1) - \mathbb{E}(Y_i(0)| G_i = 1, T_i = 0)]\\ &- [\mathbb{E}(Y_i(0)| G_i = 0, T_i = 1) - \mathbb{E}(Y_i(0)| G_i = 0, T_i = 0)]\\ &+ [\mathbb{E}(Y_i(0)|G_i = 1, T_i = 1) - \mathbb{E}(Y_i(0)|G_i = 1, T_i = 1)]\\ &= \mathbb{E}(Y_i(1)| G_i = 1, T_i = 1) - \mathbb{E}(Y_i(0)|G_i = 1, T_i = 1)\\ &+ [\mathbb{E}(Y_i(0)|G_i = 1, T_i = 1) - \mathbb{E}(Y_i(0)| G_i = 1, T_i = 0)]\\ &- [\mathbb{E}(Y_i(0)| G_i = 0, T_i = 1) - \mathbb{E}(Y_i(0)| G_i = 0, T_i = 0)], \end{split} \] - \(\tau_{DID}\) is the average treatment effect on \(G_i = 1, T_i = 1\) plus the difference in the trends between two groups.
\[ \begin{split} \tau_{DID} &= \mathbb{E}(Y_{i1} - Y_{i0}| G_i = 1) - \mathbb{E}(Y_{i1} - Y_{i0}| G_i = 0). \end{split} \] - We can estimate this parameter as a two-way fixed-effect estimator \(\hat{\tau}_{DID}\) of: \[ Y_{it} = \mu_i + \lambda_t + \tau \cdot G_i \cdot t + \epsilon_{it}. \]
\[ \begin{split} \tau_{DID} &= \mathbb{E}(Y_{i1} - Y_{i0}| G_i = 1) - \mathbb{E}(Y_{i1} - Y_{i0}| G_i = 0)\\ &= \mathbb{E}(Y_{i1}(1) - Y_{i0}(0)| G_i = 1) - \mathbb{E}(Y_{i1}(0) - Y_{i0}(0)| G_i = 0)\\ &+ \mathbb{E}(Y_{i1}(0) - Y_{i1}(0)|G_i = 1)\\ &= \mathbb{E}(Y_{i1}(1) - Y_{i1}(0)| G_i = 1)\\ &+ \mathbb{E}(Y_{i1}(0) - Y_{i0}(0)|G_i = 1) - \mathbb{E}(Y_{i1}(0) - Y_{i0}(0)| G_i = 0). \end{split} \]
The parallel trend assumption in the panel case is: \[ \mathbb{E}(Y_{i1}(0) - Y_{i0}(0)|G_i = 1) = \mathbb{E}(Y_{i1}(0) - Y_{i0}(0)| G_i = 0). \]
This holds when: \[ Y_{it}(1) - Y_{it}(0) \perp\!\!\!\!\perp G_i. \]
Under this assumption, the DID parameter is the average treatment effect on treated: \[ \tau_{DID} = \mathbb{E}(Y_{i1}(1) - Y_{i0}(0)| G_i = 1). \]
\[ \begin{split} &= \mathbb{E}\Bigg[\frac{G_i - p(X_i)}{p(X_i) \cdot [1 - p(X_i)]} \cdot (Y_{i1} - Y_{i0}) \cdot \frac{p(X_i)}{\mathbb{P}(G_i = 1)} \Bigg]\\ &= \frac{1}{\mathbb{P}(G_i = 1)} \mathbb{E}\Bigg[\frac{G_i - p(X_i)}{1 - p(X_i)} \cdot (Y_{i1} - Y_{i0}) \Bigg]. \end{split} \]
set.seed(1) N <- 1000 T <- 2 tau <- 10 f <- function(x) { y <- x return(y) } g <- function(x) { y <- exp(x) return(y) }
df_i <- tibble::tibble( i = 1:N, x = rnorm(length(i)), v = rnorm(length(i)), d = (runif(length(i)) < exp(g(x)) / (1 + exp(g(x))) ) %>% as.integer() ) df <- tidyr::expand_grid(i = 1:N, t = 0:(T - 1)) %>% dplyr::left_join(df_i, by = "i") %>% dplyr::mutate( e_0 = rnorm(length(i)), e_1 = rnorm(length(i)), y_0 = f(x) * t + e_0, y_1 = tau + x + f(x) * t + e_1, y = (1 - d) * y_0 + d * (1 - t) * y_0 + d * t * y_1 )
df %>% modelsummary::datasummary_skim()
Unique (#) | Missing (%) | Mean | SD | Min | Median | Max | ||
---|---|---|---|---|---|---|---|---|
i | 1000 | 0 | 500.5 | 288.7 | 1.0 | 500.5 | 1000.0 | |
t | 2 | 0 | 0.5 | 0.5 | 0.0 | 0.5 | 1.0 | |
x | 1000 | 0 | -0.0 | 1.0 | -3.0 | -0.0 | 3.8 | |
v | 1000 | 0 | -0.0 | 1.0 | -3.3 | -0.0 | 3.6 | |
d | 2 | 0 | 0.7 | 0.4 | 0.0 | 1.0 | 1.0 | |
e_0 | 2000 | 0 | 0.0 | 1.0 | -3.7 | 0.0 | 3.1 | |
e_1 | 2000 | 0 | -0.0 | 1.0 | -3.2 | -0.0 | 3.6 | |
y_0 | 2000 | 0 | 0.0 | 1.3 | -4.6 | 0.0 | 4.4 | |
y_1 | 2000 | 0 | 10.0 | 1.9 | 2.6 | 10.0 | 18.9 | |
y | 2000 | 0 | 3.8 | 5.3 | -4.0 | 0.8 | 18.9 |
df %>% dplyr::mutate(t = as.factor(t)) %>% ggplot(aes(x = x, y = d, color = t, group = t)) + geom_smooth(method = "gam", formula = y ~ s(x, bs = "cs"), se = FALSE) + scale_color_viridis_d() + theme_classic()
df %>% dplyr::mutate(t = as.factor(t)) %>% ggplot(aes(x = x, y = y_0, color = t, group = t)) + geom_point() + scale_color_viridis_d() + theme_classic()
df %>% dplyr::mutate(t = as.factor(t)) %>% ggplot(aes(x = x, y = y_1, color = t, group = t)) + geom_point() + scale_color_viridis_d() + theme_classic()
df %>% dplyr::mutate(t = as.factor(t)) %>% dplyr:::mutate(tau_i = y_1 - y_0) %>% ggplot(aes(x = x, y = tau_i, color = t, group = t)) + geom_point() + scale_color_viridis_d() + theme_classic()
df %>% dplyr::filter(t == 1, d == 1) %>% dplyr::summarise(mean(y_1 - y_0))
## # A tibble: 1 x 1 ## `mean(y_1 - y_0)` ## <dbl> ## 1 10.2
model_twfe <- lfe::felm( data = df, formula = y ~ d:t | i + t ) modelsummary::modelsummary(model_twfe)
Model 1 | |
---|---|
d × t | 10.709 |
(0.171) | |
Num.Obs. | 2000 |
R2 | 0.951 |
R2 Adj. | 0.901 |
model_ordid <- DRDID::ordid(data = df, yname = "y", tname = "t", idname = "i",dname = "d", xformla = ~ x ) summary(model_ordid)
## Call: ## DRDID::ordid(yname = "y", tname = "t", idname = "i", dname = "d", ## xformla = ~x, data = df) ## ------------------------------------------------------------------ ## Outcome-Regression DID estimator for the ATT: ## ## ATT Std. Error t value Pr(>|t|) [95% Conf. Interval] ## 9.9773 0.1336 74.6829 0 9.7154 10.2391 ## ------------------------------------------------------------------ ## Estimator based on panel data. ## Outcome regression est. method: OLS. ## Analytical standard error. ## ------------------------------------------------------------------ ## See Sant'Anna and Zhao (2020) for details.
model_ipwdid <- DRDID::ipwdid(data = df, yname = "y", tname = "t", idname = "i",dname = "d", xformla = ~ x ) summary(model_ipwdid)
## Call: ## DRDID::ipwdid(yname = "y", tname = "t", idname = "i", dname = "d", ## xformla = ~x, data = df) ## ------------------------------------------------------------------ ## IPW DID estimator for the ATT: ## ## ATT Std. Error t value Pr(>|t|) [95% Conf. Interval] ## 10.273 0.1308 78.5239 0 10.0165 10.5294 ## ------------------------------------------------------------------ ## Estimator based on panel data. ## Hajek-type IPW estimator (weights sum up to 1). ## Propensity score est. method: maximum likelihood. ## Analytical standard error. ## ------------------------------------------------------------------ ## See Sant'Anna and Zhao (2020) for details.
model_drdid <- DRDID::drdid(data = df, yname = "y", tname = "t", idname = "i",dname = "d", xformla = ~ x ) summary(model_drdid)
## Call: ## DRDID::drdid(yname = "y", tname = "t", idname = "i", dname = "d", ## xformla = ~x, data = df) ## ------------------------------------------------------------------ ## Further improved locally efficient DR DID estimator for the ATT: ## ## ATT Std. Error t value Pr(>|t|) [95% Conf. Interval] ## 9.9616 0.1366 72.9093 0 9.6938 10.2294 ## ------------------------------------------------------------------ ## Estimator based on panel data. ## Outcome regression est. method: weighted least squares. ## Propensity score est. method: inverse prob. tilting. ## Analytical standard error. ## ------------------------------------------------------------------ ## See Sant'Anna and Zhao (2020) for details.