5.1 — Fixed Effects

ECON 480 • Econometrics • Fall 2022

Dr. Ryan Safner
Associate Professor of Economics

safner@hood.edu
ryansafner/metricsF22
metricsF22.classes.ryansafner.com

Contents

Panel Data

Pooled Regression

Fixed Effects Model

Least Squares Dummy Variable Approach

De-Meaned Approach

Two-Way Fixed Effects

Panel Data

Types of Data I

  • Cross-sectional data: compare different individual i’s at same time ˉt
ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
deaths
<dbl>
cell_plans
<dbl>
Alabama201213.3160569433.800
Alaska201212.3119768872.799
Arizona201213.7204198810.889
Arkansas201216.46673010047.027
California20128.7565079362.424
Colorado201210.0922049403.225
6 rows

Types of Data I

  • Cross-sectional data: compare different individual i’s at same time ˉt
ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
deaths
<dbl>
cell_plans
<dbl>
Alabama201213.3160569433.800
Alaska201212.3119768872.799
Arizona201213.7204198810.889
Arkansas201216.46673010047.027
California20128.7565079362.424
Colorado201210.0922049403.225
6 rows
  • Time-series data: track same individual ˉi over different times t
ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
deaths
<dbl>
cell_plans
<dbl>
Maryland200710.8666798942.137
Maryland200810.7409639290.689
Maryland20099.8927549339.452
Maryland20108.7838839630.120
Maryland20118.62674510335.795
Maryland20128.94191610393.295
6 rows

Types of Data II

  • Cross-sectional data: compare different individual i’s at same time ˉt

ˆYi=β0+β1Xi+ui

  • Time-series data: track same individual ˉi over different times t

ˆYt=β0+β1Xt+ut

  • Panel data: combines these dimensions: compare all individual i’s over all time t’s

Panel Data I

Panel Data II

ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
deaths
<dbl>
cell_plans
<dbl>
Alabama200718.0752328135.525
Alabama200816.2892278494.391
Alabama200913.8336788979.108
Alabama201013.4340849054.894
Alabama201113.7719899340.501
Alabama201213.3160569433.800
Alaska200716.3011846730.282
Alaska200812.7440905580.707
Alaska200912.9738498389.730
Alaska201011.6708938560.595
Next
123456
...
31
Previous
1-10 of 306 rows
  • Panel or Longitudinal data contains
    • repeated observations (t)
    • on multiple individuals (i)

Panel Data II

ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
deaths
<dbl>
cell_plans
<dbl>
Alabama200718.0752328135.525
Alabama200816.2892278494.391
Alabama200913.8336788979.108
Alabama201013.4340849054.894
Alabama201113.7719899340.501
Alabama201213.3160569433.800
Alaska200716.3011846730.282
Alaska200812.7440905580.707
Alaska200912.9738498389.730
Alaska201011.6708938560.595
Next
123456
...
31
Previous
1-10 of 306 rows
  • Panel or Longitudinal data contains
    • repeated observations (t)
    • on multiple individuals (i)
  • Thus, our regression equation looks like:

ˆYit=β0+β1Xit+uit

for individual i in time t.

Panel Data: Our Motivating Example

ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
deaths
<dbl>
cell_plans
<dbl>
Alabama200718.0752328135.525
Alabama200816.2892278494.391
Alabama200913.8336788979.108
Alabama201013.4340849054.894
Alabama201113.7719899340.501
Alabama201213.3160569433.800
Alaska200716.3011846730.282
Alaska200812.7440905580.707
Alaska200912.9738498389.730
Alaska201011.6708938560.595
Next
123456
...
31
Previous
1-10 of 306 rows

Example

Do cell phones cause more traffic fatalities?

  • No measure of cell phones used while driving
    • cell_plans as a proxy for cell phone usage
  • U.S. State-level data over 6 years

The Data I

glimpse(phones)
Rows: 306
Columns: 8
$ year          <fct> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 20…
$ state         <fct> Alabama, Alaska, Arizona, Arkansas, California, Colorado…
$ urban_percent <dbl> 30, 55, 45, 21, 54, 34, 84, 31, 100, 53, 39, 45, 11, 56,…
$ cell_plans    <dbl> 8135.525, 6730.282, 7572.465, 8071.125, 8821.933, 8162.0…
$ cell_ban      <fct> 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ text_ban      <fct> 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ deaths        <dbl> 18.075232, 16.301184, 16.930578, 19.595430, 12.104340, 1…
$ year_num      <dbl> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 20…

The Data II

phones %>%
  count(state)
ABCDEFGHIJ0123456789
state
<fct>
n
<int>
Alabama6
Alaska6
Arizona6
Arkansas6
California6
Colorado6
Connecticut6
Delaware6
District of Columbia6
Florida6
Next
123456
Previous
1-10 of 51 rows
phones %>%
  count(year)
ABCDEFGHIJ0123456789
year
<fct>
n
<int>
200751
200851
200951
201051
201151
201251
6 rows

The Data III

phones %>%
  distinct(state)
ABCDEFGHIJ0123456789
state
<fct>
Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
District of Columbia
Florida
Next
123456
Previous
1-10 of 51 rows
phones %>%
  distinct(year)
ABCDEFGHIJ0123456789
year
<fct>
2007
2008
2009
2010
2011
2012
6 rows

The Data IV

phones %>%
  summarize(States = n_distinct(state),
            Years = n_distinct(year))
ABCDEFGHIJ0123456789
States
<int>
Years
<int>
516
1 row

Pooled Regression

Pooled Regression I

  • What if we just ran a standard regression:

^Yit=β0+β1Xit+uit

  • N number of i groups (e.g. U.S. States)

  • T number of t periods (e.g. years)

  • This is a pooled regression model: treats all observations as independent

Pooled Regression II

pooled <- lm(deaths ~ cell_plans, data = phones)
pooled %>% tidy()
ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
(Intercept)17.33710341670.97538450417.7746355.821724e-49
cell_plans-0.00056663850.000106975-5.2969262.264086e-07
2 rows

Pooled Regression III

Code
ggplot(data = phones)+
  aes(x = cell_plans,
      y = deaths)+
  geom_point()+
  labs(x = "Cell Phones Per 10,000 People",
       y = "Deaths Per Billion Miles Driven")+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)

Pooled Regression III

Code
ggplot(data = phones)+
  aes(x = cell_plans,
      y = deaths)+
  geom_point()+
  geom_smooth(method = "lm", color = "red")+
  labs(x = "Cell Phones Per 10,000 People",
       y = "Deaths Per Billion Miles Driven")+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)

Recall: Assumptions about Errors

  • We make 4 critical assumptions about u:
  1. The expected value of the errors is 0

E[u]=0

  1. The variance of the errors over X is constant:

var(u|X)=σ2u

  1. Errors are not correlated across observations:

cor(ui,uj)=0∀i≠j

  1. There is no correlation between X and the error term:

cor(X,u)=0 or E[u|X]=0

Biases of Pooled Regression

^Yit=β0+β1Xit+uit

  • Assumption 3: cor(ui,uj)=0∀i≠j

  • Pooled regression model is biased because it ignores:

    • Multiple observations from same group i
    • Multiple observations from same time t
  • Thus, errors are serially or auto-correlated; cor(ui,uj)≠0 within same i and within same t

Biases of Pooled Regression: Our Example

^Deathsit=β0+β1Cell Phonesit+uit

  • Multiple observations come from same state i
    • Probably similarities among ut for obs in same state i
    • Residuals on observations from same state are likely correlated

cor(uMD, 2008,uMD, 2009)≠0

  • Multiple observations come from same year t
    • Probably similarities among ui for obs in same year t
    • Residuals on observations from same year are likely correlated

cor(uMD, 2008,uVA, 2008)≠0

Example: Consider Just 5 States

Code
phones %>%
  filter(state %in% c("District of Columbia",
                      "Maryland", "Texas",
                      "California", "Kansas")) %>% 
ggplot()+
  aes(x = cell_plans,
      y = deaths,
      color = state)+
  geom_point()+ 
  geom_smooth(method = "lm")+
  labs(x = "Cell Phones Per 10,000 People",
       y = "Deaths Per Billion Miles Driven",
       color = NULL)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)+
  theme(legend.position = "top")

Example: Consider Just 5 States

Code
phones %>%
  filter(state %in% c("District of Columbia",
                      "Maryland", "Texas",
                      "California", "Kansas")) %>% 
ggplot()+
  aes(x = cell_plans,
      y = deaths,
      color = state)+
  geom_point()+ 
  geom_smooth(method = "lm")+
  labs(x = "Cell Phones Per 10,000 People",
       y = "Deaths Per Billion Miles Driven",
       color = NULL)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)+
  theme(legend.position = "top")+
  facet_wrap(~state, ncol = 3)

Example: Consider All 51 States

