Notation
Still assumes
\(y_{it} = \delta D_{it} + \gamma_{i} + \gamma_{t} + \epsilon_{it}\) for \(t=1,...,T\) and \(i=1,...,N\)
\(y_{it} = \delta D_{it} + \gamma_{i} + \gamma_{t} + \epsilon_{it}\) for \(t=1,...,T\) and \(i=1,...,N\)
Most common approach (default in most statistical software)
Equivalent to demeaned model: \[y_{it} - \bar{y}_{i} = \delta (D_{it} - \bar{D}_{i}) + (\gamma_{i} - \bar{\gamma}_{i}) + (\gamma_{t} - \bar{\gamma}_{t}) + (\epsilon_{it} - \bar{\epsilon}_{i})\]
\(\gamma_{i} - \bar{\gamma}_{i} = 0\) since \(\gamma_{i}\) is time-invariant
Requires strict exogeneity assumption (error is uncorrelated with \(D_{it}\) for all time periods)
\(y_{it} = \delta D_{it} + \gamma_{i} + \gamma_{t} + \epsilon_{it}\) for \(t=1,...,T\) and \(i=1,...,N\)
Instead of subtracting the mean, subtract the prior period values \[y_{it} - y_{i,t-1} = \delta(D_{it} - D_{i,t-1}) + (\gamma_{i} - \gamma_{i}) + (\gamma_{t} - \gamma_{t-1}) + (\epsilon_{it} - \epsilon_{i,t-1})\]
Requires exogeneity of \(\epsilon_{it}\) and \(D_{it}\) only for time \(t\) and \(t-1\) (weaker assumption than within estimator)
Sometimes useful to estimate both FE and FD just as a check
library(fixest)
library(modelsummary)
library(causaldata)
reg.dat <- causaldata::gapminder %>%
mutate(lgdp_pc=log(gdpPercap))
m1 <- feols(lifeExp ~ lgdp_pc | country, data=reg.dat)
modelsummary(list("Default FE"=m1),
shape=term + statistic ~ model,
gof_map=NA,
coef_rename=c("lgdp_pc"="Log GDP per Capita"))| Default FE | |
|---|---|
| Log GDP per Capita | 9.769 |
| (0.702) |
library(lmtest)
reg.dat <- causaldata::gapminder %>%
group_by(country) %>%
mutate(lgdp_pc=log(gdpPercap),
lgdp_pc=lgdp_pc - mean(lgdp_pc, na.rm=TRUE),
lifeExp=lifeExp - mean(lifeExp, na.rm=TRUE))
m2 <- lm(lifeExp~ 0 + lgdp_pc , data=reg.dat)
modelsummary(list("Default FE"=m1, "Manual FE"=m2),
shape=term + statistic ~ model,
gof_map=NA,
coef_rename=c("lgdp_pc"="Log GDP per Capita"),
vcov = ~country)| Default FE | Manual FE | |
|---|---|---|
| Log GDP per Capita | 9.769 | 9.769 |
| (0.702) | (0.701) |
Note: feols defaults to clustering at level of FE, lm requires our input
library(plm)
reg.dat <- causaldata::gapminder %>%
mutate(lgdp_pc=log(gdpPercap))
m3 <- plm(lifeExp ~ 0 + lgdp_pc, model="fd", index=c("country","year"), data=reg.dat)
modelsummary(list("Default FE"=m1, "Manual FE"=m2, "Default FD"=m3),
shape=term + statistic ~ model,
gof_map=NA,
coef_rename=c("lgdp_pc"="Log GDP per Capita"))| Default FE | Manual FE | Default FD | |
|---|---|---|---|
| Log GDP per Capita | 9.769 | 9.769 | 5.290 |
| (0.702) | (0.284) | (0.291) |
reg.dat <- causaldata::gapminder %>%
mutate(lgdp_pc=log(gdpPercap)) %>%
group_by(country) %>%
arrange(country, year) %>%
mutate(fd_lifeexp=lifeExp - dplyr::lag(lifeExp),
lgdp_pc=lgdp_pc - dplyr::lag(lgdp_pc)) %>%
na.omit()
m4 <- lm(fd_lifeexp~ 0 + lgdp_pc , data=reg.dat)
modelsummary(list("Default FE"=m1, "Manual FE"=m2, "Default FD"=m3, "Manual FD"=m4),
shape=term + statistic ~ model,
gof_map=NA,
coef_rename=c("lgdp_pc"="Log GDP per Capita"))| Default FE | Manual FE | Default FD | Manual FD | |
|---|---|---|---|---|
| Log GDP per Capita | 9.769 | 9.769 | 5.290 | 5.290 |
| (0.702) | (0.284) | (0.291) | (0.291) |
reg.dat2 <- causaldata::gapminder %>%
mutate(lgdp_pc=log(gdpPercap)) %>%
inner_join(reg.dat %>% select(country, year), by=c("country","year"))
m5 <- feols(lifeExp ~ lgdp_pc | country, data=reg.dat2)
modelsummary(list("Default FE"=m5, "Default FD"=m3, "Manual FD"=m4),
shape=term + statistic ~ model,
gof_map=NA,
coef_rename=c("lgdp_pc"="Log GDP per Capita"))| Default FE | Default FD | Manual FD | |
|---|---|---|---|
| Log GDP per Capita | 8.929 | 5.290 | 5.290 |
| (0.741) | (0.291) | (0.291) |
Don’t want to read too much into this, but…
Want to estimate \(ATT = E[Y_{1}(1)- Y_{0}(1) | D=1]\)
| Pre-Period | Post-Period | |
|---|---|---|
| Treatment | \(E(Y_{0}(0)|D=1)\) | \(E(Y_{1}(1)|D=1)\) |
| Control | \(E(Y_{0}(0)|D=0)\) | \(E(Y_{0}(1)|D=0)\) |
Problem: We don’t see \(E[Y_{0}(1)|D=1]\)
Want to estimate \(ATT = E[Y_{1}(1)- Y_{0}(1) | D=1]\)
| Pre-Period | Post-Period | |
|---|---|---|
| Treatment | \(E(Y_{0}(0)|D=1)\) | \(E(Y_{1}(1)|D=1)\) |
| Control | \(E(Y_{0}(0)|D=0)\) | \(E(Y_{0}(1)|D=0)\) |
Strategy 1: Estimate \(E[Y_{0}(1)|D=1]\) using \(E[Y_{0}(0)|D=1]\) (before treatment outcome used to estimate post-treatment)
Want to estimate \(ATT = E[Y_{1}(1)- Y_{0}(1) | D=1]\)
| Pre-Period | Post-Period | |
|---|---|---|
| Treatment | \(E(Y_{0}(0)|D=1)\) | \(E(Y_{1}(1)|D=1)\) |
| Control | \(E(Y_{0}(0)|D=0)\) | \(E(Y_{0}(1)|D=0)\) |
Strategy 2: Estimate \(E[Y_{0}(1)|D=1]\) using \(E[Y_{0}(1)|D=0]\) (control group used to predict outcome for treatment)
Want to estimate \(ATT = E[Y_{1}(1)- Y_{0}(1) | D=1]\)
| Pre-Period | Post-Period | |
|---|---|---|
| Treatment | \(E(Y_{0}(0)|D=1)\) | \(E(Y_{1}(1)|D=1)\) |
| Control | \(E(Y_{0}(0)|D=0)\) | \(E(Y_{0}(1)|D=0)\) |
Strategy 3: DD
Estimate \(E[Y_{1}(1)|D=1] - E[Y_{0}(1)|D=1]\) using \(E[Y_{0}(1)|D=0] - E[Y_{0}(0)|D=0]\) (pre-post difference in control group used to predict difference for treatment group)
Basic DD Graph
Basic DD Graph, Animated
Key identifying assumption is that of parallel trends
\[E[Y_{0}(1) - Y_{0}(0)|D=1] = E[Y_{0}(1) - Y_{0}(0)|D=0]\]
\[\begin{align} E[Y_{1}(1) - Y_{0}(1)|D=1] &=& \left( E[Y(1)|D=1] - E[Y(1)|D=0] \right) \\ & & - \left( E[Y(0)|D=1] - E[Y(0)|D=0]\right) \end{align}\]
\[y_{it} = \alpha + \beta D_{i} + \lambda \times Post_{t} + \delta \times D_{i} \times Post_{t} + \varepsilon_{it}\]
| Pre | Post | Post - Pre | |
|---|---|---|---|
| Treatment | \(\alpha + \beta\) | \(\alpha + \beta + \lambda + \delta\) | \(\lambda + \delta\) |
| Control | \(\alpha\) | \(\alpha + \lambda\) | \(\lambda\) |
| Diff | \(\beta\) | \(\beta + \delta\) | \(\delta\) |
| Treated | Period | Mean |
|---|---|---|
| Control | Pre | 1.512192 |
| Control | Post | 3.010816 |
| Treated | Pre | 4.517785 |
| Treated | Post | 12.026116 |
In this example:
So the ATT is 6.0097068
| (1) | |
|---|---|
| dTRUE | 3.006 |
| (0.028) | |
| tTRUE | 1.499 |
| (0.028) | |
| dTRUE × tTRUE | 6.010 |
| (0.040) |