Get the simple slopes of a SEM model
simple_slopes.RdThis function calculates simple slopes (predicted values of the outcome variable)
at user-specified values of the focal predictor (x) and moderator (z)
in a structural equation modeling (SEM) framework. It supports interaction terms
(xz), computes standard errors (SE), and optionally returns confidence or
prediction intervals for these predicted values. It also provides p-values for
hypothesis testing. This is useful for visualizing and interpreting moderation
effects or to see how the slope changes at different values of the moderator.
Usage
simple_slopes(
x,
z,
y,
model,
vals_x = -3:3,
vals_z = -1:1,
rescale = TRUE,
ci_width = 0.95,
ci_type = "confidence",
relative_h0 = TRUE,
standardized = FALSE,
xz = NULL,
...
)Arguments
- x
The name of the variable on the x-axis (focal predictor).
- z
The name of the moderator variable.
- y
The name of the outcome variable.
- model
An object of class
modsem_pi,modsem_da,modsem_mplus, or alavaanobject. This should be a fitted SEM model that includes paths fory ~ x + z + x:z.- vals_x
Numeric vector of values of
xat which to compute predicted slopes. Defaults to-3:3. Ifrescale = TRUE, these values are taken relative to the mean and standard deviation ofx. A higher density of points (e.g.,seq(-3, 3, 0.1)) will produce smoother curves and confidence bands.- vals_z
Numeric vector of values of the moderator
zat which to compute predicted slopes. Defaults to-1:1. Ifrescale = TRUE, these values are taken relative to the mean and standard deviation ofz. Each unique value ofzgenerates a separate regression liney ~ x | z.- rescale
Logical. If
TRUE(default),xandzare standardized according to their means and standard deviations in the model. The values invals_xandvals_zare interpreted in those standardized units. The raw (unscaled) values corresponding to these standardized points will be displayed in the returned table.- ci_width
A numeric value between 0 and 1 indicating the confidence (or prediction) interval width. The default is 0.95 (i.e., 95% interval).
- ci_type
A string indicating whether to compute a
"confidence"interval for the predicted mean (i.e., uncertainty in the regression line) or a"prediction"interval for individual outcomes. The default is"confidence". If"prediction", the residual variance is added to the variance of the fitted mean, resulting in a wider interval.- relative_h0
Logical. If
TRUE(default), hypothesis tests for the predicted values (predicted - h0) assumeh0is the model-estimated mean ofy. IfFALSE, the null hypothesis ish0 = 0.- standardized
Should coefficients be standardized beforehand?
- xz
The name of the interaction term (
x:z). IfNULL, it will be created by combiningxandzwith a colon (e.g.,"x:z"). Some backends may remove or alter the colon symbol, so the function tries to account for that internally.- ...
Additional arguments passed to lower-level functions or other internal helpers.
Value
A data.frame (invisibly inheriting class "simple_slopes")
with columns:
vals_x,vals_z: The requested grid values ofxandz.predicted: The predicted value ofyat that combination ofxandz.std.error: The standard error of the predicted value.z.value,p.value: The z-statistic and corresponding p-value for testing the null hypothesis thatpredicted == h0.ci.lower,ci.upper: Lower and upper bounds of the confidence (or prediction) interval.
An attribute "variable_names" (list of x, z, y)
is attached for convenience.
Details
Computation Steps
The function extracts parameter estimates (and, if necessary, their covariance matrix) from the fitted SEM model (
model).It identifies the coefficients for
x,z, andx:zin the model's parameter table, as well as the variance ofx,zand the residual variance ofy.If
xzis not provided, it will be constructed by combiningxandzwith a colon (":"). Depending on the approach used to estimate the model, the colon may be removed or replaced internally; the function attempts to reconcile that.A grid of
xandzvalues is created fromvals_xandvals_z. Ifrescale = TRUE, these values are transformed back into raw metric units for display in the output.For each point in the grid, a predicted value of
yis computed via(beta0 + beta_x * x + beta_z * z + beta_xz * x * z)and, if included, a mean offset.The standard error (
std.error) is derived from the covariance matrix of the relevant parameters, and ifci_type = "prediction", adds the residual variance.Confidence (or prediction) intervals are formed using
ci_width(defaulting to 95%). The result is a table-like data frame with predicted values, CIs, standard errors, z-values, and p-values.
Examples
# \dontrun{
library(modsem)
m1 <- "
# Outer Model
X =~ x1 + x2 + x3
Z =~ z1 + z2 + z3
Y =~ y1 + y2 + y3
# Inner model
Y ~ X + Z + X:Z
"
est1 <- modsem(m1, data = oneInt)
# Simple slopes at X in [-3, 3] and Z in [-1, 1], rescaled to the raw metric.
simple_slopes(x = "X", z = "Z", y = "Y", model = est1)
#>
#> Difference test of Y~X|Z at Z = -1.008 and 1.008:
#> ┌───────────┬───────────┬─────────┬─────────┬───────────────┐
#> │Difference │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞═══════════╪═══════════╪═════════╪═════════╪═══════════════╡
#> │ 1.42 │ 0.054 │ 26.36 │ 0.000 │ [1.31, 1.52] │
#> └───────────┴───────────┴─────────┴─────────┴───────────────┘
#>
#> Effect of Y~X|Z given values of Z:
#> ┌────────┬────────┬───────────┬─────────┬─────────┬────────────────┐
#> │ Y~X │ Z │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞════════╪════════╪═══════════╪═════════╪═════════╪════════════════╡
#> │ -0.033 │ -1.01 │ 0.038 │ -0.88 │ 0.377 │ [-0.11, 0.04] │
#> │ 0.675 │ 0.00 │ 0.027 │ 25.38 │ 0.000 │ [ 0.62, 0.73] │
#> │ 1.382 │ 1.01 │ 0.038 │ 36.34 │ 0.000 │ [ 1.31, 1.46] │
#> └────────┴────────┴───────────┴─────────┴─────────┴────────────────┘
#>
#>
#> Predicted Y, given Z = -1.01:
#> ┌───────┬─────────────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ X │ Predicted Y │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞═══════╪═════════════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -2.97 │ -0.47 │ 0.112 │ -4.17 │ 0.000 │ [-0.69, -0.25] │
#> │ -1.98 │ -0.50 │ 0.076 │ -6.55 │ 0.000 │ [-0.65, -0.35] │
#> │ -0.99 │ -0.53 │ 0.043 │ -12.33 │ 0.000 │ [-0.62, -0.45] │
#> │ 0.00 │ -0.57 │ 0.026 │ -21.61 │ 0.000 │ [-0.62, -0.51] │
#> │ 0.99 │ -0.60 │ 0.048 │ -12.56 │ 0.000 │ [-0.69, -0.50] │
#> │ 1.98 │ -0.63 │ 0.081 │ -7.76 │ 0.000 │ [-0.79, -0.47] │
#> │ 2.97 │ -0.66 │ 0.117 │ -5.67 │ 0.000 │ [-0.89, -0.43] │
#> └───────┴─────────────┴───────────┴─────────┴─────────┴─────────────────┘
#>
#>
#> Predicted Y, given Z = 0:
#> ┌───────┬─────────────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ X │ Predicted Y │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞═══════╪═════════════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -2.97 │ -2.00 │ 0.079 │ -25.38 │ 0.000 │ [-2.16, -1.85] │
#> │ -1.98 │ -1.34 │ 0.053 │ -25.38 │ 0.000 │ [-1.44, -1.23] │
#> │ -0.99 │ -0.67 │ 0.026 │ -25.38 │ 0.000 │ [-0.72, -0.62] │
#> │ 0.00 │ 0.00 │ 0.000 │ NaN │ NaN │ [ 0.00, 0.00] │
#> │ 0.99 │ 0.67 │ 0.026 │ 25.38 │ 0.000 │ [ 0.62, 0.72] │
#> │ 1.98 │ 1.34 │ 0.053 │ 25.38 │ 0.000 │ [ 1.23, 1.44] │
#> │ 2.97 │ 2.00 │ 0.079 │ 25.38 │ 0.000 │ [ 1.85, 2.16] │
#> └───────┴─────────────┴───────────┴─────────┴─────────┴─────────────────┘
#>
#>
#> Predicted Y, given Z = 1.01:
#> ┌───────┬─────────────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ X │ Predicted Y │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞═══════╪═════════════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -2.97 │ -3.54 │ 0.120 │ -29.48 │ 0.000 │ [-3.78, -3.31] │
#> │ -1.98 │ -2.17 │ 0.084 │ -25.94 │ 0.000 │ [-2.34, -2.01] │
#> │ -0.99 │ -0.80 │ 0.049 │ -16.30 │ 0.000 │ [-0.90, -0.71] │
#> │ 0.00 │ 0.57 │ 0.026 │ 21.61 │ 0.000 │ [ 0.51, 0.62] │
#> │ 0.99 │ 1.93 │ 0.042 │ 45.91 │ 0.000 │ [ 1.85, 2.02] │
#> │ 1.98 │ 3.30 │ 0.076 │ 43.74 │ 0.000 │ [ 3.16, 3.45] │
#> │ 2.97 │ 4.67 │ 0.112 │ 41.84 │ 0.000 │ [ 4.45, 4.89] │
#> └───────┴─────────────┴───────────┴─────────┴─────────┴─────────────────┘
#>
# If the data or user wants unscaled values, set rescale = FALSE, etc.
simple_slopes(x = "X", z = "Z", y = "Y", model = est1, rescale = FALSE)
#>
#> Difference test of Y~X|Z at Z = -1.000 and 1.000:
#> ┌───────────┬───────────┬─────────┬─────────┬───────────────┐
#> │Difference │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞═══════════╪═══════════╪═════════╪═════════╪═══════════════╡
#> │ 1.40 │ 0.053 │ 26.36 │ 0.000 │ [1.30, 1.51] │
#> └───────────┴───────────┴─────────┴─────────┴───────────────┘
#>
#> Effect of Y~X|Z given values of Z:
#> ┌────────┬─────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ Y~X │ Z │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞════════╪═════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -0.027 │ -1 │ 0.037 │ -0.73 │ 0.462 │ [-0.10, 0.046] │
#> │ 0.675 │ 0 │ 0.027 │ 25.38 │ 0.000 │ [ 0.62, 0.727] │
#> │ 1.377 │ 1 │ 0.038 │ 36.34 │ 0.000 │ [ 1.30, 1.451] │
#> └────────┴─────┴───────────┴─────────┴─────────┴─────────────────┘
#>
#>
#> Predicted Y, given Z = -1:
#> ┌────┬─────────────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ X │ Predicted Y │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞════╪═════════════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -3 │ -0.48 │ 0.112 │ -4.25 │ 0.000 │ [-0.70, -0.26] │
#> │ -2 │ -0.51 │ 0.077 │ -6.61 │ 0.000 │ [-0.66, -0.36] │
#> │ -1 │ -0.53 │ 0.043 │ -12.33 │ 0.000 │ [-0.62, -0.45] │
#> │ 0 │ -0.56 │ 0.026 │ -21.61 │ 0.000 │ [-0.61, -0.51] │
#> │ 1 │ -0.59 │ 0.048 │ -12.34 │ 0.000 │ [-0.68, -0.49] │
#> │ 2 │ -0.62 │ 0.082 │ -7.54 │ 0.000 │ [-0.78, -0.46] │
#> │ 3 │ -0.64 │ 0.118 │ -5.46 │ 0.000 │ [-0.87, -0.41] │
#> └────┴─────────────┴───────────┴─────────┴─────────┴─────────────────┘
#>
#>
#> Predicted Y, given Z = 0:
#> ┌────┬─────────────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ X │ Predicted Y │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞════╪═════════════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -3 │ -2.02 │ 0.080 │ -25.38 │ 0.000 │ [-2.18, -1.87] │
#> │ -2 │ -1.35 │ 0.053 │ -25.38 │ 0.000 │ [-1.45, -1.24] │
#> │ -1 │ -0.67 │ 0.027 │ -25.38 │ 0.000 │ [-0.73, -0.62] │
#> │ 0 │ 0.00 │ 0.000 │ NaN │ NaN │ [ 0.00, 0.00] │
#> │ 1 │ 0.67 │ 0.027 │ 25.38 │ 0.000 │ [ 0.62, 0.73] │
#> │ 2 │ 1.35 │ 0.053 │ 25.38 │ 0.000 │ [ 1.24, 1.45] │
#> │ 3 │ 2.02 │ 0.080 │ 25.38 │ 0.000 │ [ 1.87, 2.18] │
#> └────┴─────────────┴───────────┴─────────┴─────────┴─────────────────┘
#>
#>
#> Predicted Y, given Z = 1:
#> ┌────┬─────────────┬───────────┬─────────┬─────────┬─────────────────┐
#> │ X │ Predicted Y │ Std.Error │ z.value │ p.value │ Conf.Interval │
#> ╞════╪═════════════╪═══════════╪═════════╪═════════╪═════════════════╡
#> │ -3 │ -3.57 │ 0.121 │ -29.57 │ 0.000 │ [-3.81, -3.33] │
#> │ -2 │ -2.19 │ 0.084 │ -26.08 │ 0.000 │ [-2.36, -2.03] │
#> │ -1 │ -0.82 │ 0.049 │ -16.53 │ 0.000 │ [-0.91, -0.72] │
#> │ 0 │ 0.56 │ 0.026 │ 21.61 │ 0.000 │ [ 0.51, 0.61] │
#> │ 1 │ 1.94 │ 0.042 │ 45.91 │ 0.000 │ [ 1.85, 2.02] │
#> │ 2 │ 3.31 │ 0.076 │ 43.68 │ 0.000 │ [ 3.17, 3.46] │
#> │ 3 │ 4.69 │ 0.112 │ 41.78 │ 0.000 │ [ 4.47, 4.91] │
#> └────┴─────────────┴───────────┴─────────┴─────────┴─────────────────┘
#>
# }