# VanderWeele bias calculation

In his book "Explanation in Causal Inference Methods for Mediation and Interaction", Tyler VanderWeele gives the following formula for bias (also Cinelli & Hazlet).

Let $$\beta'$$ be the biased coefficient of our exposure of interest in a simple situation where our exposure $$X$$, has a confounder $$U$$.

$$\begin{equation} \beta' = \gamma \delta \end{equation}$$

$$\gamma$$ being the direct effect of the confounder $$U$$ on our outcome $$Y$$,

In the case where $$U$$ and $$X$$ are binary, we have

$$\begin{equation} \gamma = E[Y|X=x,U=1] - E[Y|X=x,U=0] \end{equation}$$

and $$\delta$$ the difference in proportion $$U$$ in $$X$$ ("the difference in the prevalence of the unmeasured confounder", p.68 VanderWeele),

$$\begin{equation} \delta = Pr[Y|X=1, U=1] - Pr[Y|X=0,U=1] \end{equation}$$

When I try to simulate this bias (see code below, it is not working).

Now it was established elsewhere that the bias could simply be estimated as

$$\begin{equation} \beta' = \beta + \frac{\Delta}{\gamma} \end{equation}$$ Which is basically the "selection path" ($$\Delta$$) divided by the direct path of $$U$$ to $$Y$$ ($$\gamma$$).

library(tidyverse)

set.seed(123)
n=10000

# around 70% #
plogis(1)

u = rnorm(n, 0, 1)
# x is a function of u + a random component
x = rnorm(n, 0, 1) + u
# dichotomise
x = ifelse(plogis(x) < 0.5, 0, 1)
u = ifelse(plogis(u) < 0.5, 0, 1)

# y equation
y = x*1.5 + u*2

df = data.frame(u,x,y)

# counterfactual outcomes
df$$y0 = u df$$y1 = u + 1.5

df$$y1y0 = df$$y1-df$y0  Here I have the $$\delta$$ part, the difference of proportion of $$U$$ in $$X$$ # \delta -- P(U=1,X=1) - P(U=1,X=0) count(df, u, x) %>% group_by(u) %>% mutate(n = n/sum(n)) %>% filter(u==1) %>% spread(x,n) %>% mutate(1-0)  I get 0.5 (50%) We know that the direct effect $$\gamma$$ is 2, but $$0.5 \times 2$$ is not the bias that we find when we run a simple OLS regression, where we miss $$U$$. lm(y ~ x)  We get a $$\beta$$ of 2.5 for x. Once we correct for $$u$$, we get the correct $$\beta$$ of 1.5 lm(y ~ x + u)  # Question 1 What I am missing in VanderWeele bias calculation? # Question 2 What is the relationship between the 2 formulas of bias $$\beta' = \gamma \delta$$ and $$\beta' = \beta + \frac{\Delta}{\gamma}$$ • The expression you wrote for$\delta$is the causal (unconfounded) effect of$X$on$Y$, which is not what you described in the text preceding it. Is that what you meant? – Noah Jun 6, 2022 at 20:04 • wait the delta of the$\gamma \delta$is the unconfounded effect of X on Y? Maybe I am misunderstanding this but Cinelli p.6 write that$U = \delta X$.$\delta$"gives the difference in the linear expectation of the confounder, when comparing individuals with the same values for the covariates, but differing by one unit on the treatment" p.6 – giac Jun 7, 2022 at 6:45 • carloscinelli.com/files/… – giac Jun 7, 2022 at 6:45 • I'm not making a claim about what$\delta$actually is, but rather what you wrote it as. You said$\delta = Pr[Y|X=1, U = 1] - Pr[Y|X=0, U=1]$. That's the effect of$X$on$Y$holding$U$constant, i.e., the unconfounded effect of$X$on$Y\$. Just pointing out that maybe that's not what you meant to write given how you described it.
– Noah
Jun 7, 2022 at 7:04
• Thanks let me think about it. Are you interested in bias Noah? I feel that it is missing a paper on a graphical approach to bias. Maybe there is a collaboration to do on this?
– giac
Jun 7, 2022 at 12:41

Your replication of the formula is not correct. The correct formula in Cinelli and Hazlett (see equation 5) is:

$$\beta' = \beta + \gamma\delta$$

This is an algebraic identity that holds for any OLS model. In your example we obtain:

beta.prime <- coef(lm(y ~ x))["x"]
beta       <- coef(lm(y ~ x + u))["x"]
imbalance  <- coef(lm(u ~ x))["x"]
impact     <- coef(lm(y ~ x + u))["u"]

> beta.prime
x
2.514337

> beta + impact*imbalance
x
2.514337


Your second formula does not seem to be true in general, you seem to be assuming that a single latent variable determines both $$X$$ and $$Y$$. Here is a counter-example to your formula:

> n <- 1e3
> u <- rnorm(n)
> x <- u + rnorm(n)
> y <- x + u + rnorm(n)
> lm(y ~ x)

Call:
lm(formula = y ~ x)

Coefficients:
(Intercept)            x
0.00792      1.48475