Code
ggplot(data = phones)+
  aes(x = cell_plans,
      y = deaths,
      color = state)+
  geom_point()+ 
  geom_smooth(method = "lm")+
  labs(x = "Cell Phones Per 10,000 People",
       y = "Deaths Per Billion Miles Driven",
       color = NULL)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)+
  theme(legend.position = "none")+
  facet_wrap(~state, ncol = 7)

The Bias in our Pooled Regression

^Deathsit=β0+β1Cell Phonesit+uit

  • Cell Phonesit is endogenous:

cor(uit,Cell Phonesit)≠0E[uit|Cell Phonesit]≠0

  • Things in uit correlated with Cell phonesit:
    • infrastructure spending, population, urban vs. rural, more/less cautious citizens, cultural attitudes towards driving, texting, etc
  • A lot of these things vary systematically by State!
    • cor(uit1,uit2)≠0
      • Error in State i during t1 correlates with error in State i during t2
      • things in State i that don’t change over time

Fixed Effects Model

Fixed Effects: DAG I

  • A simple pooled model likely contains lots of omitted variable bias

  • Many (often unobservable) factors that determine both Phones & Deaths

    • Culture, infrastructure, population, geography, institutions, etc

Fixed Effects: DAG II

  • A simple pooled model likely contains lots of omitted variable bias

  • Many (often unobservable) factors that determine both Phones & Deaths

    • Culture, infrastructure, population, geography, institutions, etc
  • But the beauty of this is that most of these factors systematically vary by U.S. State and are stable over time!

  • We can simply “control for State” to safely remove the influence of all of these factors!

Fixed Effects: Decomposing uit

  • Much of the endogeneity in Xit can be explained by systematic differences across i (groups)
  • Exploit the systematic variation across groups with a fixed effects model
  • Decompose the model error term into two parts:

uit=αi+ϵit

Fixed Effects: αi

  • Decompose the model error term into two parts:

uit=αi+ϵit

  • αi are group-specific fixed effects
    • group i tends to have higher or lower ˆY than other groups given regressor(s) Xit
    • estimate a separate αi (“intercept”) for each group i
    • essentially, estimate a separate constant (intercept) for each group
    • notice this is stable over time within each group (subscript only i, no t)
  • This includes all factors that do not change within group i over time

Fixed Effects: ϵit

  • Decompose the model error term into two parts:

uit=αi+ϵit

  • ϵit is the remaining random error
    • As usual in OLS, assume the 4 typical assumptions about this error:
      • E[ϵit]=0, var[ϵit]=σ2ϵ, cor(ϵit,ϵjt)=0, cor(ϵit,Xit)=0
  • ϵit includes all other factors affecting Yit not contained in group effect αi
    • i.e. differences within each group that change over time
    • Be careful: Xit can still be endogenous due to other factors!
      • cor(Xit,ϵit)≠0

Fixed Effects: New Regression Equation

ˆYit=β0+β1Xit+αi+ϵit

  • We’ve pulled αi out of the original error term into the regression

  • Essentially we’ll estimate an intercept for each group (minus one, which is β0)

    • avoiding the dummy variable trap
  • Must have multiple observations (over time) for each group (i.e. panel data)

Fixed Effects: Our Example

^Deathsit=β0+β1Cell phonesit+αi+ϵit

  • αi is the State fixed effect
    • Captures everything unique about each state i that does not change over time
      • culture, institutions, history, geography, climate, etc!
  • There could still be factors in ϵit that are correlated with Cell phonesit!
    • things that do change over time within States
    • perhaps individual States have cell phone bans for some years in our data

Estimating Fixed Effects Models

ˆYit=β0+β1Xit+αi+ϵit

  • Two methods to estimate fixed effects models:
  1. Least Squares Dummy Variable (LSDV) approach

  2. De-meaned data approach

Least Squares Dummy Variable Approach

Least Squares Dummy Variable Approach

