Chapter 3 Types of Causal Effects
Sometimes our experiments because quasi-experiments because of crossover or non-compliance.
Simulating data on assignment, compliance, and potential outcomes:
set.seed(1)
= rbinom(100, 1, 0.5) # half half assign
Simulating non-compliance as a function of gender:
set.seed(101)
= rbinom(100, 1, 0.4) # 40% are men
gender = rep();
comply ==1] = rbinom(sum(gender==1), 1, 0.5) # prob of men complying is 0.5
comply[gender==0] = rbinom(sum(gender==0), 1, 0.7) # prob of women complying is 0.7 comply[gender
treatment effect: 100 (from 400 –> 500) fixed for everyone:
= rnorm(100, 400, 12) # Y0
notutor = notutor + 100 + rnorm(100, 0, 20) # Y1
tutor = data.frame(assign, notutor, tutor)
simdata head(simdata)
## assign notutor tutor
## 1 0 403.2168 499.9361
## 2 0 392.8935 465.2280
## 3 1 425.6018 534.0721
## 4 1 414.0730 498.2632
## 5 0 408.9611 533.1596
## 6 1 397.2339 515.1242
actual treatment:
= ifelse(comply==1, assign, 1-assign)
treat table(assign, treat)
## treat
## assign 0 1
## 0 31 21
## 1 22 26
observed value:
= treat*tutor + (1-treat)*notutor # Y1 if T=1 and Y0 if T=0 obs
- when treat=1: Y = 1tutor + 0notutor = Y1
- when treat=0: Y = 0tutor + 1notutor = Y0
Simulated data:
= data.frame(assign, comply, treat, tutor, notutor, obs, gender)
simdata head(simdata)
## assign comply treat tutor notutor obs gender
## 1 0 1 0 499.9361 403.2168 403.2168 0
## 2 0 1 0 465.2280 392.8935 392.8935 0
## 3 1 0 0 534.0721 425.6018 425.6018 1
## 4 1 0 0 498.2632 414.0730 414.0730 1
## 5 0 1 0 533.1596 408.9611 408.9611 0
## 6 1 1 1 515.1242 397.2339 515.1242 0
3.1 ATT, ATE, ATU, … what the what?
- ATE/ACE: Average Treatment Effect in the population
- ATT: Average Treatment Effect on the Treated
- ATU: Average Treatment Effect on the Untreated
- LATE: Local Average Treatment Effect for Compilers
- CATE: Conditional Average Treatment Effect
- ITT: Intention To Treat. Effect of simply the intention (instead of receipt) of treatment
= mean(simdata$tutor - simdata$notutor) # whole population
ATE = mean((simdata$tutor - simdata$notutor)[treat==1])
ATT = mean((simdata$tutor - simdata$notutor)[treat==0])
ATU = mean((simdata$tutor - simdata$notutor)[comply==1])
LATE = mean((simdata$tutor - simdata$notutor)[gender==0])
CATE0 = mean((simdata$tutor - simdata$notutor)[gender==1]) CATE1
cbind(ATE, ATT, ATU, LATE, CATE0, CATE1)
## ATE ATT ATU LATE CATE0 CATE1
## [1,] 100.0414 101.1523 99.05629 99.88937 102.4829 97.28824
# all close to ATE
3.2 Calculating different causal effects in practice
- ATE
= lm(obs ~ treat, data = simdata)
ATE_obs coef(ATE_obs) # 99.82048
## (Intercept) treat
## 400.12192 99.82048
- ATT & ATU
no way to estimate ATT & ATU from data
- LATE if compliance status is known
= lm(obs ~ treat, data = simdata[simdata$comply==1,])
LATE_obs coef(LATE_obs) # 101.1594
## (Intercept) treat
## 398.5844 101.1594
- CATE if gender is included as a confounder:
= lm(obs ~ treat, data = simdata[simdata$gender==0,])
CATE0_obs coef(CATE0_obs) # 106.5414
## (Intercept) treat
## 400.1959 106.5414
= lm(obs ~ treat, data = simdata[simdata$gender==1,])
CATE1_obs coef(CATE1_obs) # 90.71861
## (Intercept) treat
## 400.05067 90.71861
- Intention To Treat (ITT)
= lm(obs ~ assign)
ITT coef(ITT) # 15.460 whereas the true effect is 100!!
## (Intercept) assign
## 439.61675 15.45999
- Intention To Treat on Compliers
= lm(obs ~ assign, data = simdata[simdata$comply==1,])
ITT_c coef(ITT_c) # 101.159 which is pretty close to the true effect 100
## (Intercept) assign
## 398.5844 101.1594
Generally recommended: LATE or ITT on Compliers!