2 Star 4 Fork 18

计量经济学/CausalitySlides

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Lecture_08_Fixed_Effects.Rmd 15.04 KB
一键复制 编辑 原始数据 按行查看 历史
NickCH-K 提交于 2021-02-23 13:49 . Push slides
title author date output
Lecture 8 Fixed Effects
Nick Huntington-Klein
`r Sys.Date()`
revealjs::revealjs_presentation
theme transition self_contained smart fig_caption reveal_options
solarized
slide
true
true
true
slideNumber
true
```{r setup, include=FALSE} knitr::opts_chunk$set(echo = FALSE, warning=FALSE, message=FALSE) library(tidyverse) library(stringr) library(dagitty) library(ggdag) library(gganimate) library(ggthemes) library(Cairo) library(gapminder) library(modelsummary) library(fixest) library(ggpubr) theme_set(theme_gray(base_size = 15)) ``` ## Recap - Last time we talked about how controlling is a common way of blocking back doors to identify an effect - We can control for a variable `W` by using our method of using `W` to explain our other variables, then take the residuals - Another form of controlling is using a sample that has only observations with similar values of `W` - Some variables you want to be careful NOT to control for - you don't want to close front doors, or open back doors by controlling for colliders ## Today - Today we'll be starting on our path for the rest of the class, where we'll be talking about standard *methods* for performing causal inference - Different ways of getting identification once we have a diagram! - Our goal here will be to understand these methods *conceptually* and to also figure out some good statistical practices for their use - Our goal is to *understand* these methods and be able to apply a straightforward version of them ## Today - In particular we'll be talking about a method that is commonly used to identify causal effects, called fixed effects - We'll be discussing the *kind* of causal diagram that fixed effects can identify - All of the methods we'll be discussing are like this - they'll only apply to particular diagrams - And so knowing our diagrams will be key to knowing when to use a given method ## The Problem - One problem we ran into last time is that we can't really control for things if we can't measure them - And there are lots of things we can't measure or don't have data for! - So what can we do? ## The Solution - If we observe each person/firm/country *multiple times*, then we can forget about controlling for the actual back-door variable we're interested in - And just control for *person/firm/country identity* instead! - This will control for EVERYTHING unique to that individual, whether we can measure it or not! ## In Practice - Let's do this on the data from the "gapminder" package - This data tracks life expectancy and GDP per capita in many countries over time ```{r, echo=TRUE, eval=FALSE} library(gapminder) data(gapminder) cor(gapminder$lifeExp,log(gapminder$gdpPercap)) ``` ```{r, echo=FALSE, eval=TRUE} data(gapminder) cor(gapminder$lifeExp,log(gapminder$gdpPercap)) ``` ```{r, echo=TRUE} gapminder % group_by(country) %>% mutate(lifeExp.r = lifeExp - mean(lifeExp), logGDP.r = log(gdpPercap) - mean(log(gdpPercap))) %>% ungroup() cor(gapminder$lifeExp.r,gapminder$logGDP.r) ``` ## So What? - This isn't any different, mechanically, from any other time we've controlled for something - So what's different here? - Let's think about what we're doing conceptually ## What's the Diagram? - Why are we controlling for things in this gapminder analysis? - Because there are LOTS of things that might be back doors between GDP per capita and life expectancy - War, disease, political institutions, trade relationships, health of the population, economic institutions... ## What's the Diagram? ```{r, dev='CairoPNG', echo=FALSE, fig.width=5, fig.height=6} dag % tidy_dagitty() ggdag_classic(dag,node_size=20) + theme_dag_blank() ``` ## What's the Diagram? - There's no way we can identify this - The list of back doors is very long - And likely includes some things we can't measure! ## What's the Diagram? - HOWEVER! If we think that these things are likely to be constant within country... - Then we don't really have a big long list of back doors, we just have one: "country" ```{r, dev='CairoPNG', echo=FALSE, fig.width=5, fig.height=3.5} dag % tidy_dagitty() ggdag_classic(dag,node_size=20) + theme_dag_blank() ``` ## What We Get - So what we get out of this is that we can identify our effect even if some of our back doors include variables that we can't actually measure - When we do this, we're basically comparing countries *to themselves* at different time periods! - Pretty good way to do an apples-to-apples comparison! ## Graphically ```{r, dev='CairoPNG', echo=FALSE, fig.width=7, fig.height=5} lgdpmean % mutate(X = .5+.5*(Person-2.5) + rnorm(200)) %>% mutate(Y = -.5*X + (Person-2.5) + 1 + rnorm(200),time="1") %>% group_by(Person) %>% mutate(mean_X=mean(X),mean_Y=mean(Y)) %>% ungroup() #Calculate correlations before_cor % mutate(mean_X=NA,mean_Y=NA,time=before_cor), #Step 2: Add x-lines df %>% mutate(mean_Y=NA,time='2. Figure out between-Individual differences in X'), #Step 3: X de-meaned df %>% mutate(X = X - mean_X,mean_X=0,mean_Y=NA,time="3. Remove all between-Individual differences in X"), #Step 4: Remove X lines, add Y df %>% mutate(X = X - mean_X,mean_X=NA,time="4. Figure out between-Individual differences in Y"), #Step 5: Y de-meaned df %>% mutate(X = X - mean_X,Y = Y - mean_Y,mean_X=NA,mean_Y=0,time="5. Remove all between-Individual differences in Y"), #Step 6: Raw demeaned data only df %>% mutate(X = X - mean_X,Y = Y - mean_Y,mean_X=NA,mean_Y=NA,time=after_cor)) p % tidy_dagitty() ggdag_classic(dag,node_size=20) + theme_dag_blank() ``` ## Varying Over Time - Of course, in this case, we could control for War as well and be good! - Time-varying things doesn't mean that fixed effects doesn't work, it just means you need to control for that stuff too - It always comes down to thinking carefully about your diagram - Fixed effects mainly works as a convenient way of combining together lots of different constant-within-country back doors into something that lets us identify the model even if we can't measure them all ## Fixed Effects in Regression - We can just do fixed effects as we did-subtract out the group means and analyze (perhaps with regression) what's left - We can also include *dummy variables for each group/individual*, which accomplishes the same thing $$ Y = \beta_0 + \beta_1Group1 + \beta_2Group2 + ... + $$ $$ \beta_NGroupN + \beta_{N+1}X + \varepsilon $$ $$ Y = \beta_i + \beta_1X + \varepsilon $$ ## Fixed Effects in Regression - Why does that work? - We want to "control for group/individual" right? So... just... put in a control for group/individual - Of course, like all categorical variables as predictors, we leave out a reference group - But here, unlike with, say, a binary predictor, we're rarely interested in the FE coefficients themselves. Most software works with the mean-subtraction approach (or a variant) and don't even report them! ## Fixed Effects in Regression: Variation - Remember we are isolating *within variation* - If an individual *has* no within variation, say their treatment never changes, they basically get washed out entirely! - A fixed-effects regression wouldn't represent them. And can't use FE to study things that are fixed over time - And in general if there's not a lot of within variation, FE is going to be very noisy. Make sure there's variation to study! ## Fixed Effects in Regression: Notes - It's common to *cluster standard errors* at the level of the fixed effects, since it seems likely that errors would be correlated over time (autocorrelated errors) - It's possible to have *more than one set* of fixed effects. $Y = \beta_i + \beta_j + \beta_1X + \varepsilon$ - But interpretation gets tricky - think through what variation in $X$ you're looking at at that point! ## Coding up Fixed Effects - We will use the **fixest** package - It's very fast, and can be easily adjusted to do FE with other regression methods like logit, or combined with instrumental variables - Clusters at the first listed fixed effect by default ```{r, echo = TRUE, eval = FALSE} library(fixest) m1 % rename(mm1 = `mm[rep(c(TRUE, FALSE), 2100/2), ]`) mm2 % rename(mm2 = `mm[rep(c(FALSE, TRUE), 2100/2), ]`) mmdata % mutate(sentreform = ceiling(sentreform)) %>% na.omit ``` - I've omitted code reading in the data - But in our data we have multiple observations per state ```{r, echo=TRUE} head(mmdata) mmdata % mutate(assaultper1000 = assault/pop1000, robberyper1000 = robbery/pop1000) ``` ## Fixed Effects - We can see how robbery rates evolve in each state over time as states implement reform ```{r, dev='CairoPNG', echo=FALSE, fig.width=8, fig.height=4.5} ggplot(mmdata,aes(x=year,y=robberyper1000, group=state,color=factor(sentreform)))+ geom_line(size=1)+scale_color_colorblind(name="Reform")+ labs(x="Year",y="Robberies per 1000 Population") + theme_pubr() + theme(legend.position = c(.8,.9)) ``` ## Fixed Effects - You can tell that states are more or less likely to implement reform in a way that's correlated with the level of robbery they already had - So SOMETHING about the state is driving both the level of robberies AND the decision to implement reform - Who knows what! - Our diagram has `reform -> robberies` and `reform robberies`, which is something we can address with fixed effects. ## Fixed Effects ```{r, echo=TRUE} sentencing_ols
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/econometric/CausalitySlides.git
git@gitee.com:econometric/CausalitySlides.git
econometric
CausalitySlides
CausalitySlides
main

搜索帮助