Skip to content

Instantly share code, notes, and snippets.

@balachia
Created November 18, 2014 20:03
Show Gist options
  • Save balachia/ae2d307a392ee6b3286b to your computer and use it in GitHub Desktop.
Save balachia/ae2d307a392ee6b3286b to your computer and use it in GitHub Desktop.
Instrumental variables with backdoors break everything, even when you know control for the backdoor.
rm(list=ls())
set.seed(1)
n <- 1000
b <- as.matrix(c(1,1))
xb <- 1
zb <- 1
conx <- 1.0
cony <- 1.0
pc <- 0.1
pa <- 0.4
z <- rnorm(n)
Cs <- rnorm(n)
# MODEL: C,Z -> X; C,X -> Y
# MODEL: X,Z observed, C unobserved
# Z is the instrument for X
# CHANGE: how big is the backdoor effect of Z on Y?
zony <- 1e-5 * runif(n)
x <- z + Cs * conx + rnorm(n,0,0.1)
Y <- x + Cs * cony + z * zony + rnorm(n,0,0.1)
X <- cbind(1,x)
Xz <- cbind(1,x,z)
Xzo <- cbind(1,x,zony)
Z <- cbind(1,z)
Zo <- cbind(1,zony,z)
b.ols <- solve(crossprod(X)) %*% crossprod(X,Y)
Xh <- Z %*% solve(crossprod(Z)) %*% crossprod(Z,X)
Xzoh <- Zo %*% solve(crossprod(Zo)) %*% crossprod(Zo,Xzo)
b.iv <- solve(crossprod(Xh)) %*% crossprod(Xh,Y)
bzo.iv <- solve(crossprod(Xzoh)) %*% crossprod(Xzoh,Y)
# true effect of X on Y = 1
b.ols
b.iv
bzo.iv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment