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…