6.9 The \(2 \times 2\) Difference-in-Differences Estimate
Now that we’ve disscussed the difference-in-differences framework (mostly canonical DiD), we would like to look at various ways of estimating DiD. As we’ve seen, (a canonical) DiD estimation can simply be done non-parametrically by using the appropriate differences in means. Another way to do it is by using the regression framework, which provides several advantages including but not limited to: \(i)\) estimation of standard errors; \(ii)\) ease of accounting for necessary covariates; and \(iii)\) feasible estimation of DiD with multiple treatment groups with staggered treatment.
Let’s begin with the canonical DiD framework using the regression format. I’m going to set it up as the following:
\[\begin{equation} \label{eq:DiD_reg} Y_{it} = \alpha + \tau Post_{it} \times D_{i} + \sigma Post_{it} + \eta D_{i} + \epsilon_{it} \end{equation}\]
Let’s rewrite the DiD estimator from before as:
\(\tau_{did} = \underbrace{E[Y_{11} - Y_{10} | D = 1]}_{first\; difference} - \underbrace{E[Y_{01} - Y_{00} | D = 0]}_{second\; difference}\)
We’d want to see whether estimation of \(\tau\) in the regression above uncovers the DiD estimate. Let’s look at the following conditional expectations.
1). expected outcome for treated group post treatment: \(E(Y | D = 1, Post = 1) = \alpha + \tau + \sigma + \eta\)
2). expected outcome for treated group pre treatment: \(E(Y | D = 1, Post = 0) = \alpha + \eta\)
3). expected outcome for control group post treatment: \(E(Y | D = 0, Post = 1) = \alpha + \sigma\)
4). expected outcome for control group pre treatment: \(E(Y | D = 0, Post = 0) = \alpha\)
If you do the math, the first difference is given as \(\tau + \sigma\) and the second difference is \(\sigma\). The DiD – the difference between the first and the second difference – is \(\tau\). Hence, the estimation of \(\tau\), in the regression framework above, is the DiD estimate.
Let’s apply this to our ACA-Medicaid example.
# lets create the post, treat, and the interaction between the post and treat (labeled as did)
<- dat_canonical %>%
dat_canonical mutate(post = ifelse(year >= 2014, 1, 0),
treat = ifelse(expand == 1, 1, 0),
did = post * treat)
<- lm(sahieunins138 ~ did + post + treat, data = dat_canonical)
reg_did summary(reg_did)
##
## Call:
## lm(formula = sahieunins138 ~ did + post + treat, data = dat_canonical)
##
## Residuals:
## Min 1Q Median 3Q Max
## -25.2196 -5.1221 -0.7641 4.7804 26.7359
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.4641 0.1890 219.41 <2e-16 ***
## did -5.8134 0.4126 -14.09 <2e-16 ***
## post -4.7840 0.2673 -17.89 <2e-16 ***
## treat -7.8445 0.2918 -26.89 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.655 on 5650 degrees of freedom
## Multiple R-squared: 0.425, Adjusted R-squared: 0.4247
## F-statistic: 1392 on 3 and 5650 DF, p-value: < 2.2e-16
<- naive - naive_pre
did print(did)
## [1] -5.813426
Note that the difference in mean did and the regression coefficient on the interaction between \(Post \times treat\) are the same. Plus, we get the standard errors as well. Of course, the standard errors are not adjusted for clustering. The errors of observations within a cluster (the ground at which the treatment is implemented, in our case state) will be correlated, so we need to account for it. The way to do it is to cluster the standard error at the state level. This can be done using the fixest library and feols command.
<- feols(sahieunins138 ~ did + post + treat, data = dat_canonical, cluster = ~state.abb)
reg_did_cluster summary(reg_did_cluster)
## OLS estimation, Dep. Var.: sahieunins138
## Observations: 5,654
## Standard-errors: Clustered (state.abb)
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.46411 2.041183 20.31376 < 2.2e-16 ***
## did -5.81343 1.266824 -4.58898 3.6981e-05 ***
## post -4.78400 0.278769 -17.16117 < 2.2e-16 ***
## treat -7.84455 2.612190 -3.00305 4.3962e-03 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## RMSE: 7.65276 Adj. R2: 0.424736
Note that the did coefficient remains unchanged. However, the standard error is inflated after clustering the errors at the state level.