ˆYit=β0+β1Xit+β2D1i+β3D2i+⋯+βND(N−1)i+ϵit

  • Create a dummy variable Di={0,1} for each possible group, {=1if observation it is from group i=0otherwise
  • If there are N groups:
    • Include N−1 dummies (to avoid dummy variable trap) and β0 is the reference category1
    • So we are estimating a different intercept for each group
  • Sounds like a lot of work, automatic in R
  1. If we do not estimate β0, we could include all N dummies. In either case, β0 takes the place of one category-dummy.

Least Squares Dummy Variable Approach: Our Example

Example

^Deathsit=β0+β1Cell Phonesit+Alaskai+⋯+Wyomingi

  • Let Alabama be the reference category (β0), include dummy for each of the other U.S. States

Our Example in R

^Deathsit=β0+β1Cell Phonesit+Alaskai+⋯+Wyomingi

  • If state variable is a factor, can just include it in the regression

  • R automatically creates N−1 dummy variables and includes them in the regression

    • Keeps intercept and leaves out first group dummy (Alabama)

Our Example in R: Regression I

fe_reg_1 <- lm(deaths ~ cell_plans + state, data = phones)
fe_reg_1 %>% tidy()
ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
(Intercept)25.5076799251.017640028925.065523371.241581e-70
cell_plans-0.0012037420.0001013125-11.881475843.483442e-26
stateAlaska-2.4841647830.6745076282-3.682930602.816972e-04
stateArizona-1.5105773830.6704569688-2.253056432.510925e-02
stateArkansas3.1926629310.66643839364.790634762.829319e-06
stateCalifornia-4.9786686510.6655467951-7.480568891.206933e-12
stateColorado-4.3445534930.6654735335-6.528514323.588784e-10
stateConnecticut-6.5951855300.6654428902-9.910971528.698802e-20
stateDelaware-2.0983936280.6666483193-3.147677071.842218e-03
stateDistrict of Columbia6.3557900101.28971726204.928049111.499627e-06
Next
123456
Previous
1-10 of 52 rows

Our Example in R: Regression II

fe_reg_1 %>% glance()
ABCDEFGHIJ0123456789
r.squared
<dbl>
adj.r.squared
<dbl>
sigma
<dbl>
statistic
<dbl>
p.value
<dbl>
0.90549870.8865241.15255847.721447.781982e-104
1 row | 1-5 of 12 columns

De-meaned Approach

De-meaned Approach I

  • Alternatively, we can control our regression for group fixed effects without directly estimating them

  • We simply de-mean the data for each group to remove the group fixed-effect

  • For each group i, find the mean of each variable (over time, t):

ˉYi=β0+β1ˉXi+ˉαi+ˉϵit

  • ˉYi: average value of Yit for group i
  • ˉXi: average value of Xit for group i
  • ˉαi: average value of αi for group i (=αi)
  • ˉϵit=0, by assumption 1 about errors

De-meaned Approach II

ˆYit=β0+β1Xit+uitˉYi=β0+β1ˉXi+ˉαi+ˉϵi

  • Subtract the means equation from the pooled equation to get:

Yit−ˉYi=β1(Xit−ˉXi)+αi+ϵit−ˉαi−ˉϵit˜Yit=β1˜Xit+˜ϵit

  • Within each group i, the de-meaned variables ˜Yit and ˜Xit’s all have a mean of 01

  • Variables that don’t change over time will drop out of analysis altogether

  • Removes any source of variation across groups (all now have mean of 0) to only work with variation within each group

  1. Recall Rule 4 from the 2.3 class appendix on the Summation Operator: ∑(Xi−ˉX)=0

De-meaned Approach III

˜Yit=β1˜Xit+˜ϵit

  • Yields identical results to dummy variable approach

  • More useful when we have many groups (would be many dummies)

  • Demonstrates intuition behind fixed effects:

    • Converts all data to deviations from the mean of each group
      • All groups are “centered” at 0, no variation across groups
    • Fixed effects are often called the “within” estimators, they exploit variation within groups, not across groups

De-meaned Approach IV

  • We are basically comparing groups to themselves over time
    • apples to apples comparison
    • e.g. Maryland in 2000 vs. Maryland in 2005
  • Ignore all differences between groups, only look at differences within groups over time

Looking at the Data in R I

# get means of Y and X by state
means_state <- phones %>%
  group_by(state) %>%
  summarize(avg_deaths = mean(deaths),
            avg_phones = mean(cell_plans))

# look at it
means_state
ABCDEFGHIJ0123456789
state
<fct>
avg_deaths
<dbl>
avg_phones
<dbl>
Alabama14.7867118906.370
Alaska13.6129537817.759
Arizona14.2498258097.482
Arkansas17.5438819268.153
California9.6597129029.594
Colorado10.3514058981.762
Connecticut8.1417398947.729
Delaware12.2096109304.052
District of Columbia8.01589519811.205
Florida13.5446359078.592
Next
123456
Previous
1-10 of 51 rows

Looking at the Data in R II

Code
ggplot(data = means_state)+
  aes(x = fct_reorder(state, avg_deaths),
      y = avg_deaths,
      color = state)+
  geom_point()+
  geom_segment(aes(y = 0,
                   yend = avg_deaths,
                   x = state,
                   xend = state))+
  coord_flip()+
  labs(x = "State",
       y = "Deaths Per Billion Miles Driven",
       color = NULL,
       title = "Deaths Vary By State")+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size=10)+
  theme(legend.position = "none")

