Estimate Browne's (1992) circular stochastic process model (CPM) for the correlational structure of a set of circumplex scales or items, the native replacement for the archived CircE package. Each variable is modeled as a point on a circle at an estimated angle, with a communality index and a shared correlation function; the fit of that structure is summarized with the usual covariance-structure indices (chi-square, RMSEA, SRMR, CFI, TLI).
cpm_fit(
data = NULL,
scales = NULL,
angles = octants(),
cormat = NULL,
n = NULL,
m = 3,
model = c("quasi-circumplex", "constrained-angles", "equal-communality", "circulant"),
scaling = c("unit", "free"),
reference = 1,
interval = 0.95,
ci_method = c("bootstrap", "analytic"),
boots = 2000,
listwise = TRUE
)A circumplex_cpm object: a list with results (a data frame of
estimated angles and communality indices with confidence intervals),
betas (the correlation-function weights), fit (the fit indices),
corfun (the estimated correlation function), matrices (the sample and
model-implied matrices and residuals), and details (model, diagnostics,
and settings). See print.circumplex_cpm() and summary.circumplex_cpm().
A data frame or matrix containing the circumplex scales (raw-data
path). Supply exactly one of data or cormat.
For the raw-data path, a character vector of column names (or a
numeric vector of column indexes) selecting the circumplex scales. For the
cormat path, optional labels for the variables (defaults to the matrix
dimnames, or V1, V2, ...).
A numeric vector of the theoretical angular displacement of
each scale, in degrees, used both as the reference/identifying angle and as
optimization start values (default = octants()). Its length must match
the number of scales.
A correlation matrix (the matrix-input path, CircE-style).
Supply exactly one of data or cormat. Must be symmetric with a unit
diagonal and positive definite.
For the cormat path, the sample size (number of observations) the
correlation matrix was computed from. The test statistic uses N - 1 (the
Wishart degrees of freedom); pass the raw sample size here.
The number of harmonics in the correlation function (default = 3,
the octant-scale convention). Capped at floor((p - 1) / 2) for the
free-angle variants and floor(p / 2) for the fixed-angle variants.
The model variant (design of Browne 1992): "quasi-circumplex"
(default; free angles and communalities), "constrained-angles" (angles
fixed at their theoretical values), "equal-communality" (a single shared
communality), or "circulant" (both constraints).
The covariance-scaling family, orthogonal to model:
"unit" (default) fits the correlation structure with a unit model-implied
diagonal (the historical behaviour); "free" fits Browne's covariance
structure \(\Sigma = D_\sigma P D_\sigma\) with p free variance scales,
the parameterization CIRCUM and CircE use, so cpm_fit() can reproduce
their published output exactly. Free scaling adds p parameters but leaves
the degrees of freedom unchanged (it fits the p extra diagonal
covariance moments). For the model test the two families are
calibration-indistinguishable at correlation input — in paired simulation
at the measured truths (n from 250 to 50,000) their test statistics
differed by well under 1 percent of the degrees of freedom — so neither
family's chi-square is more trustworthy than the other's. (The two
statistics are close but not interchangeable digit-for-digit: the free
family nests the unit family, and its optimizer is additionally started
from the unit solution, so on the same input the free statistic never
exceeds the unit statistic beyond the engine's numerical tolerance —
fits whose boundary harmonics are polished away are compared on their
own reduced model.) "unit" remains
the default because free scaling buys no inferential benefit for
correlation input while adding p parameters whose analytic standard
errors are frequently undefined below n = 2000; choose "free" when the
goal is reproducing published CIRCUM/CircE results. The fitted
\(\hat\sigma^2\) are reported as a
VarRatio column (the ratio of reproduced to input variance); they carry
no confidence interval. The analytic intervals for the remaining parameters
follow the same sample-size caution as the default family: their coverage
regime was measured (the free-family coverage oracle) to match it, so
summary() cautions below n = 2000 and in near-boundary fits. The input
is still a correlation matrix (unit diagonal).
The index into scales of the variable whose angle is fixed
at its theoretical value to identify the rotation (default = 1).
The confidence level for the parameter intervals (default = 0.95). The RMSEA interval is always the conventional 90 percent.
How to construct the parameter confidence intervals:
"bootstrap" (the default on the raw-data path) resamples rows,
recomputes the correlation matrix, and refits the model warm-started from
the reported solution; "analytic" uses Wald intervals from the
information matrix. On the cormat path only "analytic" is available
(there is no raw data to resample), and it is the default there.
The number of bootstrap resamples for
ci_method = "bootstrap" (default = 2000).
Whether to handle missing values by listwise deletion. Only listwise deletion is supported in this release (default = TRUE).
The bootstrap (the raw-data default) refits the model to each resampled
correlation matrix, warm-started from the reported solution, and forms
percentile intervals; angle replicates are pooled with the package's
circular quantile machinery, so an angle interval that straddles the
0/360 boundary is reported wrapped (its lower limit numerically exceeds
its upper limit, as with displacement intervals in ssm_analyze()).
Resamples with a degenerate (non-positive-definite) correlation matrix or
a refit failing the convergence acceptance criterion are excluded with a
warning reporting how many; the intervals are then conditional on
estimability. Analytic (Wald) intervals are asymptotically valid but can
materially mis-cover at field-typical sample sizes; summary() prints a
caution below n = 2000. Analytic angle intervals are reported on the
unwrapped branch of the estimate (endpoints may fall outside [0, 360)
near the boundary).
Only the bootstrap consumes R's random number stream; the engine's point
estimates, fit indices, and the analytic intervals are deterministic, so
the estimates are identical across seeds and the default cormat-path
fit never touches the stream. Call set.seed() immediately before
cpm_fit() for reproducible bootstrap intervals. All resample indices
are drawn in one block before any refitting, so a given seed yields the
same intervals regardless of how many replicates are later excluded.
Browne, M. W. (1992). Circumplex models for correlation matrices. Psychometrika, 57(4), 469-497.
Other analysis functions:
cpm_simulate(),
ssm_analyze(),
ssm_analyze_long(),
ssm_ci_accuracy(),
ssm_draws(),
ssm_parameters(),
ssm_parameters_id(),
ssm_score(),
ssm_sem(),
ssm_sem_parameters(),
summary.circumplex_ssm_id()
# Raw-data path on the eight IIP-SC octant scales (bootstrap CIs; a small
# `boots` keeps the example fast -- the default is 2000)
data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
set.seed(12345)
fit <- cpm_fit(jz2017, scales = scales, boots = 100)
fit
# Matrix-input path (supply the sample size; analytic CIs)
R <- cor(jz2017[scales])
cpm_fit(cormat = R, scales = scales, n = nrow(jz2017))
Run the code above in your browser using DataLab