Skip to contents

Estimate the Structural Summary Method profile that one or more external measures show against the latent circumplex content of a set of scales – the disattenuated analog of the correlation-based ssm_analyze() – from a structural equation model with the scale angles held fixed at their theoretical values. The measurement model is generated by ssm_sem_syntax() and fitted with lavaan on raw covariances; confidence intervals for all SSM parameters are constructed in-package by propagating draws of the model's free parameters through the profile and SSM transforms and applying the same percentile/circular-quantile machinery as ssm_analyze(). No lavaan delta-method or percentile interval is ever used for amplitude or displacement (their intervals must respect the angular branch cut, which lavaan's := machinery does not).

Usage

ssm_sem(
  data,
  scales,
  angles = octants(),
  measures = NULL,
  grouping = NULL,
  contrast = FALSE,
  model = c("scaled", "strict"),
  invariance = NULL,
  invariance_alpha = 0.05,
  ci_method = c("mvn", "boot"),
  boots = 2000,
  interval = 0.95,
  estimator = "MLR",
  se = "robust.huber.white",
  missing = c("listwise", "fiml"),
  parallel = "no",
  ncpus = 1,
  ...
)

Arguments

data

Required. A data frame or matrix containing at least the circumplex scales and measures.

scales

Required. A character vector of column names, or a numeric vector of column indexes, from data that contains the circumplex scale scores.

angles

Optional. A numeric vector containing the angular displacement of each circumplex scale included in scales, in degrees (default = octants()). The angles are fixed theoretical constants in the measurement model, never free parameters.

measures

Optional with grouping, required otherwise. A character vector (or numeric indexes) of one or more columns of data to be related to the latent circumplex content (the disattenuated correlation path). With grouping and measures = NULL, the latent MEAN path is analyzed instead: each group's model-implied latent mean profile, on the raw-score metric. (A single-group latent mean profile is not a product: factor means are not identified in one group.)

grouping