Looking at the Data in R III

Code
ggplot(data = means_state)+
  aes(x = fct_reorder(state, avg_phones),
      y = avg_phones,
      color = state)+
  geom_point()+
  geom_segment(aes(y = 0,
                   yend = avg_phones,
                   x = state,
                   xend = state))+
  coord_flip()+
  labs(x = "State",
       y = "Cell Phone Plans Per 10,000 Population",
       color = NULL,
       title = "Cell Phone Plans Vary By State")+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size=10)+
  theme(legend.position = "none")

De-Meaning the Data in R

phones_dm <- phones %>% 
  select(state, year, cell_plans, deaths) %>%
  group_by(state) %>% # for each state...
  mutate(phones_dm = cell_plans - mean(cell_plans), # de-mean X
         deaths_dm = deaths - mean(deaths)) # de-mean Y
phones_dm
ABCDEFGHIJ0123456789
state
<fct>
year
<fct>
cell_plans
<dbl>
deaths
<dbl>
phones_dm
<dbl>
Alabama20078135.52518.075232-770.844401
Alaska20076730.28216.301184-1087.476481
Arizona20077572.46516.930578-525.017578
Arkansas20078071.12519.595430-1197.028076
California20078821.93312.104340-207.661621
Colorado20078162.06511.372734-819.697185
Connecticut20078234.5678.641937-713.162109
Delaware20078684.45012.337868-619.602051
District of Columbia200715910.46612.191743-3900.739418
Florida20078550.10315.592783-528.489258
Next
123456
...
31
Previous
1-10 of 306 rows | 1-5 of 6 columns

De-Meaning the Data in R II

phones_dm %>%
 #ungroup() %>% # it's still grouped by state
  summarize(mean_deaths = round(mean(deaths_dm),2), sd_deaths = round(sd(deaths_dm),2), mean_phones = round(mean(phones_dm),2), sd_phones = round(sd(phones_dm),2)) #%>%
ABCDEFGHIJ0123456789
state
<fct>
mean_deaths
<dbl>
sd_deaths
<dbl>
mean_phones
<dbl>
sd_phones
<dbl>
Alabama01.950501.58
Alaska01.9001348.37
Arizona01.570514.31
Arkansas01.180969.67
California01.410242.00
Colorado00.850477.62
Connecticut01.190470.90
Delaware00.940489.14
District of Columbia02.6802333.18
Florida01.380358.16
Next
123456
Previous
1-10 of 51 rows

De-Meaning the Data in R: Visualizing

Code
ggplot(data = phones_dm)+
  aes(x = phones_dm,
      y = deaths_dm,
      color = state)+
  geom_point()+
  geom_smooth(method = "lm", color = "black")+
  geom_hline(yintercept = 0)+
  geom_vline(xintercept = 0)+
  labs(x = "De-Meaned Cell Phones Per 10,000 People",
       y = "De-Meaned Deaths Per Billion Miles Driven",
       color = NULL)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 12)+
  theme(legend.position = "none")

De-Meaning the Data in R: Regression I

ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
(Intercept)-8.618515e-166.022574e-02-1.431035e-141.000000e+00
phones_dm-1.203742e-039.260683e-05-1.299841e+015.067582e-31
2 rows

De-Meaning the Data in R: Regression II

ABCDEFGHIJ0123456789
r.squared
<dbl>
adj.r.squared
<dbl>
sigma
<dbl>
statistic
<dbl>
p.value
<dbl>
0.35723780.35512341.05352168.95875.067582e-31
1 row | 1-5 of 12 columns

Using fixest I

  • The fixest package is designed for running regressions with fixed effects

  • feols() function is just like lm(), with some additional arguments:

library(fixest)
feols(y ~ x | g, # after |, g is the group variable
      data = df)

Using fixest II

fe_reg_1_alt <- feols(deaths ~ cell_plans | state,
                      data = phones)

fe_reg_1_alt %>% summary()
OLS estimation, Dep. Var.: deaths
Observations: 306 
Fixed-effects: state: 51
Standard-errors: Clustered (state) 
            Estimate Std. Error  t value  Pr(>|t|)    
