Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • 8d5b031
  • /
  • mediation.Rmd
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge Iframe embedding
swh:1:cnt:7aab1e0eb5296146f583a9c3c9cf4a483597f72b
directory badge Iframe embedding
swh:1:dir:8d5b031a87f31d25119ba488f12a4e87b0f09922

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
mediation.Rmd
---
title: "Mediation Analysis using Bayesian Regression Models"
output: 
  rmarkdown::html_vignette:
    toc: true
    fig_width: 10.08
    fig_height: 6
tags: [r, bayesian, posterior, mediation]
vignette: >
  \usepackage[utf8]{inputenc}
  %\VignetteIndexEntry{Mediation Analysis using Bayesian Regression Models}
  %\VignetteEngine{knitr::rmarkdown}
editor_options: 
  chunk_output_type: console
bibliography: bibliography.bib
csl: apa.csl
---

```{r, SETTINGS-knitr, echo = FALSE, warning = FALSE, message = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE, 
  comment = "#>", 
  dev = "png", 
  fig.width = 7, 
  fig.height = 5, 
  message = FALSE, 
  warning = FALSE
)
options(width = 800)
if (!requireNamespace("mediation", quietly = TRUE) ||
    !requireNamespace("httr", quietly = TRUE) ||
    !requireNamespace("lavaan", quietly = TRUE) ||
    !requireNamespace("brms", quietly = TRUE) ||
    !requireNamespace("rstanarm", quietly = TRUE) ||
    !requireNamespace("insight", quietly = TRUE)) {
  knitr::opts_chunk$set(eval = FALSE)
}
```

This vignettes demonstrates the `mediation()`-function. Before we start, we fit
some models, including a mediation-object from the _mediation_-package and a
structural equation modelling approach with the _lavaan_-package, both of which
we use for comparison with _brms_ and _rstanarm_.

## Mediation Analysis in brms and rstanarm

```{r}
library(bayestestR)
library(mediation)
library(brms)
library(rstanarm)

# load sample data
data(jobs)

set.seed(123)
# linear models, for mediation analysis
b1 <- lm(job_seek ~ treat + econ_hard + sex + age, data = jobs)
b2 <- lm(depress2 ~ treat + job_seek + econ_hard + sex + age, data = jobs)

# mediation analysis, for comparison with brms
m1 <- mediate(b1, b2, sims = 1000, treat = "treat", mediator = "job_seek")
```
```{r eval=FALSE}
# Fit Bayesian mediation model in brms
f1 <- bf(job_seek ~ treat + econ_hard + sex + age)
f2 <- bf(depress2 ~ treat + job_seek + econ_hard + sex + age)
m2 <- brm(f1 + f2 + set_rescor(FALSE), data = jobs, cores = 4)

```
```{r echo=FALSE}
m2 <- insight::download_model("brms_mv_6")
```
```{r eval=FALSE}
# Fit Bayesian mediation model in rstanarm
m3 <- stan_mvmer(
  list(job_seek ~ treat + econ_hard + sex + age + (1 | occp),
       depress2 ~ treat + job_seek + econ_hard + sex + age + (1 | occp)),
  data = jobs,
  cores = 4,
  refresh = 0
)
```
```{r echo=FALSE}
m3 <- insight::download_model("stanmvreg_2")
```

`mediation()` is a summary function, especially for mediation analysis, i.e. for
multivariate response models with casual mediation effects.

In the models `m2` and `m3`, `treat` is the treatment effect and `job_seek` is
the mediator effect. For the *brms* model (`m2`), `f1` describes the mediator
model and `f2` describes the outcome model. This is similar for the *rstanarm*
model.

`mediation()` returns a data frame with information on the _direct effect_
(median value of posterior samples from treatment of the outcome model),
_mediator effect_ (median value of posterior samples from mediator of the
outcome model), _indirect effect_ (median value of the multiplication of the
posterior samples from mediator of the outcome model and the posterior samples
from treatment of the mediation model) and the _total effect_ (median value of
sums of posterior samples used for the direct and indirect effect). The
_proportion mediated_ is the indirect effect divided by the total effect.

The simplest call just needs the model-object.

```{r, message=TRUE}
# for brms
mediation(m2)

# for rstanarm
mediation(m3)
```

Typically, `mediation()` finds the treatment and mediator variables
automatically. If this does not work, use the `treatment` and `mediator`
arguments to specify the related variable names. For all values, the 89%
credible intervals are calculated by default. Use `ci` to calculate a different
interval.

## Comparison to the mediation package

Here is a comparison with the _mediation_ package. Note that the
`summary()`-output of the _mediation_ package shows the indirect effect first,
followed by the direct effect.

```{r}
summary(m1)

mediation(m2, ci = .95)

mediation(m3, ci = .95)
```

If you want to calculate mean instead of median values from the posterior
samples, use the `centrality`-argument. Furthermore, there is a
`print()`-method, which allows to print more digits.

```{r, message=TRUE}
m <- mediation(m2, centrality = "mean", ci = .95)
print(m, digits = 4)
```

As you can see, the results are similar to what the _mediation_ package produces
for non-Bayesian models.

## Comparison to SEM from the lavaan package

Finally, we also compare the results to a SEM model, using *lavaan*. This
example should demonstrate how to "translate" the same model in different
packages or modeling approached.

```{r}
library(lavaan)
data(jobs)
set.seed(1234)

model <- ' # direct effects
             depress2 ~ c1*treat + c2*econ_hard + c3*sex + c4*age + b*job_seek
             
           # mediation
             job_seek ~ a1*treat + a2*econ_hard + a3*sex + a4*age
             
           # indirect effects (a*b)
             indirect_treat := a1*b
             indirect_econ_hard := a2*b
             indirect_sex := a3*b
             indirect_age := a4*b
             
           # total effects
             total_treat := c1 + (a1*b)
             total_econ_hard := c2 + (a2*b)
             total_sex := c3 + (a3*b)
             total_age := c4 + (a4*b)
         '
m4 <- sem(model, data = jobs)
summary(m4)

# just to have the numbers right at hand and you don't need to scroll up
mediation(m2, ci = .95)
```

The summary output from *lavaan* is longer, but we can find the related numbers
quite easily:

- the _direct effect_ of treatment is `treat (c1)`, which is `-0.040`
- the _indirect effect_ of treatment is `indirect_treat`, which is `-0.016`
- the _mediator effect_ of job_seek is `job_seek (b)`, which is `-0.240`
- the _total effect_ is `total_treat`, which is `-0.056`

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API