Site icon R-bloggers

My Simple Understanding of Total Effect = Direct Effect + Indirect Effect (via Mediator)

[This article was first published on r on Everyday Is A School Day, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

I’ve struggled with differentiating between total, direct, and indirect effects, so this blog/note serves as a personal reference to solidify my understanding and make future amendments as needed. While there are comprehensive articles available, this is a simplified explanation for myself and potentially others

Objectives < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Reason For This Note < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

I’ve always had problem understanding the difference between total, direct, and indirect effect, even though it should sound fairly straightforward (mind you it is), but I still had problem grasping the intuition behind. Hence, this blog/note is to write down what I understand, so that I can refer to in the future, make more notes or amendments, if I found out certain things/concepts that I’ve noted are wrong. There are great articles out there, this is not an attempt to re-create that but more so a note for myself, perhaps others as well, for a simpler explaination of the concept.

DAG It Out < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Here we have:
X : Treatment
Y : Outcome
Z : Mediator
b : Path Coefficient of the effect of X on Y
c : Path Coefficient of the effect of X on Z
d : Path Coefficient of the effect of Z on Y

The total effect here would be b + cd. If we are interested in direct effect, then it would be just b. If we’re interested in the indirect effect then it would cd, which is essentially total effect minus direct effect. The DAG displayed above has a partial mediator as opposed to full mediator such as this.

The above all made sense mathematically but the problem I couldn’t quite grasp is when do we want to know the direct vs the total effect? I think have exammples will be helpful to get a glimpse of the intution.

Examples < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

A quick search on the internet, I was able to find a few examples using mediation analysis to look at direct effect of interest. In my mind at least, having some examples would be helpful to conceptualize the intuition behind total effect, direct effect, and indirect effect.

  1. Causal effects and immune cell mediators between prescription analgesic use and risk of infectious diseases: a Mendelian randomization study From my understanding, with this study, the idea is to assess if there is any direct causal relationship between analgesics and infection. As some analgesics have tendencies to suppress immune system, one would like to know is the relationship all mediated through low immunesuppressed status, or there is some direct relationship between analgesics and infection.

  1. The mediating factors in the relationship between lower urinary tract symptoms and health-related quality of life Same thing here, the study assess whether change in severity of UTI itself is the cause of change of quality of life without mediation of change in mental health, basically assessing direct causal effect as opposed to total effect.

  1. A chain mediation model on COVID-19 symptoms and mental health outcomes in Americans, Asians and Europeans Here is another interesting study design that looked at whether the physical symptoms resembling COVID-19 infection would be positively associated with adverse mental health outcomes.

Other things that I could think of, which could be possible new research area (there may already have been studies done on these, I may not have looked hard enough), such as:

or CDI and symptom resolution mediated by absence of toxin.

or certain antimicrobial and respiratory symptom improvement.

Here is a non-medical example by Aleksander Molak, the author of Causal Inference and Discovery in Python: Unlock the secrets of modern causal machine learning with DoWhy, EconML, PyTorch and more

What a guy! He took time to explain simple things like these. This is truly inspiring. What a role model! The marketing campaign made sense!

Simulation < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Let’s revisit out DAG.

We will simulate these variables as continuous data.

library(tidyverse)
library(kableExtra)

set.seed(1)
n <- 1000
x <- rnorm(n)
z <- 0.5*x + rnorm(n,0,0.05)
y <- 0.25*x + 0.4*z + rnorm(n)

tibble(x,z,y) |>
  head() |>
  kable()
x z y
-0.6264538 -0.2564787 -1.1453545
0.1836433 0.1474183 -1.8173768
-0.8356286 -0.4613532 1.2262523
1.5952808 0.8081770 1.2413609
0.3295078 0.1682237 0.0938165
-0.8204684 -0.4933666 0.2939539

Total Effect Model

total <- lm(y ~ x)
summary(total)

## 
## Call:
## lm(formula = y ~ x)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.5516 -0.6371 -0.0202  0.6911  2.8081 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.01556    0.03261   0.477    0.633    
## x            0.49932    0.03152  15.841   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.031 on 998 degrees of freedom
## Multiple R-squared:  0.2009,	Adjusted R-squared:  0.2001 
## F-statistic: 250.9 on 1 and 998 DF,  p-value: < 2.2e-16

Here we can see that the total effect of a change in y related to a one-unit change of x is 0.4993191. On the DAG, this is b + cd. But how do we find b, c and d respectively?

Calculate < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Finding c

We changed the outcome to z and there is no open bias path because there is a collider. Hence, we can model it directly as z ~ x

x_z <- lm(z ~ x)
summary(x_z)

## 
## Call:
## lm(formula = z ~ x)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.162422 -0.033598 -0.000688  0.037770  0.182216 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.0008093  0.0016452  -0.492    0.623    
## x            0.5003216  0.0015904 314.581   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.05202 on 998 degrees of freedom
## Multiple R-squared:   0.99,	Adjusted R-squared:   0.99 
## F-statistic: 9.896e+04 on 1 and 998 DF,  p-value: < 2.2e-16

And we get 0.5003216. On the DAG, this is c.

Finding d

Now, we changed both the exposure and outcome to z (exposure) and y (outcome). Do you see the red warning color of x and its edges? This means there there is a bias path. We need to adjust for x in order to get a more accurate estimate of d.

z_y <- lm(y ~ z + x)
summary(z_y)

## 
## Call:
## lm(formula = y ~ z + x)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.6151 -0.6564 -0.0223  0.6815  2.8132 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)  0.01624    0.03260   0.498    0.618
## z            0.84034    0.62709   1.340    0.181
## x            0.07888    0.31533   0.250    0.803
## 
## Residual standard error: 1.031 on 997 degrees of freedom
## Multiple R-squared:  0.2024,	Adjusted R-squared:  0.2008 
## F-statistic: 126.5 on 2 and 997 DF,  p-value: < 2.2e-16

Here, we get 0.8403406. On the DAG, this is d.

Finding b

To estimate b, we will need to adjust for z our partial mediator. The model is essentially the same as z_y, the coefficient of x is b, which is 0.0788785

Total effect = b + c*d

x_z$coefficients[['x']]*z_y$coefficients[['z']] + z_y$coefficients[['x']]

## [1] 0.4993191

If you want to know why the indirect effect is c*d, please check out this section Why Coef Z * Coef X??? Addendum 2-23-24.

Let’s check our total effect model to see if we the same number!

round(total$coefficients[['x']],6) == round((x_z$coefficients[['x']]*z_y$coefficients[['z']] + z_y$coefficients[['x']]),6)

## [1] TRUE

Yes! We did! I had to round the numbers up 6 decimal points, otherwise it will be FALSE 🤣.

Lessons Learnt < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Side Note:

As I’m reading different coaching books for my coaching notes, I see total effects, direct effects, indirect effects, mediators everywhere! This is kind of fun!

The graph above was taken from the book Helping People Change which they adapted from R. E. Boyatzis and K. Akrivou, “The Ideal Self as the Driver of Intentional Change,” Journal of Management Development 25, no. 7 (2006): 624–642. Blue circled are mediators.

Happy identifying!

If you like this article:

To leave a comment for the author, please follow the link and comment on their blog: r on Everyday Is A School Day.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Exit mobile version