19.2 Causal Inference Approach to Mediation
Traditional mediation models assume that regression-based estimates provide valid causal inference. However, causal mediation analysis (CMA) extends beyond traditional models by explicitly defining mediation in terms of potential outcomes and counterfactuals.
19.2.1 Example: Traditional Mediation Analysis
We begin with a classic three-step mediation approach.
# Load data
myData <- read.csv("data/mediationData.csv")
# Step 1 (Total Effect: X → Y) [No longer required]
model.0 <- lm(Y ~ X, data = myData)
summary(model.0)
#>
#> Call:
#> lm(formula = Y ~ X, data = myData)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -5.0262 -1.2340 -0.3282 1.5583 5.1622
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 2.8572 0.6932 4.122 7.88e-05 ***
#> X 0.3961 0.1112 3.564 0.000567 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 1.929 on 98 degrees of freedom
#> Multiple R-squared: 0.1147, Adjusted R-squared: 0.1057
#> F-statistic: 12.7 on 1 and 98 DF, p-value: 0.0005671
# Step 2 (Effect of X on M)
model.M <- lm(M ~ X, data = myData)
summary(model.M)
#>
#> Call:
#> lm(formula = M ~ X, data = myData)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -4.3046 -0.8656 0.1344 1.1344 4.6954
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 1.49952 0.58920 2.545 0.0125 *
#> X 0.56102 0.09448 5.938 4.39e-08 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 1.639 on 98 degrees of freedom
#> Multiple R-squared: 0.2646, Adjusted R-squared: 0.2571
#> F-statistic: 35.26 on 1 and 98 DF, p-value: 4.391e-08
# Step 3 (Effect of M on Y, controlling for X)
model.Y <- lm(Y ~ X + M, data = myData)
summary(model.Y)
#>
#> Call:
#> lm(formula = Y ~ X + M, data = myData)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -3.7631 -1.2393 0.0308 1.0832 4.0055
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 1.9043 0.6055 3.145 0.0022 **
#> X 0.0396 0.1096 0.361 0.7187
#> M 0.6355 0.1005 6.321 7.92e-09 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 1.631 on 97 degrees of freedom
#> Multiple R-squared: 0.373, Adjusted R-squared: 0.3601
#> F-statistic: 28.85 on 2 and 97 DF, p-value: 1.471e-10
# Step 4: Bootstrapping for ACME
library(mediation)
results <-
mediate(
model.M,
model.Y,
treat = 'X',
mediator = 'M',
boot = TRUE,
sims = 500
)
summary(results)
#>
#> Causal Mediation Analysis
#>
#> Nonparametric Bootstrap Confidence Intervals with the Percentile Method
#>
#> Estimate 95% CI Lower 95% CI Upper p-value
#> ACME 0.3565 0.2119 0.51 <2e-16 ***
#> ADE 0.0396 -0.1750 0.28 0.760
#> Total Effect 0.3961 0.1743 0.64 0.004 **
#> Prop. Mediated 0.9000 0.5042 1.94 0.004 **
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Sample Size Used: 100
#>
#>
#> Simulations: 500
- Total Effect: ˆc=0.3961 → effect of X on Y without controlling for M.
- Direct Effect (ADE): ^c′=0.0396 → effect of X on Y after accounting for M.
- ACME (Average Causal Mediation Effect):
ACME = ˆc−^c′=0.3961−0.0396=0.3565
Equivalent to product of paths: ˆa׈b=0.56102×0.6355=0.3565.
These calculations do not rely on strong causal assumptions. For a causal interpretation, we need a more rigorous framework.
19.2.2 Two Approaches in Causal Mediation Analysis
The mediation
package Imai, Keele, and Yamamoto (2010) enables causal mediation analysis. It supports two inference types:
Model-Based Inference
Assumptions:
Treatment is randomized (or approximated via matching).
Sequential Ignorability: No unobserved confounding in:
Treatment → Mediator
Treatment → Outcome
Mediator → Outcome
This assumption is hard to justify in observational studies.
Design-Based Inference
- Relies on experimental design to isolate the causal mechanism.
Notation
We follow the standard potential outcomes framework:
Mi(t) = mediator under treatment condition t
Ti∈0,1 = treatment assignment
Yi(t,m) = outcome under treatment t and mediator value m
Xi = observed pre-treatment covariates
The treatment effect for an individual i: τi=Yi(1,Mi(1))−Yi(0,Mi(0)) which decomposes into:
- Causal Mediation Effect (ACME):
δi(t)=Yi(t,Mi(1))−Yi(t,Mi(0))
- Direct Effect (ADE):
ζi(t)=Yi(1,Mi(1))−Yi(0,Mi(0))
Summing up:
τi=δi(t)+ζi(1−t)
Sequential Ignorability Assumption
For CMA to be valid, we assume:
{Yi(t′,m),Mi(t)}⊥Ti|Xi=xYi(t′,m)⊥Mi(t)|Ti=t,Xi=x
First condition is the standard strong ignorability condition where treatment assignment is random conditional on pre-treatment confounders.
Second condition is stronger where the mediators is also random given the observed treatment and pre-treatment confounders. This condition is satisfied only when there is no unobserved pre-treatment confounders, and post-treatment confounders, and multiple mediators that are correlated.
Key Challenge
⚠️ Sequential Ignorability is not testable. Researchers should conduct sensitivity analysis.
We now fit a causal mediation model using mediation
.
library(mediation)
set.seed(2014)
data("framing", package = "mediation")
# Step 1: Fit mediator model (M ~ T, X)
med.fit <-
lm(emo ~ treat + age + educ + gender + income, data = framing)
# Step 2: Fit outcome model (Y ~ M, T, X)
out.fit <-
glm(
cong_mesg ~ emo + treat + age + educ + gender + income,
data = framing,
family = binomial("probit")
)
# Step 3: Causal Mediation Analysis (Quasi-Bayesian)
med.out <-
mediate(
med.fit,
out.fit,
treat = "treat",
mediator = "emo",
robustSE = TRUE,
sims = 100
) # Use sims = 10000 in practice
summary(med.out)
#>
#> Causal Mediation Analysis
#>
#> Quasi-Bayesian Confidence Intervals
#>
#> Estimate 95% CI Lower 95% CI Upper p-value
#> ACME (control) 0.0791 0.0351 0.15 <2e-16 ***
#> ACME (treated) 0.0804 0.0367 0.16 <2e-16 ***
#> ADE (control) 0.0206 -0.0976 0.12 0.70
#> ADE (treated) 0.0218 -0.1053 0.12 0.70
#> Total Effect 0.1009 -0.0497 0.23 0.14
#> Prop. Mediated (control) 0.6946 -6.3109 3.68 0.14
#> Prop. Mediated (treated) 0.7118 -5.7936 3.50 0.14
#> ACME (average) 0.0798 0.0359 0.15 <2e-16 ***
#> ADE (average) 0.0212 -0.1014 0.12 0.70
#> Prop. Mediated (average) 0.7032 -6.0523 3.59 0.14
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Sample Size Used: 265
#>
#>
#> Simulations: 100
Alternative: Nonparametric Bootstrap
med.out <-
mediate(
med.fit,
out.fit,
boot = TRUE,
treat = "treat",
mediator = "emo",
sims = 100,
boot.ci.type = "bca"
)
summary(med.out)
#>
#> Causal Mediation Analysis
#>
#> Nonparametric Bootstrap Confidence Intervals with the BCa Method
#>
#> Estimate 95% CI Lower 95% CI Upper p-value
#> ACME (control) 0.0848 0.0424 0.14 <2e-16 ***
#> ACME (treated) 0.0858 0.0410 0.14 <2e-16 ***
#> ADE (control) 0.0117 -0.0726 0.13 0.58
#> ADE (treated) 0.0127 -0.0784 0.14 0.58
#> Total Effect 0.0975 0.0122 0.25 0.06 .
#> Prop. Mediated (control) 0.8698 1.7460 151.20 0.06 .
#> Prop. Mediated (treated) 0.8804 1.6879 138.91 0.06 .
#> ACME (average) 0.0853 0.0434 0.14 <2e-16 ***
#> ADE (average) 0.0122 -0.0756 0.14 0.58
#> Prop. Mediated (average) 0.8751 1.7170 145.05 0.06 .
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Sample Size Used: 265
#>
#>
#> Simulations: 100
If we suspect moderation, we include an interaction term.
med.fit <-
lm(emo ~ treat + age + educ + gender + income, data = framing)
out.fit <-
glm(
cong_mesg ~ emo * treat + age + educ + gender + income,
data = framing,
family = binomial("probit")
)
med.out <-
mediate(
med.fit,
out.fit,
treat = "treat",
mediator = "emo",
robustSE = TRUE,
sims = 100
)
summary(med.out)
#>
#> Causal Mediation Analysis
#>
#> Quasi-Bayesian Confidence Intervals
#>
#> Estimate 95% CI Lower 95% CI Upper p-value
#> ACME (control) 0.07417 0.02401 0.14 <2e-16 ***
#> ACME (treated) 0.09496 0.02702 0.16 <2e-16 ***
#> ADE (control) -0.01353 -0.11855 0.11 0.76
#> ADE (treated) 0.00726 -0.11007 0.11 0.90
#> Total Effect 0.08143 -0.05646 0.19 0.26
#> Prop. Mediated (control) 0.64510 -14.31243 3.13 0.26
#> Prop. Mediated (treated) 0.98006 -17.83202 4.01 0.26
#> ACME (average) 0.08457 0.02738 0.15 <2e-16 ***
#> ADE (average) -0.00314 -0.11457 0.12 1.00
#> Prop. Mediated (average) 0.81258 -16.07223 3.55 0.26
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Sample Size Used: 265
#>
#>
#> Simulations: 100
test.TMint(med.out, conf.level = .95) # Tests for interaction effect
#>
#> Test of ACME(1) - ACME(0) = 0
#>
#> data: estimates from med.out
#> ACME(1) - ACME(0) = 0.020796, p-value = 0.3
#> alternative hypothesis: true ACME(1) - ACME(0) is not equal to 0
#> 95 percent confidence interval:
#> -0.01757310 0.07110837
Since sequential ignorability is untestable, we examine how unmeasured confounding affects ACME estimates.
# Load required package
library(mediation)
# Simulate some example data
set.seed(123)
n <- 100
data <- data.frame(
treat = rbinom(n, 1, 0.5), # Binary treatment
med = rnorm(n), # Continuous mediator
outcome = rnorm(n) # Continuous outcome
)
# Fit the mediator model (med ~ treat)
med_model <- lm(med ~ treat, data = data)
# Fit the outcome model (outcome ~ treat + med)
outcome_model <- lm(outcome ~ treat + med, data = data)
# Perform mediation analysis
med_out <- mediate(med_model,
outcome_model,
treat = "treat",
mediator = "med",
sims = 100)
# Conduct sensitivity analysis
sens_out <- medsens(med_out, sims = 100)
# Print and plot results
summary(sens_out)
#>
#> Mediation Sensitivity Analysis for Average Causal Mediation Effect
#>
#> Sensitivity Region
#>
#> Rho ACME 95% CI Lower 95% CI Upper R^2_M*R^2_Y* R^2_M~R^2_Y~
#> [1,] -0.9 -0.6194 -1.3431 0.1043 0.81 0.7807
#> [2,] -0.8 -0.3898 -0.8479 0.0682 0.64 0.6168
#> [3,] -0.7 -0.2790 -0.6096 0.0516 0.49 0.4723
#> [4,] -0.6 -0.2067 -0.4552 0.0418 0.36 0.3470
#> [5,] -0.5 -0.1525 -0.3406 0.0355 0.25 0.2409
#> [6,] -0.4 -0.1083 -0.2487 0.0321 0.16 0.1542
#> [7,] -0.3 -0.0700 -0.1723 0.0323 0.09 0.0867
#> [8,] -0.2 -0.0354 -0.1097 0.0389 0.04 0.0386
#> [9,] -0.1 -0.0028 -0.0648 0.0591 0.01 0.0096
#> [10,] 0.0 0.0287 -0.0416 0.0990 0.00 0.0000
#> [11,] 0.1 0.0603 -0.0333 0.1538 0.01 0.0096
#> [12,] 0.2 0.0928 -0.0317 0.2173 0.04 0.0386
#> [13,] 0.3 0.1275 -0.0333 0.2882 0.09 0.0867
#> [14,] 0.4 0.1657 -0.0369 0.3684 0.16 0.1542
#> [15,] 0.5 0.2100 -0.0422 0.4621 0.25 0.2409
#> [16,] 0.6 0.2642 -0.0495 0.5779 0.36 0.3470
#> [17,] 0.7 0.3364 -0.0601 0.7329 0.49 0.4723
#> [18,] 0.8 0.4473 -0.0771 0.9717 0.64 0.6168
#> [19,] 0.9 0.6768 -0.1135 1.4672 0.81 0.7807
#>
#> Rho at which ACME = 0: -0.1
#> R^2_M*R^2_Y* at which ACME = 0: 0.01
#> R^2_M~R^2_Y~ at which ACME = 0: 0.0096
plot(sens_out)
- If ACME confidence intervals contain 0, the effect is not robust to confounding.
Alternatively, using R2 interpretation, we need to specify the direction of confounder that affects the mediator and outcome variables in plot
using sign.prod = "positive"
(i.e., same direction) or sign.prod = "negative"
(i.e., opposite direction).
Summary: Causal Mediation vs. Traditional Mediation
Aspect | Traditional Mediation | Causal Mediation |
---|---|---|
Model Assumption | Linear regressions | Potential outcomes framework |
Assumptions Needed | No omitted confounders | Sequential ignorability |
Inference Method | Product of coefficients | Counterfactual reasoning |
Bootstrapping? | Common | Essential |
Sensitivity Analysis? | Rarely used | Strongly recommended |