cell_plans -0.001204   0.000143 -8.41708 3.792e-11 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 1.05007     Adj. R2: 0.886524
                Within R2: 0.357238
fe_reg_1_alt %>% tidy()
ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
cell_plans-0.0012037420.0001430118-8.4170773.791955e-11
1 row

Comparing FE Approaches

Pooled Regression FE: LSDV Method FE: De-Meaned FE: fixest
Constant 17.33710*** 25.50768*** 0.00000
(0.97538) (1.01764) (0.06023)
Cell Phone Plans −0.00057*** −0.00120*** −0.00120*** −0.00120***
(0.00011) (0.00010) (0.00009) (0.00014)
n 306 306 306 306
Adj. R2 0.08 0.89 0.36
SER 3.27 1.05 1.05 1.05
* p < 0.1, ** p < 0.05, *** p < 0.01

Two-Way Fixed Effects

Two-Way Fixed Effects

  • State fixed effect controls for all factors that vary by state but are stable over time

  • But there are still other (often unobservable) factors that affect both Phones and Deaths, that don’t vary by State

    • The country’s macroeconomic performance, federal laws, etc

Two-Way Fixed Effects

  • State fixed effect controls for all factors that vary by state but are stable over time

  • But there are still other (often unobservable) factors that affect both Phones and Deaths, that don’t vary by State

    • The country’s macroeconomic performance, federal laws, etc
  • If these factors systematically vary over time, but are the same by State, then we can “control for Year” to safely remove the influence of all of these factors!

Two-Way Fixed Effects

  • A one-way fixed effects model estimates a fixed effect for groups
  • Two-way fixed effects model (TWFE) estimates fixed effects for both groups and time periods

^Yit=β0+β1Xit+αi+θt+νit

  • αi: group fixed effects
    • accounts for time-invariant differences across groups
  • θt: time fixed effects
    • accounts for group-invariant differences over time
  • νit remaining random error
    • all remaining factors that affect Yit that vary by state and change over time

Two-Way Fixed Effects: Our Example

^Deathsit=β0+β1Cell phonesit+αi+θt+νit

  • αi: State fixed effects
    • differences across states that are stable over time (note subscript i only)
    • e.g. geography, culture, (unchanging) state laws
  • θt: Year fixed effects
    • differences over time that are stable across states (note subscript t only)
    • e.g. economy-wide macroeconomic changes, federal laws passed

Looking at the Data: Change Over Time

Code
ggplot(data = phones)+
  aes(x = cell_plans,
      y = deaths,
      color = year)+
  geom_point()+ 
  geom_smooth(method = "lm")+
  labs(x = "Cell Phones Per 10,000 People",
       y = "Deaths Per Billion Miles Driven",
       color = NULL)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)+
  theme(legend.position = "none")+
  facet_wrap(~year, ncol = 3)

Looking at the Data: Change Over Time II

means_year <- phones %>%
  group_by(year) %>%
  summarize(avg_deaths = mean(deaths),
            avg_phones = mean(cell_plans))
means_year
ABCDEFGHIJ0123456789
year
<fct>
avg_deaths
<dbl>
avg_phones
<dbl>
200714.007518064.531
200812.871568482.903
200912.086328859.706
201011.614879134.592
201111.364319485.238
201211.656669660.474
6 rows

Looking at the Data: Change In Deaths Over Time

Code
ggplot(data = phones)+
  aes(x = year,
      y = deaths)+
  geom_jitter(aes(color = year), width = 0.05)+
  # Add the yearly means as black points
  geom_point(data = means_year,
             aes(x = year,
                 y = avg_deaths),
             size = 3,
             color = "black")+
  # connect the means with a line
  geom_line(data = means_year,
            aes(x = as.numeric(year),
                y = avg_deaths),
            color = "black",
            size = 1)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)+
  theme(legend.position = "none")

Looking at the Data: Change in Cell Phones Over Time

Code
ggplot(data = phones)+
  aes(x = year,
      y = cell_plans)+
  geom_jitter(aes(color = year), width = 0.05)+
  # Add the yearly means as black points
  geom_point(data = means_year,
             aes(x = year,
                 y = avg_phones),
             size = 3,
             color = "black")+
  # connect the means with a line
  geom_line(data = means_year,
            aes(x = as.numeric(year),
                y = avg_phones),
            color = "black",
            size = 1)+
  theme_bw(base_family = "Fira Sans Condensed",
           base_size = 14)+
  theme(legend.position = "none")

