--- title: "Evaluating Circumplex Structure" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Evaluating Circumplex Structure} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` ```{r setup} library(circumplex) ``` ## 1. Two questions to ask before interpreting an SSM analysis The Structural Summary Method (SSM) condenses a circumplex profile into a few interpretable parameters: elevation, amplitude, displacement, and fit. That condensation rests on two assumptions that are testable but often left untested: 1. **Does the instrument actually have circumplex structure?** The SSM locates a profile on a circle whose positions are given by the scales' theoretical angles. If the scales do not really form a circumplex — or sit at very different angles than the theory says — the summary is distorted before any profile is computed. 2. **Are the confidence intervals trustworthy at your sample size and profile?** Zimmermann and Wright (2017) showed that the accuracy of bootstrap SSM intervals depends on the sample size, the instrument's correlation structure, and — for amplitude and displacement — on how differentiated the profile really is in the population. Intervals that are accurate for one construct in your table can be inaccurate for the construct printed directly below it. This vignette shows how to answer both questions with `cpm_fit()` and `fit_structure()` (question 1) and `ssm_ci_accuracy()` (question 2), using the `jz2017` dataset — the same sample of 1,166 undergraduates analyzed in Zimmermann and Wright (2017, Study 5), with octant scores on the IIP-SC and personality disorder (PD) scales from the PDQ-4+. ## 2. Does the instrument fit a circumplex? ### Fitting the circular process model `cpm_fit()` estimates Browne's (1992) circular process model (CPM), the confirmatory model behind the CIRCUM and CircE programs. Each scale gets an estimated angle on the circle and a *communality index* $\zeta$ (the correlation between the scale and the common circumplex "factor"; its square, $\zeta^2$, is the scale's *communality* — the share of its variance the circumplex explains). The model also yields the usual covariance-structure fit indices. On the raw-data path the default confidence intervals are bootstrapped. We lower `boots` from its default of 2000 to keep this vignette quick to build; in practice, use the default. ```{r cpm} data("jz2017") set.seed(12345) cpm <- cpm_fit(jz2017, scales = PANO(), angles = octants(), boots = 500) summary(cpm) ``` Two parts of this output matter most for evaluating structure: - **The estimated angles.** Compare them with the theoretical angles: the IIP-SC octants land near — but not exactly on — their theoretical positions, so the circumplex ordering is preserved while the *spacing* is not perfectly equal. This is the typical result for well-validated circumplex instruments: minor deviations from perfect structure are common and have little practical impact on SSM profiles (Gurtman & Pincus, 2000). - **The communality indices.** Scales with low $\zeta$ are poorly described by the circle; a profile peak at such a scale's angle means less than the same peak at a well-explained scale's angle. The estimated configuration is easiest to read on the circle itself: each scale is drawn at its estimated angle, at a radius equal to its communality ($\zeta^2$), with a joint confidence region where one is estimable. ```{r cpm_plot, fig.width = 7.5, fig.height = 4.5, out.width = "100%"} plot(cpm) ``` ### Reading the fit indices The `summary()` output reports the standard indices, and the standard benchmarks apply: RMSEA at or below about .08 suggests adequate approximate fit and above about .10 poor fit (Browne & Cudeck, 1993); SRMR at or below about .08 suggests acceptable average residuals (Hu & Bentler, 1999); CFI and TLI near .95 or above suggest good comparative fit (Hu & Bentler, 1999). Treat these as conventions from the broader covariance-structure literature, not circumplex-specific laws. Two caveats come from the benchmark sources themselves. Browne and Cudeck call their own RMSEA thresholds "based on subjective judgment," cautioning that such a figure "cannot be regarded as infallible or correct" (Browne & Cudeck, 1993) — read the cutoffs as conventions, not decision rules. And these benchmarks are least dependable at small samples: Hu and Bentler (1999) found that the ML-based TLI and RMSEA tend to *overreject* true-population models when the sample is small (CFI is not among the indices they flag), and circumplex analyses are often run at modest sample sizes — the SSM accuracy thresholds in Section 3 span roughly $n = 50$ to $200$. At small $n$, then, a TLI or RMSEA that falls short of its benchmark can reflect the index's small-sample behavior as much as the model's fit. Two further cautions are circumplex-specific, both from this package's own validation simulations: - **Boundary solutions are common at realistic sample sizes.** When octant scales share a strong general factor (as interpersonal problem scales do), fitted solutions frequently sit at or near a parameter boundary — a communality estimate at 1 (a "Heywood" case), or a harmonic weight at 0. `cpm_fit()` flags these in its diagnostics. They are usually a property of the estimator meeting real data at finite $n$, not a data-entry error, but they matter for inference (next point). - **Do not lean hard on the chi-square p value.** In simulations at field-typical sample sizes with octant-like population structures, the test statistic did not follow its nominal chi-square reference distribution, even for correctly specified models. Read the chi-square descriptively (bigger is worse), and prefer RMSEA/SRMR/CFI for judging approximate fit. For the same reasons, when the intervals are analytic (Wald) — the only option on the correlation-matrix input path — `summary()` prints a caution below $N = 2000$, and up to very large $N$ when a boundary marker is present: in validation, analytic intervals mis-covered in exactly those regimes. Prefer the bootstrap (the raw-data default) when you have raw data. ### Comparing model variants Constrained variants make the structural question sharp: is the instrument consistent with *equally spaced* scales? With *equal* communalities? The correlation-matrix path is convenient for this comparison (point estimates and fit indices are deterministic, so no bootstrap is needed): ```{r variants} R <- cpm$matrices$R # the sample correlation matrix stored by cpm_fit() fits <- lapply( c("quasi-circumplex", "equal-communality", "circulant"), function(mod) { cpm_fit( cormat = R, scales = PANO(), angles = octants(), n = nrow(jz2017), model = mod ) } ) data.frame( model = vapply(fits, function(f) f$details$model, character(1)), df = vapply(fits, function(f) f$fit$df, numeric(1)), rmsea = round(vapply(fits, function(f) f$fit$rmsea, numeric(1)), 3), srmr = round(vapply(fits, function(f) f$fit$srmr, numeric(1)), 3), cfi = round(vapply(fits, function(f) f$fit$cfi, numeric(1)), 3), tli = round(vapply(fits, function(f) f$fit$tli, numeric(1)), 3) ) ``` The pattern reproduces what Zimmermann and Wright (2017, p. 14) reported for these data with CircE: the fully constrained model (equal spacing *and* equal communality — the `"circulant"` variant) fits poorly, while relaxing the equal-spacing constraint improves fit to the edge of the conventional benchmarks (marginal by RMSEA, acceptable by SRMR and CFI); they reported CFI = .824, TLI = .795, RMSEA = .169 for the former and CFI = .958, TLI = .931, RMSEA = .098 for the latter. Do not expect the default fit's indices to match theirs to the digit: CIRCUM/CircE fit a covariance version of the model with free scaling constants, whereas `cpm_fit()` by default fits the correlation structure directly, and the two differ slightly at finite sample sizes; pass `scaling = "free"` to fit their covariance parameterization and reproduce published CIRCUM/CircE output exactly. For the model test the choice does not matter here: with correlation input the two families' test statistics are calibration-indistinguishable (differing by well under 1% of the model degrees of freedom in paired simulation at sample sizes 250–50,000; the free statistic never exceeds the default's on the same input beyond numerical tolerance, since the free family nests the default and is additionally started from its solution), and the default is recommended for routine inference because free scaling adds parameters whose analytic standard errors are often undefined at small-to-moderate samples. The *conclusion* — ordered octants with unequal spacing, adequate approximate fit once equal spacing is not forced — is the same. A poor CPM fit does not make SSM output uncomputable; it makes the summary less meaningful, because the profile is being referred to scale positions the data contradict. If the ordering itself fails (scales out of sequence around the circle), SSM parameters should not be interpreted. ## 3. Can you trust your confidence intervals? ### What Zimmermann & Wright (2017) found Zimmermann and Wright's simulation studies (their Studies 1–4) evaluated the accuracy of 95% percentile bootstrap intervals for SSM parameters — the same interval type `ssm_analyze()` reports — judging an interval accurate when its empirical coverage stayed within Bradley's (1978) liberal band of 92.5% to 97.5%. Their headline results: | Parameter | Point estimate | 95% bootstrap CI accurate when... | |---|---|---| | Elevation ($e$) | essentially unbiased | $n \ge 50$ | | X value / affiliation | essentially unbiased | $n \ge 50$ | | Y value / dominance | essentially unbiased | $n \ge 50$ | | Amplitude ($a$) | **biased upward**, strongly so when population amplitude is small | $n \ge 75$ (general-factor instrument) or $n \ge 150$ (no general factor), *given* population amplitude $\ge .10$ | | Displacement ($\delta$) | unbiased but imprecise at low amplitude | $n \ge 100$ (general factor) or $n > 200$ (no general factor), *given* population amplitude $\ge .10$ | | Fit ($R^2$) | biased downward | population $R^2 < .9$ only; unsuited near 1 | *(Transcribed from Zimmermann & Wright, 2017, Studies 1–2, pp. 6–11.)* Three implications are worth internalizing: - **Amplitude overestimates differentiation.** Across their conditions the relative bias averaged 15.5% and reached 135.8%; with $n = 50$ and no general factor, the *expected* sample amplitude was about .15 when the population amplitude was exactly zero (their pp. 6–7). An amplitude of .15 is commonly read as "marked"; at small $n$ it can be pure sampling artifact. - **Displacement is only as stable as amplitude is large.** The standard error of the displacement grows as amplitude shrinks (e.g., roughly 50 degrees at $n = 100$ for a weakly differentiated profile; their p. 8). A displacement estimate from a flat profile has no meaningful direction. - **The thresholds above are grid minima, not guarantees.** They come from specific instruments, specific sample sizes, and population amplitudes of .10 or larger. Their Study 3 quantified the frontier more finely: the minimum population affiliation/dominance component needed for accurate amplitude and displacement intervals is approximately $2.95 \cdot f_a \cdot n^{-0.587}$, where $f_a$ is an instrument constant (their Eq. 3; ≈ .55 for the IIP-C, .63 for the IIP-SC, .85 for the IAS). At $n = 100$ with an IIP-C-like instrument that is a population component of about .11 — larger than many real construct profiles. ### Simulating coverage for your own analysis Published thresholds cover a coarse grid of conditions, and your analysis — your instrument, your $n$, your group sizes, your profile, your number of bootstrap resamples — usually falls between or outside the grid points. `ssm_ci_accuracy()` answers the question directly at your configuration: it builds a population whose structure matches your fitted estimates (through the CPM by default), simulates many datasets of your exact sample size from it, replays your own CI procedure on each, and reports how often the intervals covered the known population values. To see it catch a real problem, we analyze two PD scales at a modest sample size: paranoid PD (a well-differentiated interpersonal profile) and obsessive–compulsive PD, whose profile Zimmermann and Wright's Table 4 showed to be nearly flat (amplitude .012 at full sample size). We use the first 250 participants — a sample size many construct-validation studies would consider respectable. ```{r accuracy} set.seed(23456) res <- ssm_analyze( jz2017[1:250, ], scales = PANO(), angles = octants(), measures = c("PARPD", "OCPD"), boots = 500 # reduced from the default 2000 to keep the vignette quick; # the diagnostic below replays whatever procedure this object used ) summary(res) ``` Note the guardrail in the printed output: when a profile's amplitude CI lower bound sits less than 0.35 CI-widths above zero, `ssm_analyze()` marks the displacement as uninterpretable rather than certifying its direction. That rule is scale-free (it compares the lower bound to the interval's own width, so it means the same thing on any score metric) and does not depend on the display precision. The diagnostic below measures, among other things, how well that certification rule performs at your configuration. We again use reduced settings (`reps = 200`, a short amplitude ladder, and the smaller `boots` above) to keep the vignette fast; the defaults (`reps = 1000`, four ladder rungs, on an object built with the default `boots = 2000`) give a Monte Carlo standard error under one percentage point for coverage near the nominal level and are recommended in practice. The `parallel`/`ncpus` arguments speed up real runs without changing results for a given seed. ```{r accuracy_run} set.seed(34567) acc <- ssm_ci_accuracy(res, reps = 200, amplitude_factors = c(1, 0.5, 0)) summary(acc) ``` How to read this output: - **The coverage table** reports, for each parameter, how often your CI procedure covered the truth in the simulated replications, at the amplitude the profile was estimated to have (`Condition = 1`) and at fractions of it. Compare coverage against the nominal level using the Wilson interval and the Bradley band, which is what the verdict does for you. - **The amplitude ladder** (`Condition` column) matters because your estimated amplitude is biased upward — the population that generated your data plausibly has *less* differentiation than your estimate. The rungs below 1 show what happens to coverage in that direction; the 0 rung shows the degenerate flat-profile case, where displacement has no true value at all and the amplitude interval cannot cover the boundary truth (its printed zero coverage is structural, flagged in the table). When a profile's estimated amplitude is smaller than half its own CI width — as for obsessive–compulsive PD here — the diagnostic adds one more rung at a scaling factor above 1, the amplitude at which the population would sit exactly at the observed CI half-width. - **The guardrail table** reports how often profiles were *certified* (amplitude CI lower bound at least 0.35 CI-widths above zero) at each rung. At the 0 rung, any certification is a false certification: the summary prints a caution when the false-certification rate is materially above the rate a user would expect from the interval level. This is a measured property of the shipped display rule, not a hypothesis test. - **The verdict** classifies elevation, amplitude, and certification-conditional displacement coverage at your as-estimated amplitude, and the plain-language paragraph states the overall conclusion per profile. For a visual summary across the ladder: ```{r accuracy_plot, fig.width = 7.5, fig.height = 5, out.width = "100%"} plot(acc) ``` The two profiles tell usefully different stories. Paranoid PD is certified: its amplitude CI lower bound clears the 0.35-CI-width margin, so `ssm_analyze()` reports its displacement, and nothing in its coverage table clearly leaves the Bradley band at the as-estimated amplitude or with the population amplitude halved. Obsessive–compulsive PD is *not* certified — its amplitude (about .02 here) is far too close to zero relative to its CI width — so the printed output already withholds its displacement as uninterpretable, before any coverage question is asked. On top of that, the diagnostic shows its amplitude and displacement CIs under-cover badly at this sample size (missing below the truth), so its verdict is a caution for a genuine reason: the intervals themselves are unreliable, not merely the point on the circle. The guardrail line confirms the rule is doing its job. At this configuration ($n = 250$, eight octant correlations), a profile whose true amplitude is exactly zero would be certified only about the benchmark rate — roughly the one-sided error a user reading the guardrail would expect — so no caution fires from the guardrail itself. This is the scale-free rule's payoff: unlike a fixed amplitude-unit cutoff, it holds false-certification near its intended rate even in the near-zero regime Zimmermann and Wright flagged, where a sample amplitude large enough to look non-zero is otherwise the *expected* outcome from a flat population. One reading note: at reduced `reps`, classes tend to print as `borderline` — the Wilson interval around the estimated coverage is too wide to place it clearly inside or outside the Bradley band. That is the diagnostic being honest about its own Monte Carlo error; the default `reps = 1000` sharpens such classifications into `adequate` or `inadequate`. Two settings worth knowing: `structure = "observed"` rebuilds the population from the pooled observed correlations instead of the CPM — if the two structures yield different verdicts, that disagreement is itself informative (structure uncertainty is material for your data); and the embedded CPM fit is returned as `acc$cpm` for inspection with the tools from Section 2. The diagnostic itself was validated against Zimmermann and Wright's published results: configured to their transcribed simulation conditions, it reproduces their accuracy classifications — coverage inside the Bradley band at conditions they found accurate, and the same one-sided under-coverage at conditions they found inaccurate. ### When to trust SSM parameters Putting Sections 2 and 3 together into a checklist: 1. **Structure first.** Fit `cpm_fit()` to your instrument in your sample. If the octant ordering fails or communalities are very low, stop; SSM positions mean little. 2. **Elevation is the robust parameter.** Essentially unbiased, and its intervals were accurate from $n \ge 50$ in every published and package-run condition. (On the correlation path, elevation is also the parameter ipsatizing destroys — see Section 4.) 3. **Treat amplitude as optimistic.** It cannot go below zero, so it overshoots when true differentiation is weak. Before interpreting a "marked" amplitude at modest $n$, run `ssm_ci_accuracy()` and look at the sub-1 ladder rungs. 4. **Only interpret displacement when amplitude is credible.** The package already withholds the displacement interval when the amplitude CI lower bound sits less than 0.35 CI-widths above zero; the diagnostic tells you how reliable that certification is at your configuration. 5. **Do not build claims on the fit parameter's interval.** Zimmermann and Wright found bootstrap $R^2$ intervals accurate only when population fit was mediocre — near-perfect prototypicality cannot be bracketed from below. Report $R^2$ descriptively. 6. **Remember what the diagnostic conditions on.** It asks "would my CI procedure work in a population *like my estimates*", under multivariate normality, with complete data. It is a strong check, not a certificate. ## 4. Does the instrument have circumplex structure at all? Section 2's confirmatory model (`cpm_fit()`) fits one theory-driven circular model and asks how well it fits. A complementary, more exploratory question is whether the scales' correlations show circumplex structure *at all*, without committing to the theoretical angles: are the scales spread evenly around a circle, with comparable communalities, rather than clustering into a small number of independent clusters (simple structure)? Acton and Revelle (2004) evaluated ten such criteria by simulation; `fit_structure()` implements four of them — Fisher, Gap, VT2, and Rotation — leaving out a variance-test variant A&R found ineffective (VT1) and a criterion so highly correlated with Rotation as to be redundant (MT, r = .99 with RT in their Table 1). A fifth test, RANDALL, is not one of A&R's ten at all: it is an independent order-correspondence test (Hubert & Arabie, 1987; Tracey, 1997) that A&R excluded from their own simulation because, unlike their criteria, its null distribution is known analytically rather than needing simulated cutoffs (their footnote 3). ### The five tests `fit_structure()` extracts the first two unrotated principal-axis factors of the scales' correlation matrix (Acton & Revelle, 2004, p. 13) and computes four criteria from that two-factor solution, plus a fifth test that works directly on the correlations: - **Fisher Test** (equal axes). Are the scales' communalities on the two-factor solution comparable, rather than one axis dominating? The statistic is the coefficient of variation of the scales' vector lengths $\sqrt{h^2}$. - **Gap Test** (equal spacing). Are the scales evenly distributed in angle around the circle, rather than bunched together? The statistic is the variance of the angular gaps between angularly adjacent scales, including the gap that wraps from the last scale back around to the first. - **Variance Test (VT2)** and **Rotation Test** (interstitiality). Both ask whether the scales sit *between* a small number of dominant axes rather than on them — the signature of a genuine circumplex, as opposed to simple structure. Each takes a criterion computed at many rotations of the two-factor solution and summarizes it as a coefficient of variation across rotations; a true circumplex is indifferent to rotation, so both criteria stay low. - **RANDALL** (Hubert & Arabie, 1987; Tracey, 1997). Does the *hypothesized circular order* you supplied (the order of `scales`) match the observed correlations, in the sense that closer-together scales correlate more strongly? Unlike the other four, this is a genuine randomization test: its null distribution (scales randomly relabeled onto the hypothesized positions) is enumerated exactly for up to nine scales, or estimated by Monte Carlo relabeling for more, so it returns an exact or Monte Carlo p value rather than a simulated cutoff. The four factor-analytic criteria (Fisher, Gap, VT2, Rotation) have the most power to detect simple structure when there is no large general factor across the scales. *Deviation scoring* — centering each respondent on their own mean across the selected scales, exactly what `ipsatize()` does — approximates removing that general factor (Acton & Revelle, 2004, p. 9), so it is `fit_structure()`'s default; pass `scoring = "raw"` to analyze the scores as given. Each of the two scorings carries its own set of cutoffs (next section), matched automatically. ```{r fit_structure} res <- fit_structure(jz2017, scales = PANO()) res ``` ```{r fit_structure_summary} summary(res) ``` `summary()` adds the numeric cutoffs behind each classification and the estimated angle and communality of every scale on the two-factor solution — the same geometry the plot below draws. A clean circumplex shows scales at roughly the theoretical octant spacing with broadly similar communalities; `Fisher` measures departures in communality, `Gap`/`VT2`/`Rotation` measure departures in even angular spread. ```{r fit_structure_plot, fig.width = 7, fig.height = 4.5, out.width = "100%"} plot(res) ``` For the IIP-SC octants the picture agrees with Section 2's CPM fit: the scales keep their theoretical circular *ordering* with comparable communalities and roughly even spacing, and the Fisher, Gap, and interstitiality criteria all classify the configuration as consistent with (or close to) a circumplex under deviation scoring. One caveat when reading the angles: the two-factor solution is *unrotated*, so its absolute orientation is arbitrary — it is the scales' ordering and relative spacing that agree with theory, not their absolute angles (which is why `summary()` places PA well away from its nominal 90°). RANDALL's p value confirms the hypothesized circular order directly, independent of the factor-analytic criteria. ### Where the cutoffs come from The four factor-analytic criteria are only as good as the thresholds used to classify them, and this is where the published article cannot be used as-is. Acton and Revelle calibrated their cutoffs by simulation at 64 and 128 variables and reported (their p. 18) that the Gap Test's cutoffs shift sharply with the number of scales — far too sharply to reuse at the eight scales a typical circumplex instrument has. This package's development process re-derived every cutoff at $n_v = 8$ under Acton and Revelle's own generating model (their Eqs. 11.1–11.3), in a script committed at `data-raw/structure-test-cutoffs.R`: it first reproduced their published 64/128-variable design as a sanity gate on the simulation machinery, then reran the same design at $n_v = 8$ to derive the constants `fit_structure()` actually uses. The nv effect the re-derivation found is large — the raw- scored Gap Test's "almost certain" cutoff moves from .01 at $n_v = 64/128$ to .35 at $n_v = 8$ — which is exactly why `fit_structure()` refuses to interpret any scale count it has not calibrated: at any $n_v \ne 8$ the statistics are still reported, but the classification column prints a dash rather than guessing. RANDALL needs no such calibration; its p value comes from enumerating (or Monte Carlo sampling) the randomization null directly on your data, so it is available at any scale count of four or more. ### Reading the classifications The classification categories describe where a statistic falls among the simulated distributions for competing structures (circumplex vs. simple structure): "almost certain" (below the 1st percentile of the competing distribution), "at least 3x/2x as likely as the alternative" (the criterion's structure is at least three/two times as likely as its competitor at that statistic value), and "not clearly supported". Those ratios are *likelihood ratios*, not posterior probabilities or p values. They are **heuristic classifications read off simulated distributions, not significance tests**, and `fit_structure()`'s `print()`/`summary()` output repeats that caveat every time an interpretation is shown. Treat a "weak" or unsupported classification as a caution to inspect the loading configuration (the plot above) and Section 2's CPM fit together, not as a rejection of any specific hypothesis. ### How this complements the CPM fit `cpm_fit()` (Section 2) and `fit_structure()` ask related but different questions. `cpm_fit()` commits to the theoretical angles and communality model and tests goodness of fit against that specific structure; a good overall RMSEA/CFI can still hide unequal spacing or a dominant general factor, both of which `fit_structure()` is built to detect. Conversely, `fit_structure()`'s exploratory criteria say nothing about how well the scales match *your* theoretical angles — only RANDALL, via the order you supply, references a hypothesis at all, and even that is an order hypothesis, not the specific angles `cpm_fit()` estimates. Running both is more informative than either alone: agreement between a good CPM fit and circumplex-supporting `fit_structure()` classifications is stronger evidence than either result on its own, and disagreement (for example, adequate CPM fit alongside a Fisher Test flagging unequal axes) points to exactly which aspect of circumplex structure to examine further. ## 5. Ipsatization and what it costs Ipsatizing — subtracting each respondent's own mean across the octant scales from each of their scale scores (`ipsatize()`) — is a common preprocessing step in circumplex work, used to remove individual differences in overall endorsement before examining profile shape. For SSM analyses its main cost is simple to state: **ipsatizing discards elevation.** After row-centering, every respondent's octant scores sum to zero, so a group's mean profile has zero mean by construction, and the covariances between the ipsatized scales and any external measure sum to exactly zero — forcing the mean correlation toward zero regardless of how strongly the construct relates to the instrument's general factor (Zimmermann & Wright, 2017, p. 4). ```{r ipsatize} set.seed(45678) res_raw <- ssm_analyze( jz2017, scales = PANO(), angles = octants(), measures = "PARPD", boots = 100 ) jz_ips <- ipsatize(jz2017, items = PANO()) set.seed(45678) res_ips <- ssm_analyze( jz_ips, scales = paste0(PANO(), "_i"), angles = octants(), measures = "PARPD", boots = 100 ) comparison <- rbind( res_raw$results[, c("e_est", "a_est", "d_est")], res_ips$results[, c("e_est", "a_est", "d_est")] ) rownames(comparison) <- c("raw", "ipsatized") round(comparison, 3) ``` The raw-score elevation — which matches the value Zimmermann and Wright report for this scale in their Table 4 — collapses to near zero after ipsatizing. The displacement stays close to its raw-score value, and the amplitude stays broadly similar — though not identical, because ipsatizing also changes the scales' variances and intercorrelations, so shape parameters shift somewhat too. Guidance: - If elevation carries meaning in your application (for interpersonal problems it indexes association with generalized interpersonal distress), analyze raw scores and let the SSM separate elevation from shape — that separation is exactly what the model is for. - If you receive data that were already ipsatized, do not interpret the elevation row, and say so in the write-up; amplitude and displacement remain interpretable. - Do not describe an ipsatized profile's near-zero elevation as evidence that a construct is "not generally interpersonal" — the preprocessing made that value uninformative. ## 6. Wrap-up Evaluating circumplex structure has two layers: whether the instrument behaves like a circumplex in your sample (`cpm_fit()`), and whether the inferential machinery of the SSM can be trusted at your sample size and profile (`ssm_ci_accuracy()`). Both are one function call, and both change what you should claim more often than users expect — amplitude and displacement intervals, in particular, earn their trust only when the profile is genuinely differentiated relative to the precision your sample size affords. ## References * Acton, G. S., & Revelle, W. (2004). Evaluation of ten psychometric criteria for circumplex structure. _Methods of Psychological Research Online, 9_(1), 1–27. * Bradley, J. V. (1978). Robustness? _British Journal of Mathematical and Statistical Psychology, 31_(2), 144–152. * Browne, M. W. (1992). Circumplex models for correlation matrices. _Psychometrika, 57_(4), 469–497. * Browne, M. W., & Cudeck, R. (1993). Alternative ways of assessing model fit. In K. A. Bollen & J. S. Long (Eds.), _Testing structural equation models_ (pp. 136–162). Newbury Park, CA: Sage. * Grassi, M., Luccio, R., & Di Blas, L. (2010). CircE: An R implementation of Browne's circular stochastic process model. _Behavior Research Methods, 42_(1), 55–73. * Gurtman, M. B., & Pincus, A. L. (2000). Interpersonal Adjective Scales: Confirmation of circumplex structure from multiple perspectives. _Personality and Social Psychology Bulletin, 26_(3), 374–384. * Hu, L., & Bentler, P. M. (1999). Cutoff criteria for fit indexes in covariance structure analysis: Conventional criteria versus new alternatives. _Structural Equation Modeling, 6_(1), 1–55. * Hubert, L., & Arabie, P. (1987). Evaluating order hypotheses within proximity matrices. _Psychological Bulletin, 102_(1), 172–178. * Tracey, T. J. G. (1997). RANDALL: A Microsoft FORTRAN program for a randomization test of hypothesized order relations. _Educational and Psychological Measurement, 57_(1), 164–168. * Zimmermann, J., & Wright, A. G. C. (2017). Beyond description in interpersonal construct validation: Methodological advances in the circumplex Structural Summary Approach. _Assessment, 24_(1), 3–23.