Structural Equation Modeling (SEM)

Purpose:

SEM simultaneously estimates relationships among multiple variables, including latent variables — constructs measured indirectly through observed indicators such as survey items. It combines factor analysis and path analysis in a single model.

SEM is confirmatory, not exploratory. Your model should be grounded in an established theoretical framework before running the analysis.

Context Used:

  • You have multiple observed variables (e.g., survey items) measuring one or more latent constructs.
  • You want to test a theoretically derived structural model with directional paths.
  • You have a large enough sample (generally N ≥ 200).

Assumptions:

  • Large sample size: At least 10 observations per estimated parameter; N ≥ 200 recommended for stable estimates.
  • Multivariate normality: Observed variables should be approximately normally distributed. Severe non-normality inflates χ² fit statistics.
  • Theory-driven model: Testing multiple models until one fits ("model fishing") inflates Type I error. Specify your model before looking at the data.
  • Sufficient indicators: Each latent variable should have at least 3 observed indicators for the model to be identified.
Do NOT use SEM if: Your sample is small (N < 200) | You are exploring without a prior theoretical model → use EFA or regression first | All variables are directly observed with no latent constructs → use path analysis or multiple regression | You have not yet worked through regression and factor analysis

Jamovi Walkthrough:

Requires the semlj module. Install via Modules → jamovi library → search "semlj."
  1. Click "SEM" → "semlj"
  2. Specify your measurement model in the syntax editor using lavaan syntax: latent =~ item1 + item2 + item3
  3. Specify structural paths: Y ~ X
  4. Under "Fit Indices," check CFI, TLI, RMSEA, and SRMR
  5. Under "Parameters," check "Estimates" and "Standard errors"

R Walkthrough:

sem_model <- '
  LatentX =~ x1 + x2 + x3
  LatentM =~ m1 + m2 + m3
  LatentY =~ y1 + y2 + y3

  LatentM ~ a * LatentX
  LatentY ~ b * LatentM + c * LatentX

  indirect := a * b
  total    := c + (a * b)
'

sem_fit <- sem(sem_model, data = df, missing = "fiml", estimator = "ML")
summary(sem_fit, fit.measures = TRUE, standardized = TRUE, rsquare = TRUE)
For full latent variable models, the syntax editor within semlj is required. A tutorial video is strongly recommended for first-time users.

Output Interpretation:

Chi-Square (χ²): Unlike other tests, in SEM a non-significant χ² (p > .05) indicates good model fit — the model-implied covariances do not significantly differ from the observed covariances. However, χ² is highly sensitive to sample size: with N > 300, even minor misspecification will produce a significant χ². Always report χ² alongside other fit indices.

CFI (Comparative Fit Index):

  • CFI > .95 = good fit
  • CFI .90 – .95 = acceptable fit
  • CFI < .90 = poor fit

TLI (Tucker-Lewis Index):

  • TLI > .95 = good fit
  • TLI .90 – .95 = acceptable fit
  • TLI < .90 = poor fit

RMSEA (Root Mean Square Error of Approximation):

  • RMSEA < .05 = good fit
  • RMSEA .05 – .08 = acceptable fit
  • RMSEA > .10 = poor fit

Also report the 90% CI around RMSEA. A narrower CI reflects more precise estimates.

AIC (Akaike Information Criterion): Used to compare competing models. A lower AIC indicates better fit. Only meaningful in comparison — not in isolation.

Path coefficients: Interpreted similarly to β in regression. Each represents the unique directional relationship between two variables in the model, controlling for all others.

APA Format:

Sample write-up:

A structural equation model tested whether [X] predicted [Y] through [latent construct]. The model demonstrated acceptable fit: χ²() = , p = , CFI = , TLI = , RMSEA = , 90% CI [, ]. The standardized path from [X] to [Y] was significant (β = , p = ), indicating that [conclusion].

Note: Always report χ², df, p, CFI, TLI, RMSEA (with 90% CI), and standardized path coefficients. Include a path diagram as a figure.