Estimating Two-Way Fixed Effects

ˆYit=β0+β1Xit+αi+θt+νit

  • As before, several equivalent ways to estimate two-way fixed effects models:
  1. Least Squares Dummy Variable (LSDV) Approach: add dummies for both groups and time periods (separate intercepts for groups and times)
  1. Fully De-meaned data:

˜Yit=β1˜Xit+˜νit

where for each variable: ~varit=varit−¯vart−¯vari

  1. Hybrid: de-mean for one effect (groups or years) and add dummies for the other effect (years or groups)

LSDV Method

fe2_reg_1 <- lm(deaths ~ cell_plans + state + year,
                data = phones)

fe2_reg_1 %>% tidy()
ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
(Intercept)18.93047073991.451132396213.04530925.427406e-30
cell_plans-0.00029952940.0001723149-1.73826778.339982e-02
stateAlaska-1.49982924820.6241082951-2.40315541.698648e-02
stateArizona-0.77917147130.6113519094-1.27450572.036724e-01
stateArkansas2.86553447560.59850629524.78781012.895040e-06
stateCalifornia-5.09008971130.5956293282-8.54573381.299236e-15
stateColorado-4.41272416920.5953924847-7.41145431.945083e-12
stateConnecticut-6.63258348010.5952933996-11.14170511.169797e-23
stateDelaware-2.45798299530.5991822226-4.10222955.546475e-05
stateDistrict of Columbia-3.50449636161.9710939218-1.77794497.663326e-02
Next
123456
Previous
1-10 of 57 rows

With fixest

fe2_reg_2 <- feols(deaths ~ cell_plans | state + year,
                 data = phones)

fe2_reg_2 %>% summary()
OLS estimation, Dep. Var.: deaths
Observations: 306 
Fixed-effects: state: 51,  year: 6
Standard-errors: Clustered (state) 
           Estimate Std. Error   t value Pr(>|t|) 
cell_plans   -3e-04   0.000305 -0.980739  0.33144 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.930036     Adj. R2: 0.909197
                 Within R2: 0.011989
fe2_reg_2 %>% tidy()
ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
cell_plans-0.00029952940.0003054118-0.98073940.3314431
1 row

Adding Covariates I

  • State fixed effect absorbs all unobserved factors that vary by state, but are constant over time

  • Year fixed effect absorbs all unobserved factors that vary by year, but are constant over States

  • But there are still other (often unobservable) factors that affect both Phones and Deaths, that vary by State and change over time!

    • Some States change their laws during the time period
    • State urbanization rates change over the time period
  • We will also need to control for these variables (not picked up by fixed effects!)

    • Add them to the regression

Adding Covariates — Necessary?

phones %>%
  group_by(year) %>%
  count(cell_ban) %>%
  pivot_wider(names_from = cell_ban, values_from = n) %>%
  rename(`States Without a Ban` = `0`,
         `States With Cell Phone Ban` = `1`)
ABCDEFGHIJ0123456789
year
<fct>
States Without a Ban
<int>
States With Cell Phone Ban
<int>
2007465
2008465
2009447
2010438
20114110
20124011
6 rows

Adding Covariates — Necessary?

phones %>%
  group_by(year) %>%
  count(text_ban) %>%
  pivot_wider(names_from = text_ban, values_from = n) %>%
  rename(`States Without a Ban` = `0`,
         `States With a Texting Ban` = `1`)
ABCDEFGHIJ0123456789
year
<fct>
States Without a Ban
<int>
States With a Texting Ban
<int>
2007492
2008474
2009429
20103021
20112031
20121635
6 rows

Adding Covariates — Necessary?

Adding Covariates II

^Deathsit=β1Cell Phonesit+αi+θt+β2urban pctit+β3cell banit+β4text banit

  • Can still add covariates to remove endogeneity not soaked up by fixed effects
    • factors that change within groups over time
    • e.g. some states pass bans over the time period in data (some years before, some years after)

Adding Covariates III (fixest)

fe2_controls_reg <- feols(deaths ~ cell_plans + text_ban + urban_percent + cell_ban | state + year,
                          data = phones) 

fe2_controls_reg %>% summary()
OLS estimation, Dep. Var.: deaths
Observations: 306 
Fixed-effects: state: 51,  year: 6
Standard-errors: Clustered (state) 
               Estimate Std. Error  t value Pr(>|t|)    
