Introduction
The wsMed function is designed for two condition
within-subject mediation analysis, incorporating SEM models through the
lavaan package and Monte Carlo simulation methods. This
document provides a detailed description of the function’s parameters,
workflow, and usage, along with an example demonstration.
Main Function Overview
The wsMed() function automates the full workflow for
two-condition within-subject mediation analysis. Its main steps are:
Validate inputs – check dataset structure,
mediation model type (form), and missing-data
settings.
Prepare data – compute difference scores
(Mdiff, Ydiff) and centered averages
(Mavg) from the two-condition variables.
Build the model – generate SEM syntax according
to the chosen structure:
"P": Parallel mediation
"CN": Chained / serial mediation
"CP": Chained + Parallel
"PC": Parallel + Chained
Fit the model – estimate parameters while
handling missing data:
"DE": listwise deletion
"FIML": full-information ML
"MI": multiple imputation
Compute inference – provide confidence intervals
using:
- Bootstrap
(
ci_method = "bootstrap")
- Monte Carlo (
ci_method = "mc")
Optional: Standardization – if
standardized = TRUE, return standardized effects with
CIs.
Optional: Covariates – automatically center and
include:
- Between-subject covariates (
C):
mean-centered and added to all regressions.
- Within-subject covariates (
C_C1,
C_C2): difference scores and centered averages are computed
and included.
The dataset should be in wide format, where each participant has
separate columns for measurements in different conditions. Specifically,
each mediator variable (e.g., M1) should be split into two columns: one
for Condition 1 and one for Condition 2. Similarly, the outcome variable
should also have separate columns for each condition. This structure
ensures that within-subject changes can be properly analyzed.
Example
Dataset
The dataset should be in wide format, where each participant has
separate columns for measurements in different conditions. Specifically,
each mediator variable (e.g., M1) should be split into two columns: one
for Condition 1 and one for Condition 2. Similarly, the outcome variable
should also have separate columns for each condition. This structure
ensures that within-subject changes can be properly analyzed.
For example, the first rows of example_data look like
this:
data("example_data", package = "wsMed")
head(example_data)
## # A tibble: 6 × 14
## A1 A2 A3 B1 B2 B3 C1 C2 C3 D1 D2 D3 Group W_Group
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <fct> <fct>
## 1 0.520 0.348 0.0518 0.0935 0.254 0.502 0 0.240 0 0.702 0.485 0.314 low low
## 2 0.329 0.121 0.291 0.259 0.328 0.152 0.116 0 0.118 0 0.392 0.0133 high high
## 3 0.208 0.168 0.156 0.295 0.342 0.490 0.237 0.214 0.137 0.336 0.706 0.521 med med
## 4 0.565 0.175 0.401 0.622 0.450 0.536 0.285 0.395 0.143 0.532 0.437 0.290 med med
## 5 0.514 0.767 0.598 0.653 0.448 0.525 0.284 0.464 0.161 0.456 0.351 0.217 med med
## 6 0.763 0.567 0.803 0.766 0.716 0.554 0.260 0.313 0.177 0.813 0.666 1 med med
How to interpret these columns:
- A1 / A2 – the same mediator A, measured under
Condition 1 and Condition 2.
- B1 / B2 – the same mediator B, measured under
Condition 1 and Condition 2.
- C1 / C2 – the outcome variable measured under each condition.
Example 1 – Quick Start
result1 <- wsMed(
data = example_data, # Input dataset with scores from both conditions
M_C1 = c("A1", "B1"), # Mediators measured under Condition 1
M_C2 = c("A2", "B2"), # Same mediators measured under Condition 2
Y_C1 = "C1", # Outcome under Condition 1
Y_C2 = "C2", # Outcome under Condition 2
form = "P" # Model type: "P" | "CN" | "CP" | "PC"
)
print(result1)
Key Arguments in Example 1
data – a data frame containing raw
scores; variables must be named consistently with suffix 1
/ 2 for the two conditions.
M_C1, M_C2 – character
vectors with the mediator names for each condition.
Y_C1, Y_C2 – outcome
variable names for each condition.
form – specifies the mediation model:
"P" – parallel mediation
"CN" – chained / serial mediation (e.g., A → B →
Y)
"CP" – combined parallel + serial model
"PC" – parallel-to-serial model (alternative
structure)
Additional options often used with Example 1: -
alpha – set the significance level for Monte Carlo
confidence intervals (default = 0.05). -
print(..., digits = k) – control number of decimals printed
in the summary. - R – number of Monte Carlo draws (default
= 20000L).
By default, wsMed() uses Monte Carlo confidence
intervals if ci_method is not specified.
You can adjust the settings as follows:
result1 <- wsMed(
data = example_data,
M_C1 = c("A1", "B1"),
M_C2 = c("A2", "B2"),
Y_C1 = "C1",
Y_C2 = "C2",
form = "P",
alpha = 0.01, # 99% confidence intervals
R = 5000 # reduce MC draws for faster runtime in demos
)
# Control printed precision
print(result1, digits = 4) # Use 'digits' to control decimal places
Example 2 – Using Bootstrap Confidence Intervals
In this example we demonstrate how to switch from Monte Carlo to
bootstrap confidence intervals, and how to control the
number of replicates and the random seed.
result2 <- wsMed(
data = example_data, # Input dataset with scores from both conditions
M_C1 = c("A1", "B1"), # Mediators measured under Condition 1
M_C2 = c("A2", "B2"), # Same mediators measured under Condition 2
Y_C1 = "C1", # Outcome under Condition 1
Y_C2 = "C2", # Outcome under Condition 2
form = "P", # Parallel mediation, also can use "CN","CP","PC"
# additional argument for bootstrap
ci_method = "bootstrap", # Use bootstrap CI instead of Monte Carlo CI
boot_ci_type = "perc", # CI type: "perc" | "bc" | "bca.simple"
bootstrap = 2000, # Number of bootstrap replicates
iseed = 123 # Seed for reproducibility
)
print(result2)
Key Arguments in This Example
ci_method – choose the CI engine
("bootstrap" or "mc").
boot_ci_type –"perc"is
percentile CI and "bc"is bias-corrected percentile CI.
bootstrap – number of bootstrap
samples to draw (default = 2000).
iseed – random seed to ensure
reproducible bootstrap results.
You can combine these with other arguments, such as
alpha in wsMed() to set a different confidence level, or
digits in print() to control the number of decimal
places.
Example 3 – Requesting Standardized Effects
You can ask wsMed() to compute standardized path
coefficients and effects by setting
standardized = TRUE.
result3 <- wsMed(
data = example_data,
M_C1 = c("A1","B1","C1"), # Three mediators measured under Condition 1
M_C2 = c("A2","B2","C2"), # Same mediators measured under Condition 2
Y_C1 = "D1", # Outcome variable in Condition 1
Y_C2 = "D2", # Outcome variable in Condition 2
form = "CN", # "CN" = Chained / Serial mediation
standardized = TRUE, # Request standardized path coefficients and effects
alpha = 0.05 # Use 95% CI for standardized effects, also can use`0.01` for 99% CI
)
# Print summary with more decimals for clarity
print(result3)
Key Arguments in This Example
standardized – returns standardized
estimates, enabling effect size comparison.
alpha – sets the confidence level for
both unstandardized and standardized effects (default = 0.05)
Example 4 – Handling Missing Data
wsMed() supports three strategies via the
Na argument:
"DE" — listwise deletion (default if
Na is omitted).
"MI" — multiple imputation (via the
mice package).
"FIML" — full information maximum
likelihood (via lavaan).
Note: When Na = "MI", only monte carlo
CIs are available, bootstrap CIs are not available.
Generate a dataset with missing data:
## Warning: 程序包'knitr'是用R版本4.4.3 来建造的
data(example_data)
set.seed(123)
example_dataN <- mice::ampute(
data = example_data,
prop = 0.1,
)$amp
## Warning: Data is made numeric internally, because the calculation of weights requires numeric
## data
# (A) Multiple Imputation (MI) + Monte Carlo CI
result4_mi <- wsMed(
data = example_dataN, # dataset with missing values (wide format)
M_C1 = c("A1","B1"), # mediators under Condition 1
M_C2 = c("A2","B2"), # mediators under Condition 2
Y_C1 = "C1", # outcome under Condition 1
Y_C2 = "C2", # outcome under Condition 2
form = "P", # parallel mediation
Na = "MI", # handle missing data via Multiple Imputation
standardized = TRUE # Request standardized path coefficients and effects
)
print(result4_mi)
# (B) Full Information Maximum Likelihood (FIML) + Bootstrap CI
result4_fiml <- wsMed(
data = example_data, # dataset with missing values (wide format)
M_C1 = c("A1","B1"), # mediators under Condition 1
M_C2 = c("A2","B2"), # mediators under Condition 2
Y_C1 = "C1",
Y_C2 = "C2",
form = "CN", # chained/serial mediation (A -> B -> Y)
# additional argument for FIML and bootstrap
Na = "FIML", # full information maximum likelihood
ci_method = "bootstrap", # use Bootstrap CIs with FIML
bootstrap = 2000, # number of resamples (small for demo; typical 2000)
boot_ci_type = "perc", # CI type: "perc" or "bc"
iseed = 123 # seed for bootstrap reproducibility
)
print(result4_fiml)
Example 7 – Covariates
In this example,three covariates are included:
D3 is specified as a between-subject
covariate, representing a stable individual difference (e.g.,
trait-level variable). It is mean-centered and entered as a predictor in
all regression models.
D1 and D2 form a within-subject
covariate pair, assumed to be measured under Condition 1 and
Condition 2, respectively. The function automatically computes:
Cw1diff = D2 - D1 (difference score)
Cw1avg = mean-centered average of D1 and D2
These covariates are included as predictors of both the mediators and
the outcome in the SEM model.
result7 <- wsMed(
data = example_data, #dataset
M_C1 = c("A1","B1"), # A1/B1 is A/B mediator variable in condition 1
M_C2 = c("A2","B2"), # A2/B2 is A/B mediator variable in condition 2
Y_C1 = "C1", # C1 is outcome variable in condition 1
Y_C2 = "C2", # C2 is outcome variable in condition 2
form = "P", # Parallel mediation
C_C1 = "D1", # within-subject covariate (e.g., measured under D1)
C_C2 = "D2", # within-subject covariate (e.g., measured under C2)
C = "D3" # between-subject covariates
)
print(result7)
Key Arguments in This Example
C_C1, C_C2 — character
vectors naming within-subject covariates measured under
Condition 1 and Condition 2. wsMed() automatically
computes:
Cw1diff — difference score (C_C2 −
C_C1)
Cw1avg — mean-centered average of the
two conditions
These transformed covariates are included as predictors for all
mediators and the outcome.
C — character vector naming
between-subject covariates (e.g., stable traits). They
are automatically mean-centered and entered into all regression
equations.
form — model structure
("P" here, but can be "CN", "CP",
"PC").
Only including within-subject covariate D1 and D2
result7 <- wsMed(
data = example_data, #dataset
M_C1 = c("A1","B1"), # A1/B1 is A/B mediator variable in condition 1
M_C2 = c("A2","B2"), # A2/B2 is A/B mediator variable in condition 2
Y_C1 = "C1", # C1 is outcome variable in condition 1
Y_C2 = "C2", # C2 is outcome variable in condition 2
form = "P", # Parallel mediation
C_C1 = "D1", # within-subject covariate (e.g., measured under D1)
C_C2 = "D2", # within-subject covariate (e.g., measured under C2)
)
print(result7)
Only including between-subject covariate D3
result7 <- wsMed(
data = example_data, #dataset
M_C1 = c("A1","B1"), # A1/B1 is A/B mediator variable in condition 1
M_C2 = c("A2","B2"), # A2/B2 is A/B mediator variable in condition 2
Y_C1 = "C1", # C1 is outcome variable in condition 1
Y_C2 = "C2", # C2 is outcome variable in condition 2
form = "P", # Parallel mediation
C = "D3" # between-subject covariates
)
print(result7)
Understanding the Output
The printed output from wsMed() is divided into several
sections. Below we briefly explain what each section contains and how to
read it.