Optional. A string naming the column of data indicating group membership. With grouping, the fixed-angle measurement model is fitted as a multi-group model under an invariance ladder (configural, then metric, then – when required – scalar), and the latent SSM profiles are reported per group. The FIRST factor level is the reference group. With measures = NULL and grouping, the latent MEAN path is analyzed (each group's model-implied latent mean profile).

contrast

Optional. A logical (default = FALSE) requesting a difference of latent SSM parameters, always second minus first with the displacement contrast in (-180, 180] degrees. Without grouping: exactly two measures (second measure minus first). With grouping: exactly two groups (second factor level minus first) and at most one measure – one measure gives the group contrast on that measure's latent profile, none gives the latent mean-path group contrast. The group contrast is invariance-gated; see invariance.

model

Optional. The measurement-model tier passed to ssm_sem_syntax(): "scaled" (default) or "strict".

invariance

Optional. The highest invariance rung to fit and REPORT ("configural", "metric", "scalar", or "strict_residuals"). NULL (default) uses the path's required rung: "metric" for the measure-profile path, "scalar" for the latent mean path. A group contrast is only computed if EVERY tested rung up through the path's required rung is retained by lavaan's own nested test (the scaled difference test under robust estimators) – a rejection at any lower rung rejects the constraints the contrast would be computed under. Rungs fitted ABOVE the required one are reported but never gate the contrast. On rejection, the returned object states the non-comparison and reports each group's separate configural profile instead (no contrast is rendered by any method). Under the strict tier the metric rung is vacuous (all loadings fixed) and is reported as such.

invariance_alpha

Optional. The alpha level for the invariance gating decision (default = 0.05). The gate is a modeling decision with a default test, not an oracle; the invariance table is always returned so other criteria can be applied.

ci_method

Optional. How to generate parameter replicates: "mvn" (default) draws from a multivariate normal with lavaan's asymptotic covariance of the free parameters (fast; one model fit); "boot" refits the model on boots bootstrap resamples via lavaan::bootstrapLavaan() (slow; robust to the normal approximation). Both engines feed the same in-package interval machinery.

boots

Optional. A single positive whole number indicating how many draws or bootstrap refits to use (default = 2000).

interval

Optional. A single number between 0 and 1 (exclusive) indicating the confidence level (default = 0.95).

estimator

Optional. The lavaan estimator (default = "MLR": maximum likelihood with robust "Huber-White" standard errors and a scaled test statistic, the standard choice for the skewed distributions typical of circumplex scale scores). The parameter estimates are identical to "ML"; what changes is the covariance the "mvn" engine propagates (already robust via se) and the test statistic behind the global fit indices that print() reports (robust/scaled versions are used when available).

se

Optional. The lavaan standard-error method for the fitted model (default = "robust.huber.white", the sandwich estimator). This does not affect the parameter estimates, only the covariance the "mvn" engine propagates: the fixed-angle measurement model is an approximation for real data, and the package's coverage validation found that sandwich-based draws keep the intervals calibrated for the model-conditional estimand under that misspecification where the plain ML covariance undercovers (displacement ~0.88 instead of 0.95, not improving with n). Set se = "standard" for the classical ML covariance.

missing

Optional. Either "listwise" (default; complete cases) or "fiml" (full-information maximum likelihood via lavaan's missing = "ml").

parallel, ncpus

Optional. Passed to lavaan::bootstrapLavaan() when ci_method = "boot" (defaults "no" and 1): the bootstrap refits are independent and can be distributed across cores. Results for a given set.seed() are reproducible regardless of these settings (the seed lavaan receives drives its own parallel-safe RNG streams). Ignored by the "mvn" engine.

...

Optional. Additional arguments passed to lavaan::cfa() (e.g., bounds or estimator-control settings).

Value

A circumplex_ssm_sem object (a subclass of circumplex_ssm, so ssm_table() and the ssm_plot_* functions work on it), containing results (estimates and intervals), scores (the latent profile vectors), details, call, plus sem (the fitted lavaan model: the gate rung's fit for grouped analyses, or the configural fit when the gate was rejected), invariance (for grouped analyses: the ladder table, the comparable flag, the verdict text, the gate rung, and the alpha used; NULL for single-group analyses), and model (tier, generated syntax for single-group fits, and the OLS projection weights).

Inadmissible parameter draws (a nonpositive common-part or measure variance, or a disattenuated correlation at or beyond 1) are dropped whole with a warning naming the causes; if more than 5% of draws are inadmissible the analysis stops with advice to use ci_method = "boot" or revise the model. Degenerate profiles (flat or zero-amplitude) keep the same per-parameter NA contract as ssm_analyze().

Details

The latent profile of a measure is its vector of model-implied disattenuated correlations with each scale's common (circumplex) content: the scale's error and unique parts are removed from the denominator, and the covariance is restricted to common content in the numerator. All latent quantities are conditional on the fixed-angle measurement model being adequate: global fit is reported by print(), and a poorly fitting measurement model makes the latent SSM parameters uninterpretable, not merely imprecise. The fixed angles are theoretical claims, not estimates (use cpm_fit() to examine an instrument's real geometry). Latent displacement is the first-harmonic direction of the saturation-modulated disattenuated profile – heterogeneous scale saturations rotate it exactly as they rotate the observed displacement; the latent layer removes the reliability modulation, nothing more. Model-implied disattenuated correlations at or beyond 1 indicate misspecification and are refused rather than summarized.

The point estimates and intervals are reported for elevation, x-value, y-value, amplitude, and displacement (no standard errors are printed anywhere, matching the package's estimate-plus-interval reporting surface). Unlike ssm_analyze()'s closed-form estimator, the latent transform is the ordinary-least-squares projection onto the cosine basis, so for unequally spaced angles the two functionals genuinely differ (they coincide exactly for equally spaced angles, and more generally under first- and second-harmonic balance); under OLS the fit value is a bounded R-squared in [0, 1] at any spacing.

With grouping, the latent contrast this function computes and the observed contrast that ssm_analyze() computes answer different questions and are not substitutes. The observed contrast (ssm_analyze() with grouping) asks whether the groups' measured profiles differ: it is a difference of SSM parameters computed from each group's observed scores or correlations. It confounds structural difference, differential reliability, and measurement non-invariance – that is a property of its estimand, documented rather than a defect, and it requires no invariance assumption. The latent contrast (ssm_sem() with grouping) asks whether the groups' constructs differ, granted the instrument measures the same thing in both groups: it is a contrast on latent SSM parameters computed under cross-group equality constraints, disattenuated and conditional on measurement invariance. When the required invariance rung is rejected the latent contrast is not "more principled" – it is misspecified, and the function therefore returns an explicit non-comparison (the verdict plus each group's separate configural profile; no contrast is computed or rendered by any method). Neither estimand replaces the other; they answer different questions and can legitimately disagree.

The displacement contrast is reported as the second group level minus the first, in (-180, 180] degrees, with branch-aligned circular intervals (endpoints may legitimately exceed +/-180 degrees near the boundary). Under the scaled tier the general-plane covariances are fixed to zero in all groups at all rungs (a stationarity-type assumption): a cross-group difference in a general factor's lean into the plane surfaces as misfit, and the strict tier is the tier that can express it. Under the strict tier the metric rung is vacuous (all loadings fixed) and is reported as such.

Reproducibility

This function consumes R's random number stream for both ci_method settings ("mvn" through the package's own draws; "boot" through a seed handed to lavaan's bootstrap). Call set.seed() immediately before ssm_sem() for reproducible confidence intervals.

Examples

# \donttest{
data("jz2017")
set.seed(12345)
res <- ssm_sem(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  measures = "NARPD",
  boots = 500
)
res
#> 
#> # Latent (SEM-based) SSM
#> 
#> Measurement model:	 scaled fixed-angle circumplex
#> Global fit (N = 1166, robust): chisq(17) = 300.546, p < 0.001 
#> 			CFI = 0.93, RMSEA = 0.13, SRMR = 0.072
#> 
#> # Profile [NARPD]:
#> 
#>                Estimate   Lower CI   Upper CI
#> Elevation         0.249      0.210      0.295
#> X-Value          -0.009     -0.054      0.033
#> Y-Value           0.231      0.189      0.273
#> Amplitude         0.232      0.192      0.274
#> Displacement     92.132     82.515    104.461
#> Model Fit         0.975                      
#> 
summary(res)
#> 
#> Statistical Basis:	 Latent Scores 
#> MVN Draws:		 500 
#> Confidence Level:	 0.95 
#> Missing Data:		 Listwise deletion 
#> Scale Displacements:	 90 135 180 225 270 315 360 45 
#> 
#> 
#> # Latent (SEM-based) SSM
#> 
#> Measurement model:	 scaled fixed-angle circumplex
#> Global fit (N = 1166, robust): chisq(17) = 300.546, p < 0.001 
#> 			CFI = 0.93, RMSEA = 0.13, SRMR = 0.072
#> 
#> # Profile [NARPD]:
#> 
#>                Estimate   Lower CI   Upper CI
#> Elevation         0.249      0.210      0.295
#> X-Value          -0.009     -0.054      0.033
#> Y-Value           0.231      0.189      0.273
#> Amplitude         0.232      0.192      0.274
#> Displacement     92.132     82.515    104.461
#> Model Fit         0.975                      
#> 
# }