cell_plans    -0.000340   0.000277 -1.22780 0.225269    
text_ban1      0.255926   0.243444  1.05127 0.298188    
urban_percent  0.013135   0.009815  1.33822 0.186878    
cell_ban1     -0.679796   0.335655 -2.02528 0.048194 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.920123     Adj. R2: 0.910039
                 Within R2: 0.032939
fe2_controls_reg %>% tidy()
ABCDEFGHIJ0123456789
term
<chr>
estimate
<dbl>
std.error
<dbl>
statistic
<dbl>
p.value
<dbl>
cell_plans-0.00034037350.0002772212-1.2278050.22526919
text_ban10.25592615690.24344421111.0512720.29818803
urban_percent0.01313476570.00981507051.3382240.18687751
cell_ban1-0.67979565220.3356553662-2.0252790.04819377
4 rows

Comparing Models

Pooled Regression State FE State & Year FE TWFE with Controls
Constant 17.33710***
(0.97538)
Cell Phone Plans −0.00057*** −0.00120*** −3e−04 −0.00034
(0.00011) (0.00014) (0.00031) (0.00028)
text_ban1 0.25593
(0.24344)
urban_percent 0.01313
(0.00982)
cell_ban1 −0.67980**
(0.33566)
n 306 306 306 306
Adj. R2 0.08
SER 3.27 1.05 0.93 0.92
* p < 0.1, ** p < 0.05, *** p < 0.01

ECON 480 — Econometrics

1
5.1 — Fixed Effects ECON 480 • Econometrics • Fall 2022 Dr. Ryan Safner Associate Professor of Economics safner@hood.edu ryansafner/metricsF22 metricsF22.classes.ryansafner.com

  1. Slides

  2. Tools

  3. Close
  • Title Slide
  • Contents
  • Panel Data
  • Types of Data I
  • Types of Data I
  • Types of Data II
  • Panel Data I
  • Panel Data II
  • Panel Data II
  • Panel Data: Our Motivating Example
  • The Data I
  • The Data II
  • The Data III
  • The Data IV
  • Pooled Regression
  • Pooled Regression I
  • Pooled Regression II
  • Pooled Regression III
  • Pooled Regression III
  • Recall: Assumptions about Errors
  • Biases of Pooled Regression
  • Biases of Pooled Regression: Our Example
  • Example: Consider Just 5 States
  • Example: Consider Just 5 States
  • Example: Consider All 51 States
  • The Bias in our Pooled Regression
  • Fixed Effects Model
  • Fixed Effects: DAG I
  • Fixed Effects: DAG II
  • Fixed Effects: Decomposing \(\text{u}_{it}\)
  • Fixed Effects: \(\alpha_i\)
  • Fixed Effects: \(\epsilon_{it}\)
  • Fixed Effects: New Regression Equation
  • Fixed Effects: Our Example
  • Estimating Fixed Effects Models
  • Least Squares Dummy Variable Approach
  • Least Squares Dummy Variable Approach
  • Least Squares Dummy Variable Approach: Our Example
  • Our Example in R
  • Our Example in R: Regression I
  • Our Example in R: Regression II
  • De-meaned Approach
  • De-meaned Approach I
  • De-meaned Approach II
  • De-meaned Approach III
  • De-meaned Approach IV
  • Looking at the Data in R I
  • Looking at the Data in R II
  • Looking at the Data in R III
  • De-Meaning the Data in R
  • De-Meaning the Data in R II
  • De-Meaning the Data in R: Visualizing
  • De-Meaning the Data in R: Regression I
  • De-Meaning the Data in R: Regression II
  • Using fixest I
  • Using fixest II
  • Comparing FE Approaches
  • Two-Way Fixed Effects
  • Two-Way Fixed Effects
  • Two-Way Fixed Effects
  • Two-Way Fixed Effects
  • Two-Way Fixed Effects: Our Example
  • Looking at the Data: Change Over Time
  • Looking at the Data: Change Over Time II
  • Looking at the Data: Change In Deaths Over Time
  • Looking at the Data: Change in Cell Phones Over Time
  • Estimating Two-Way Fixed Effects
  • LSDV Method
  • With fixest
  • Adding Covariates I
  • Adding Covariates — Necessary?
  • Adding Covariates — Necessary?
  • Adding Covariates — Necessary?
  • Adding Covariates II
  • Adding Covariates III (fixest)
  • Comparing Models
  • f Fullscreen
  • s Speaker View
  • o Slide Overview
  • e PDF Export Mode
  • b Toggle Chalkboard
  • c Toggle Notes Canvas
  • d Download Drawings
  • ? Keyboard Help