Package 'circumplex'

Title: Analysis and Visualization of Circular Data
Description: Circumplex models, which organize constructs in a circle around two underlying dimensions, are popular for studying interpersonal functioning, mood/affect, and vocational preferences/environments. This package provides tools for analyzing and visualizing circular data, including scoring functions for relevant instruments and a generalization of the bootstrapped structural summary method from Zimmermann & Wright (2017) <doi:10.1177/1073191115621795> and functions for creating publication-ready tables and figures from the results.
Authors: Jeffrey Girard [aut, cre] (ORCID: <https://orcid.org/0000-0002-7359-3746>), Johannes Zimmermann [aut] (ORCID: <https://orcid.org/0000-0001-6975-2356>), Aidan Wright [aut] (ORCID: <https://orcid.org/0000-0002-2369-0601>)
Maintainer: Jeffrey Girard <[email protected]>
License: GPL-3
Version: 2.0.0
Built: 2026-07-24 05:01:29 UTC
Source: https://github.com/jmgirard/circumplex

Help Index


Display the anchors of a circumplex instrument

Description

Display the anchors of a circumplex instrument including the total number of anchors and each anchor's numerical value and text label. Anchors are the response options that respondants select from (e.g., 0 = No, 1 = Yes).

Usage

anchors(x)

Arguments

x

Required. An object of the instrument class.

Value

The same input object. Prints text to console.

See Also

Other instrument functions: instruments(), items(), norms(), scales()

Examples

anchors(csip)

Unwrap a sequence of angles onto a continuous branch

Description

Unwrap a temporally ordered sequence of angular displacements (e.g., one displacement per measurement wave) onto a continuous numeric branch, so that a trajectory drifting across the 0/360 boundary becomes a smooth sequence suitable for linear growth modeling. Each input is first wrapped to [0, 360) (any real numbers are accepted); the output then starts at the first wave's wrapped value and accumulates the shortest signed rotation between successive waves, so successive values never differ by more than 180 degrees. For example, c(350, 10, 30) unwraps to c(350, 370, 390).

Usage

angle_unwrap(x)

Arguments

x

A numeric vector of angles in degrees, in temporal order. Any real values are accepted and are wrapped to [0, 360) first.

Details

Two conventions are pinned. An exact 180-degree step is directionally ambiguous; it is resolved as +180 (ascending), matching the package's contrast convention of reporting an exact half-turn as +180. A missing wave makes every subsequent step branch-ambiguous, so NA propagates from the missing wave onward rather than silently bridging the gap.

Unwrapping assumes the sequence really does move by less than a half-turn between successive waves; when the truth moves faster than the sampling (or persons occupy heterogeneous locations with no common branch), the unwrapped branch is wrong without warning. See the package's growth modeling vignette for these failure modes and the bivariate (x, y) alternative that avoids them.

Value

A plain numeric vector of the same length: the unwrapped angles in degrees on a continuous branch anchored at the first wave's wrapped value. Values may legitimately fall outside [0, 360); the LM = 360 reporting convention applies to displacements, not to the unwrapped branch (an input of 360 anchors at 0).

Examples

angle_unwrap(c(350, 10, 30))
angle_unwrap(c(10, 350, 330))
angle_unwrap(c(350, NA, 30))

Standardized octant scores on hypothetical circumplex scales

Description

A small example dataset containing standardized scores on eight hypothetical circumplex scales. Taken from Wright, Pincus, Conroy, & Hilsenroth (2009).

Usage

aw2009

Format

A data frame with 5 observations and 8 variables:

PA

circumplex scale at 90 degrees

BC

circumplex scale at 135 degrees

DE

circumplex scale at 180 degrees

FG

circumplex scale at 225 degrees

HI

circumplex scale at 270 degrees

JK

circumplex scale at 315 degrees

LM

circumplex scale at 360 degrees

NO

circumplex scale at 45 degrees

Source

doi:10.1080/00223890902935696


Reliability of the circumplex axes (Strack, Jacobs & Grosse Holtforth, 2013)

Description

Estimate the reliability (and standard error of measurement) of the two circumplex axes of an octant instrument with the item-level restricted tau-equivalent CFA of Strack, Jacobs, and Grosse Holtforth (2013). The model decomposes each item's variance into orthogonal components – a general factor, the two circumplex axes, scale specificity, and item specificity – and reads the axes' reliability off the isolated axes-variance component with the Spearman-Brown formula. It is a confirmatory, item-level complement to fit_structure()'s exploratory scale-level criteria.

Usage

axes_reliability(data, items, angles = NULL, instrument = NULL, sd = "std")

Arguments

data

A data frame (or matrix) containing the circumplex items.

items

Item selection. With instrument, a character vector of column names (or numeric indices) giving all items in item-number order, as in score(). Without instrument, a list with one element per scale, each a character vector (or numeric indices) of that scale's item columns.

angles

A numeric vector of the scales' angles in degrees (one per scale), required for the explicit map and forbidden with instrument (which supplies its own). Use octants().

instrument

Optional. A circumplex_instrument object supplying the scale angles and item membership (Scales$Angle, Scales$Items).

sd

The scale for the standard error of measurement: "std" (the default) reports the z-standardized SEm sqrt(1 - reliability); "raw" uses each axis composite's observed raw SD; or a numeric vector (length 1, recycled, or length 2 for the X and Y axes) of axis SDs.

Details

The model is fit to the item correlation matrix (the items are z-standardized) as a flat fixed-links CFA: every item loads on the two axes with fixed cosine weights, on a general factor with weight one, and on its scale's specificity factor with weight one; the two axis variances are held equal (the circumplex "no preferred rotation" axiom) and every scale-specificity variance shares one value, while item errors stay free (tau-equivalent). Only the axes-variance component feeds reliability.

The Nunnally-Bernstein axis reliability (nb_reliability) is reported alongside for comparison: it overestimates axis reliability when scale specificity is large, because it charges scale-specificity variance to the axis rather than isolating it (Strack et al. 2013, Figure 3).

Because the model is fit to the item correlation matrix as if it were a covariance matrix (the paper's own practice), the component point estimates and the reliabilities are correct, but the component standard errors and the global chi-square are approximate (Cudeck, 1989). Results are reported per axis (X and Y): for a balanced octant instrument the two axes carry the same axes-variance estimate and differ only through item_n.

Missing data are handled by listwise deletion only (a message reports the complete-case count); pairwise correlation input is never used. A boundary fit (a non-positive estimated axes variance, or any negative estimated variance) returns NA reliability and SEm with a warning and a boundary flag rather than a clipped or negative value.

Value

An object of class circumplex_axes_reliability with print() and summary() methods: results (one row per axis: the axes variance, item_n, reliability, SEm, Nunnally-Bernstein reliability, and boundary flag), components (the estimated variance components with SEs), fit (global fit indices), and details.

References

Strack, S., Jacobs, K. A., & Grosse Holtforth, M. (2013). The reliability of circumplex axes. SAGE Open, 3(2). doi:10.1177/2158244013486115

Cudeck, R. (1989). Analysis of correlation matrices using covariance structure models. Psychological Bulletin, 105(2), 317-327.

See Also

fit_structure() for exploratory circumplex-structure criteria.

Examples

# A simulated 32-item octant dataset (four items per octant scale).
data("simulated_items")

# Map the item columns to their eight scales (four items each), in the
# octants() angle order, then estimate the axes reliability.
items <- split(names(simulated_items), rep(1:8, each = 4))
res <- axes_reliability(simulated_items, items = items, angles = octants())
res
summary(res)

Circumplex coordinate system

Description

A ggplot2 coordinate system that maps Structural Summary Method parameters onto the circular circumplex canvas: the displacement aesthetic (degrees, counterclockwise from the right, with the 0/360 pole labelled 360) becomes the angle and the amplitude aesthetic becomes the radius. It owns the amplitude-to-radius scaling, so geom_ssm_point() and geom_ssm_arc() no longer take an amax, and the canvas and data layers can never disagree.

Usage

coord_circumplex(amax = NULL, center = 0, r_axis_angle = NULL, ...)

Arguments

amax

Optional. A single positive number giving the amplitude represented by the outer ring. NULL (the default) trains it from the data (as ssm_plot_circle() does).

center

Optional. A single number giving the amplitude at the center of the circle (default = 0). Ring labels and the amplitude-to-radius mapping are guaranteed to agree.

r_axis_angle

Optional. A single number giving the displacement (in degrees) along which the amplitude (radial) axis and its labels are drawn. NULL (the default) places it automatically in the widest gap between the displacement spokes, so the amplitude labels never collide with a spoke label.

...

Reserved for future extensions; currently unused.

Details

coord_circumplex() subclasses ggplot2::coord_radial() and hard-pins the angular convention (displacement 0 at the right, increasing counterclockwise, the 0/360 range with no expansion) so the circumplex angle invariants survive the transform. The amplitude at the circle's center and at its outer ring are the radial limits, set once here.

Value

A ggplot2 coordinate system that can be added to a plot with +.

See Also

Other circumplex layers: geom_ssm_arc(), geom_ssm_path(), geom_ssm_point(), ggcircumplex(), scale_x_circumplex(), theme_circumplex()

Examples

data("jz2017")
res <- ssm_analyze(jz2017, scales = 2:9, measures = "NARPD")
ggplot2::ggplot(res$results) +
  coord_circumplex(amax = 0.5) +
  geom_ssm_point(ggplot2::aes(amplitude = a_est, displacement = d_est))

Fit Browne's circular stochastic process model (circumplex fit statistics)

Description

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).

Usage

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
)

Arguments

data

A data frame or matrix containing the circumplex scales (raw-data path). Supply exactly one of data or cormat.

scales

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, ...).

angles

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.

cormat

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.

n

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.

m

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.

model

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).

scaling

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 Σ=DσPDσ\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 σ^2\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).

reference

The index into scales of the variable whose angle is fixed at its theoretical value to identify the rotation (default = 1).

interval

The confidence level for the parameter intervals (default = 0.95). The RMSEA interval is always the conventional 90 percent.

ci_method

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.

boots

The number of bootstrap resamples for ci_method = "bootstrap" (default = 2000).

listwise

Whether to handle missing values by listwise deletion. Only listwise deletion is supported in this release (default = TRUE).

Value

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().

Confidence intervals

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).

Reproducibility

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.

References

Browne, M. W. (1992). Circumplex models for correlation matrices. Psychometrika, 57(4), 469-497.

See Also

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()

Examples

# 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))

Simulate data from a fitted circular process model

Description

Draw n standardized observations from the model-implied correlation matrix P^\hat{P} of a fitted cpm_fit() object, using the low-rank factor representation P=ΛΛ+(IDζ2)P = \Lambda\Lambda^\top + (I - D_\zeta^2) (Browne, 1992; design sec. 1.3/sec. 5.4). Each observation is generated as x=Λz+(IDζ2)1/2εx = \Lambda z + (I - D_\zeta^2)^{1/2}\varepsilon with independent standard-normal common-factor scores zz and unique deviates ε\varepsilon, so the draws are exactly positive semidefinite by construction (no eigenvalue clamping) and their population correlation matrix is P^\hat{P} exactly.

Usage

cpm_simulate(object, n)

Arguments

object

A circumplex_cpm object from cpm_fit().

n

The number of observations (rows) to simulate; a positive whole number.

Details

This is the mean-based simulation path of the SSM CI-trustworthiness diagnostic (ssm_ci_accuracy(); the M4 Brief-B contract): a caller draws standardized data here and rescales it to a group's means and SDs. The correlation-based (augmented scales-plus-measures) path is not produced here – it reduces to the returned population block object$matrices$Phat, from which the caller assembles and repairs its own joint matrix.

Value

A numeric matrix with n rows and one column per fitted scale, columns in the fitted scale order with colnames set to the scale names (rownames are NULL). The population covariance is object$matrices$Phat, so cov() of the returned matrix converges to it as n grows. Under the default unit scaling Phat is a correlation matrix (zero-mean, unit-variance margins), so cor() converges to it too; under scaling = "free" the margins carry the fitted variance ratios σ^2\hat\sigma^2.

Reproducibility

cpm_simulate() consumes R's global random number stream (the common-factor scores then the unique deviates, drawn in that fixed order), so it follows the package's set.seed()-immediately-before convention: a given seed reproduces the draw exactly. It is one of the package's stochastic entry points (alongside ssm_analyze() and the bootstrap path of cpm_fit()); the fit itself is deterministic.

References

Browne, M. W. (1992). Circumplex models for correlation matrices. Psychometrika, 57(4), 469-497.

See Also

cpm_fit()

Other analysis functions: cpm_fit(), 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()

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
fit <- cpm_fit(cormat = cor(jz2017[scales]), scales = scales,
               n = nrow(jz2017))
set.seed(1)
x <- cpm_simulate(fit, n = 500)
round(cor(x) - fit$matrices$Phat, 2)

Evaluate circumplex structure (Acton & Revelle, 2004)

Description

Run the exploratory circumplex-structure criteria of Acton and Revelle (2004) on a set of scales and return one object bundling all of the tests. Four criteria are computed from the first two unrotated principal-axis factors of the scales' correlation matrix – the Fisher Test of equal axes, the Gap Test of equal spacing, the Variance Test (VT2) and Rotation Test of interstitiality – and each statistic is classified against simulation-derived, scoring- and scale-count-specific cutoffs. A fifth test, RANDALL (Hubert & Arabie, 1987; Tracey, 1997), evaluates the hypothesised circular order of the scales with a randomization test that yields a genuine p-value.

Usage

fit_structure(
  data,
  scales,
  scoring = c("deviation", "raw"),
  ridge = 0,
  n_perm = NULL,
  listwise = TRUE
)

Arguments

data

A data frame (or matrix) containing the circumplex scales.

scales

A character vector of column names (or a numeric vector of column indexes) selecting the circumplex scales, in hypothesised circular order (the order is RANDALL's order hypothesis). At least four scales are required.

scoring

Either "deviation" (the default; row-mean-center the scales before analysis) or "raw" (analyze the scores as given). Selects the matching interpretive cutoffs.

ridge

A non-negative ridge added to the diagonal of the correlation matrix (then rescaled to a unit diagonal) to repair a non-positive-definite matrix before factoring; default 0, which matches the cutoff calibration. Raise it only if factoring fails, noting that a nonzero ridge moves the statistics off the calibrated scale.

n_perm

NULL (the default) to compute RANDALL's p-value by exact enumeration, available for up to nine scales; otherwise a single positive whole number of Monte Carlo relabelings (required for ten or more scales). The Monte Carlo path draws from the global RNG stream, so set a seed with set.seed() beforehand for reproducibility. Ten or more scales require n_perm (exact enumeration is infeasible); supplying it is validated up front, before any criteria are computed.

listwise

A logical indicating whether missing values are handled by listwise deletion (TRUE, the default) or pairwise deletion (FALSE), matching ssm_analyze(). Listwise deletion gives all five tests one complete-case correlation matrix, which is the metric the interpretive cutoffs were calibrated on; pairwise deletion can yield a non-positive- definite matrix and moves the statistics off that calibrated scale.

Details

The four factor-analytic criteria have the most power when there is no large general factor, which deviation scoring (centering each respondent on their own mean across the scales, exactly what ipsatize() does) approximates by removing it (Acton & Revelle, 2004, p. 9). Deviation scoring is therefore the default and is applied to all five tests; pass scoring = "raw" to leave the scores untouched. The two scorings carry different cutoffs, matched automatically.

The interpretive cutoffs are heuristic likelihood classifications read off simulated distributions, not significance tests, and they are specific to the number of scales. Only eight scales (the canonical octant instrument) are calibrated; with any other count the statistics are still reported but no interpretation is attached (see print()/summary()). The cutoffs were re-derived under Acton and Revelle's own generating model at eight scales; see vignette("evaluating-circumplex-structure"). RANDALL needs no cutoffs: with up to nine scales its null distribution is enumerated exactly, so its p-value is available at any scale count of four or more.

Value

An object of class circumplex_structure with print(), summary(), and plot() methods. Its components are results (a data frame with one row per factor-analytic criterion: statistic, cutoffs, and interpretive category), randall (the RANDALL index, p-value, and method), loadings (the two unrotated principal-axis factors), and details.

References

Acton, G. S., & Revelle, W. (2004). Evaluation of ten psychometric criteria for circumplex structure. Methods of Psychological Research Online, 9(1), 1-27.

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.

See Also

cpm_fit() for a confirmatory circumplex model; ipsatize() for deviation scoring.

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
res <- fit_structure(jz2017, scales = scales)
res
summary(res)

Draw SSM confidence-region arcs in circumplex space

Description

A ggplot2 layer that draws, for each profile, the wedge spanning its amplitude confidence interval (radially) and its displacement confidence interval (angularly) on a circumplex canvas built with coord_circumplex() (for example the canvas from ggcircumplex()). The bounds are supplied directly in SSM units; the coordinate system bends the (displacement, amplitude) rectangle into an annular wedge.

Usage

geom_ssm_arc(
  mapping = NULL,
  data = NULL,
  stat = "identity",
  position = "identity",
  ...,
  amax = NULL,
  n = NULL,
  na.rm = TRUE,
  show.legend = NA,
  inherit.aes = TRUE
)

Arguments

mapping, data, stat, position, show.legend, inherit.aes, ...

Standard ggplot2 layer arguments. mapping must supply the amplitude_min, amplitude_max, displacement_min, and displacement_max aesthetics.

amax

(Deprecated) The amplitude represented by the outer ring is now owned by coord_circumplex(); a value supplied here is ignored with a one-time note.

n

(Deprecated) Arc smoothness is now owned by the coordinate system, which curves the wedge automatically; a value supplied here is ignored with a one-time note.

na.rm

If FALSE, warn (with the dropped-row count) before removing profiles with an incomplete confidence region (a missing amplitude or displacement bound); if TRUE (the default) remove them silently.

Details

Each arc spans counterclockwise from displacement_min to displacement_max (both in degrees). Supply them in ⁠[0, 360]⁠ (a bound of exactly 360 is the 0/360 pole under the package's LM = 360 labeling). A displacement_min greater than displacement_max is read as an interval that crosses the 0/360 seam and is drawn the short way across it (e.g. 350 -> 10 is a 20 degree arc, matching how the package stores a displacement CI that straddles the boundary). The interval must describe less than a full circle; bounds that imply a span of 360 degrees or more (for example, values outside ⁠[0, 360]⁠) are rejected, since they do not name a unique arc.

Value

A ggplot2 layer.

See Also

Other circumplex layers: coord_circumplex(), geom_ssm_path(), geom_ssm_point(), ggcircumplex(), scale_x_circumplex(), theme_circumplex()

Examples

data("jz2017")
res <- ssm_analyze(jz2017, scales = 2:9, measures = "NARPD")
ggcircumplex(octants(), amax = 0.5) +
  geom_ssm_arc(
    data = res$results,
    mapping = ggplot2::aes(
      amplitude_min = a_lci, amplitude_max = a_uci,
      displacement_min = d_lci, displacement_max = d_uci
    ),
    alpha = 0.4
  )

Draw a profile's movement across occasions in circumplex space

Description

A ggplot2 layer that connects a profile's successive positions on a circumplex canvas built with coord_circumplex() (for example the canvas from ggcircumplex()), so change in amplitude and displacement reads as movement through circumplex space. Each segment is curved along the polar geodesic by the coordinate system, which owns the transform; the layer owns the ordering, the 0/360 seam handling, and the optional arrowheads.

Usage

geom_ssm_path(
  mapping = NULL,
  data = NULL,
  stat = "identity",
  position = "identity",
  ...,
  arrow = NULL,
  na.rm = TRUE,
  show.legend = NA,
  inherit.aes = TRUE
)

Arguments

mapping, data, stat, position, show.legend, inherit.aes, ...

Standard ggplot2 layer arguments. mapping must supply the amplitude and displacement aesthetics.

arrow

An arrow specification produced by ggplot2::arrow(), or NULL (the default) for a path drawn without arrowheads. Arrowheads mark the direction of time along the path.

na.rm

If FALSE, warn when occasions with no location are removed from the ends of a path; if TRUE (the default) remove them silently. Occasions with no location in the middle of a path break it either way.

Details

Points are connected in the order the rows appear in the data, exactly as ggplot2::geom_path() does, and the group aesthetic separates one series from another. Sort the data into time order before plotting: an occasion label sorted as text puts T10 before T2, which silently reverses time. ssm_plot_circle(path = TRUE) does this sorting for you, taking the order from the object's own occasion list.

Consecutive occasions are joined the short way around the circle. The displacements of each group are unwrapped onto a continuous branch before the coordinate system sees them, so a step from 350 to 10 degrees is drawn as the 20 degree arc across the pole rather than a 340 degree sweep the long way round. Unwrapped values may therefore fall outside ⁠[0, 360)⁠. This assumes the profile rotates less than a half-turn between consecutive occasions at which its displacement is defined; no data can verify that, so widely spaced occasions should be read with it in mind.

An occasion with no defined location – a flat or zero-amplitude profile, whose displacement is undefined – breaks the path rather than being interpolated through, and the segment after the gap is still drawn on the correct branch. Non-finite amplitudes and displacements are treated the same way, since an infinite angle names no position on the circle.

Value

A ggplot2 layer.

See Also

Other circumplex layers: coord_circumplex(), geom_ssm_arc(), geom_ssm_point(), ggcircumplex(), scale_x_circumplex(), theme_circumplex()

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
# Three occasions that actually move: shifting the octant scores by one
# position rotates the fitted profile by 45 degrees per occasion.
waves <- lapply(1:3, function(k) {
  idx <- ((seq_along(scales) - 1 + (k - 1)) %% length(scales)) + 1
  d <- jz2017[, scales[idx]]
  names(d) <- scales
  d$id <- seq_len(nrow(d))
  d$occasion <- paste0("T", k)
  d
})
res <- ssm_analyze_long(do.call(rbind, waves),
  scales = scales, id = "id", occasion = "occasion"
)
ggcircumplex(octants(), amax = 0.5) +
  geom_ssm_point(
    data = res$results,
    mapping = ggplot2::aes(amplitude = a_est, displacement = d_est),
    size = 2
  ) +
  geom_ssm_path(
    data = res$results,
    mapping = ggplot2::aes(amplitude = a_est, displacement = d_est),
    arrow = ggplot2::arrow(
      length = ggplot2::unit(0.18, "inches"), type = "closed"
    )
  )

Draw SSM profile points in circumplex space

Description

A ggplot2 layer that places a point for each profile at its amplitude and displacement on a circumplex canvas built with coord_circumplex() (for example the canvas from ggcircumplex()). The amplitude and displacement are supplied directly in SSM units (amplitude in the score metric, displacement in degrees); the coordinate system performs the polar transform.

Usage

geom_ssm_point(
  mapping = NULL,
  data = NULL,
  stat = "identity",
  position = "identity",
  ...,
  amax = NULL,
  na.rm = TRUE,
  show.legend = NA,
  inherit.aes = TRUE
)

Arguments

mapping, data, stat, position, show.legend, inherit.aes, ...

Standard ggplot2 layer arguments. mapping must supply the amplitude and displacement aesthetics.

amax

(Deprecated) The amplitude represented by the outer ring is now owned by coord_circumplex(); a value supplied here is ignored with a one-time note.

na.rm

If FALSE, warn (with the dropped-row count) before removing profiles with a missing displacement or amplitude, since they have no location on the circle; if TRUE (the default) remove them silently.

Value

A ggplot2 layer.

See Also

Other circumplex layers: coord_circumplex(), geom_ssm_arc(), geom_ssm_path(), ggcircumplex(), scale_x_circumplex(), theme_circumplex()

Examples

data("jz2017")
res <- ssm_analyze(jz2017, scales = 2:9, measures = "NARPD")
ggcircumplex(octants(), amax = 0.5) +
  geom_ssm_point(
    data = res$results,
    mapping = ggplot2::aes(amplitude = a_est, displacement = d_est)
  )

Create a circumplex plotting canvas

Description

Build an empty circular canvas – the amplitude rings, displacement spokes, and scale labels that circumplex figures are drawn on – as a ggplot2 object. Additional layers (points, arcs, annotations) can be added to it with +, so it serves as the reusable foundation for custom circumplex visualizations. The package's own ssm_plot_circle() draws on the same canvas.

Usage

ggcircumplex(
  angles = octants(),
  labels = NULL,
  amax = 0.5,
  font_size = 12,
  instrument = NULL
)

Arguments

angles

Optional. A numeric vector of the angular position (in degrees) of each circumplex scale, going counterclockwise from the right (default = octants()). Ignored if instrument is supplied.

labels

Optional. Either NULL or a character vector of text labels to draw around the circle, one per angle and in the same order (default = NULL, which draws the numeric angles). If instrument is supplied, NULL uses the instrument's scale abbreviations.

amax

Optional. A single positive number giving the amplitude at the outer ring, which sets the amplitude-axis labels; the center of the circle is fixed at amplitude 0 (default = 0.5).

font_size

Optional. A single positive number giving the size (in pt) of the scale and amplitude labels (default = 12).

instrument

Optional. Either NULL or a circumplex_instrument object (see instrument()). When supplied, the scale angles and (unless labels is given) the scale abbreviations are taken from the instrument (default = NULL).

Value

A ggplot2 object containing the empty circumplex canvas.

See Also

coord_circumplex(), which owns the transform this canvas is built on; ssm_plot_circle(), which draws SSM results on this canvas.

Other circumplex layers: coord_circumplex(), geom_ssm_arc(), geom_ssm_path(), geom_ssm_point(), scale_x_circumplex(), theme_circumplex()

Examples

# A default octant canvas
ggcircumplex()

# Label the scales with their circumplex pole abbreviations
ggcircumplex(octants(), labels = PANO())

# Derive the angles and labels from a circumplex instrument
ggcircumplex(instrument = csip)

Format and render data frame as HTML table

Description

Format a data frame as an HTML table and render it to the web viewer.

Usage

html_render(df, caption = NULL, align = "l", ...)

Arguments

df

A data frame to be rendered as an HTML table.

caption

A string to be displayed above the table.

align

A string indicating the alignment of the cells (default = "l").

...

Other arguments to pass to htmlTable.

Value

HTML syntax for the df table.

See Also

Other table functions: ssm_table()


List all available instruments

Description

The circumplex package includes information about numerous circumplex instruments including instructions for scoring and standardizing items. Individual instruments can be loaded using the instrument function.

Usage

instruments()

See Also

Other instrument functions: anchors(), items(), norms(), scales()

Examples

instruments()

Ipsatize circumplex items using deviation scoring across variables

Description

Rescore each circumplex item using deviation scoring across variables. In other words, subtract each observation's mean response from each response. This effectively removes the presence of a general factor, which can make certain circumplex fit analyses more powerful.

Usage

ipsatize(data, items, na.rm = TRUE, prefix = "", suffix = "_i", append = TRUE)

Arguments

data

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

items

Required. A character vector containing the column names, or a numeric vector containing column indexes, of item variables in data to be ipsatized.

na.rm

Optional. A logical that determines whether missing values should be ignored during the calculation of the mean during ipsatization (default = TRUE).

prefix

Optional. A string that will be added to the start of each items name in the output (default = "").

suffix

Optional. A string that will be added to the end of each items name in the output (default = "_i").

append

Optional. A logical that determines whether to append the ipsatized scores to data in the output or just return the ipsatized scores alone (default = TRUE).

Value

A data frame that matches data except that the variables specified in items have been rescored using ipsatization.

See Also

Other tidying functions: norm_standardize(), score(), self_standardize()

Examples

data("raw_iipsc")
ipsatize(raw_iipsc, items = 1:32)
ipsatize(raw_iipsc, items = sprintf("IIP%02d", 1:32))

Display the items of a circumplex instrument

Description

Display the items of a circumplex instrument including the total number of items and each item's number and text. The item ordering/numbering displayed here is the same ordering/numbering assumed by the score() function.

Usage

items(x)

Arguments

x

Required. An object of the instrument class.

Value

The same input object. Prints text to console.

See Also

Other instrument functions: anchors(), instruments(), norms(), scales()

Examples

items(csip)

Raw octant scores on real circumplex scales with covariates

Description

A large example dataset containing gender, raw mean scores on the Inventory of Interpersonal Problems - Short Circumplex (IIP-SC), and raw sum scores on the Personality Diagnostic Questionnaire - 4th Edition Plus (PDQ-4+).

Usage

jz2017

Format

A data frame with 1166 observations and 19 variables:

Gender

Self-reported Gender

PA

Domineering Problems (IIP-SC) 90 degrees

BC

Vindictive Problems (IIP-SC) 135 degrees

DE

Cold Problems (IIP-SC) 180 degrees

FG

Socially Avoidant Problems (IIP-SC) 225 degrees

HI

Nonassertive Problems(IIP-SC) 270 degrees

JK

Easily Exploited Problems (IIP-SC) 315 degrees

LM

Overly Nurturant Problems (IIP-SC) 360 degrees

NO

Intrusive Problems (IIP-SC) 45 degrees

PARPD

Paranoid PD Symptoms (PDQ-4+)

SCZPD

Schizoid PD Symptoms (PDQ-4+)

SZTPD

Schizotypal PD Symptoms (PDQ-4+)

ASPD

Antisocial PD Symptoms (PDQ-4+)

BORPD

Borderline PD Symptoms (PDQ-4+)

HISPD

Histrionic PD Symptoms (PDQ-4+)

NARPD

Narcissistic PD Symptoms (PDQ-4+)

AVPD

Avoidant PD Symptoms (PDQ-4+)

DPNPD

Dependent PD Symptoms (PDQ-4+)

OCPD

Obsessive-Compulsive PD Symptoms (PDQ-4+)

Source

doi:10.1177/1073191115621795


Standardize circumplex scales using normative data

Description

Take in a data frame containing circumplex scales, angle definitions for each scale, and normative data (from the package or custom) and return that same data frame with each specified circumplex scale transformed into standard scores (i.e., z-scores) based on comparison to the normative data.

Usage

norm_standardize(
  data,
  scales,
  angles = octants(),
  instrument,
  sample = 1,
  prefix = "",
  suffix = "_z",
  append = TRUE
)

Arguments

data

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

scales

Required. A character vector containing the column names, or a numeric vector containing the column indexes, for the variables (scale scores) to be standardized.

angles

Required. A numeric vector containing the angular displacement of each circumplex scale included in scales (in degrees). Can use the octants(), poles(), or quadrants() convenience functions. Each angle is matched to the instrument's normative data by angular position, so 0 and 360 degrees are treated as the same angle; an angle with no matching normative row (or with more than one) produces an informative error.

instrument

Required. An instrument object from the package. To see the available circumplex instruments, see instruments().

sample

Required. An integer corresponding to the normative sample to use in standardizing the scale scores (default = 1). See ?norms to see the normative samples available for an instrument.

prefix

Optional. A string to include at the beginning of the newly calculated scale variables' names, before the scale name and suffix (default = "").

suffix

Optional. A string to include at the end of the newly calculated scale variables' names, after the scale name and prefix (default = "_z").

append

Optional. A logical that determines whether the calculated standardized scores should be added as columns to data in the output or the standardized scores alone should be output (default = TRUE).

Value

A data frame that contains the norm-standardized versions of scales.

See Also

Other tidying functions: ipsatize(), score(), self_standardize()

Examples

data("jz2017")
norm_standardize(jz2017, scales = 2:9, instrument = iipsc, sample = 1)

Display the norms for a circumplex instrument

Description

Display the norms for a circumplex instrument including the total number of normative data sets available and each data set's number, sample size, population, and source reference and hyperlink. If another normative data set exists that is not yet included in the package, please let us know.

Usage

norms(x)

Arguments

x

Required. An object of the instrument class.

Value

The same input object. Prints text to console.

See Also

Other instrument functions: anchors(), instruments(), items(), scales()

Examples

norms(csip)

Angular displacements for octant circumplex scales

Description

Return a vector of angular displacements, in degrees, for eight equally spaced circumplex scales corresponding to the circumplex octants. Can be passed to the angles parameter of other functions in this package.

Usage

octants()

Value

A numeric vector with eight elements, each corresponding to the angular displacement (in degrees) of a subscale, in the following order: PA, BC, DE, FG, HI, JK, LM, NO.

Examples

octants()

Two-letter abbreviations for octant circumplex scales

Description

Return a vector of abbreviations for octant circumplex scales, from PA to NO.

Usage

PANO(case = "upper")

Arguments

case

An optional string the determines whether the abbreviations should be in uppercase or lowercase. (default = "upper")

Value

A character vector with eight elements, each corresponding to the abbreviation of an octant subscale: PA, BC, DE, FG, HI, JK, LM, NO.

Examples

PANO()
PANO(case = "lower")

Plot SSM CI accuracy across the amplitude ladder

Description

Draw the empirical coverage from an ssm_ci_accuracy() run against its amplitude-ladder conditions: one panel per SSM parameter (including displacement conditional on guardrail certification), one line per profile row, with 95% Wilson score intervals as error bars, Bradley's (1978) liberal robustness band shaded, and the nominal confidence level as a dashed line. Amplitude rungs whose coverage is structurally zero (a percentile interval of strictly positive amplitude replicates cannot contain a zero truth; see ssm_ci_accuracy()) are drawn as open symbols. This is a Cartesian diagnostic plot, not a circumplex figure.

Usage

## S3 method for class 'circumplex_ci_accuracy'
plot(x, ...)

Arguments

x

A circumplex_ci_accuracy object from ssm_ci_accuracy().

...

Currently ignored.

Value

A ggplot2 object.

See Also

Other ssm functions: ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other visualization functions: ssm_plot_circle(), ssm_plot_contrast(), ssm_plot_curve(), ssm_plot_trajectory()

Examples

data("jz2017")
set.seed(12345)
res <- ssm_analyze(
  jz2017[1:200, ],
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  boots = 100
)
set.seed(23456)
acc <- ssm_ci_accuracy(res, reps = 25)
plot(acc)

Plot a circular process model fit

Description

Draw the estimated item configuration of a cpm_fit() object on the circular canvas from ggcircumplex(). Each scale is placed at its estimated angle (θ\theta), at a radius given by its communality (ζ2\zeta^2, the share of its variance explained by the common circumplex factors), so items that the model explains well sit near the outer ring and items it explains poorly sit near the centre. The canvas spokes mark the theoretical angles supplied to cpm_fit(), so the gap between a point and its spoke shows how far the estimated angle departed from the hypothesised one. Where the confidence intervals are estimable, a wedge spans each item's angle CI (angularly) and communality CI (radially).

Usage

## S3 method for class 'circumplex_cpm'
plot(x, amax = 1, angle_labels = NULL, legend = TRUE, ...)

Arguments

x

A circumplex_cpm object from cpm_fit().

amax

A single positive number giving the communality represented by the canvas's outer ring (default = 1, the maximum possible communality).

angle_labels

Either NULL or a character vector of spoke labels, one per scale in the fitted order. NULL (default) labels the spokes with the scale names.

legend

A logical: draw a legend keying the colours to the scale names (default = TRUE).

...

Not used. Supplying an unrecognized argument produces a warning.

Value

A ggplot2 object.

See Also

cpm_fit(), ggcircumplex()

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
set.seed(12345)
fit <- cpm_fit(jz2017, scales = scales, boots = 100)
plot(fit)

Plot a circumplex-structure configuration

Description

Draw the two-factor loading configuration of a fit_structure() object on the circular canvas from ggcircumplex(). Each scale is placed at its estimated angle (atan2 of its two principal-axis loadings) and at a radius given by its communality (the share of its variance on the first two factors), so a clean circumplex shows the scales spread evenly around a ring of similar radius, unequal axes show scales at differing radii (what the Fisher Test measures), and simple structure shows scales bunched near a few angles (what the Gap and interstitiality tests measure). The canvas spokes mark the same estimated angles, labelled by scale.

Usage

## S3 method for class 'circumplex_structure'
plot(x, amax = 1, legend = TRUE, ...)

Arguments

x

A circumplex_structure object from fit_structure().

amax

A single positive number giving the communality represented by the canvas's outer ring (default = 1). Principal-axis communalities can exceed 1 in a Heywood case; when any scale's communality exceeds amax the ring is expanded to contain it, so no point is ever drawn outside the canvas.

legend

A logical: draw a legend keying the colours to the scale names (default = TRUE).

...

Not used. Supplying an unrecognized argument produces a warning.

Value

A ggplot2 object.

See Also

fit_structure(), ggcircumplex()

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
plot(fit_structure(jz2017, scales = scales))

Angular displacements for pole circumplex scales

Description

Return a vector of angular displacements, in degrees, for four equally spaced circumplex scales corresponding to the circumplex poles. Can be passed to the angles parameter of other functions in this package.

Usage

poles()

Value

A numeric vector with four elements, each corresponding to the angular displacement (in degrees) of a subscale, in the following order: PA, DE, HI, LM.

Examples

poles()

Print circumplex axes-reliability results

Description

Compact display of an axes_reliability() object: the per-axis reliability, SEm, and Nunnally-Bernstein comparison, with the correlation-as-covariance standard-error caveat.

Usage

## S3 method for class 'circumplex_axes_reliability'
print(x, digits = 3, ...)

Arguments

x

A circumplex_axes_reliability object.

digits

The number of decimal places to display (default = 3).

...

Not used.

Value

x, invisibly.


Print a circular process model fit

Description

Compact display of a cpm_fit() object: the estimated angles and communality indices with confidence intervals, a one-line fit summary, and any boundary/convergence notes.

Usage

## S3 method for class 'circumplex_cpm'
print(x, digits = 3, ...)

Arguments

x

A circumplex_cpm object.

digits

The number of decimal places to display (default = 3).

...

Not used.

Value

x, invisibly.


Print circumplex-structure test results

Description

Compact display of a fit_structure() object: the four factor-analytic criteria with their statistics and interpretive classifications, and the RANDALL order test with its randomization p-value.

Usage

## S3 method for class 'circumplex_structure'
print(x, digits = 3, ...)

Arguments

x

A circumplex_structure object.

digits

The number of decimal places to display (default = 3).

...

Not used.

Value

x, invisibly.


Angular displacements for quadrant circumplex scales

Description

Return a vector of angular displacements, in degrees, for four equally spaced circumplex scales corresponding to the circumplex quadrants. Can be passed to the angles parameter of other functions in this package.

Usage

quadrants()

Value

A numeric vector with eight elements, each corresponding to the angular displacement (in degrees) of a subscale, in the following order: BC, FG, JK, NO.

Examples

quadrants()

Raw item responses on real circumplex scales

Description

A small example dataset containing raw item responses on the Inventory of Interpersonal Problems, Short Circumplex (IIP-SC). This data set is useful for testing functions that operate on item-level data.

Usage

raw_iipsc

Format

A data frame with 10 observations and 32 variables.


Angle-labeled x-axis scale for circumplex plots

Description

A ggplot2 continuous position scale for the angle axis of a linear circumplex plot, such as the score-by-angle curve drawn by ssm_plot_curve(). It places axis breaks at the circumplex scale angles and labels them, by default, with their angular position in degrees. Custom text labels or a circumplex_instrument can be supplied instead, using the same conventions as ggcircumplex(), so the linear axis and the circular canvas label their scales consistently.

Usage

scale_x_circumplex(angles = octants(), labels = NULL, instrument = NULL, ...)

Arguments

angles

Optional. A numeric vector of the angular position (in degrees) of each circumplex scale (default = octants()). Ignored if instrument is supplied.

labels

Optional. Either NULL or a character vector of axis labels, one per angle and in the same order (default = NULL, which labels each break with its angle in degrees, or with the instrument's scale abbreviations when instrument is supplied).

instrument

Optional. Either NULL or a circumplex_instrument object (see instrument()) from which to take the scale angles and (unless labels is given) abbreviations (default = NULL).

...

Additional arguments passed to ggplot2::scale_x_continuous(), such as name or limits.

Value

A ggplot2 scale object that can be added to a plot with +.

See Also

Other circumplex layers: coord_circumplex(), geom_ssm_arc(), geom_ssm_path(), geom_ssm_point(), ggcircumplex(), theme_circumplex()

Examples

# Degree-labeled angle axis
scale_x_circumplex(octants())

# Label the axis with an instrument's scale abbreviations
scale_x_circumplex(instrument = csip)

Display the scales of a circumplex instrument

Description

Display the scales of a circumplex instrument including the total number of scales and each scale's abbreviation, hypothetical angle, and text label.

Usage

scales(x, items = FALSE)

Arguments

x

Required. An object of the instrument class.

items

Optional. A logical determining whether the items for each scale should be displayed below its other information (default = FALSE).

Value

The same input object. Prints text to console.

See Also

Other instrument functions: anchors(), instruments(), items(), norms()

Examples

scales(csip)
scales(csip, items = TRUE)

Score circumplex scales from item responses

Description

Calculate mean scores on circumplex scales from item responses by using a set of scoring instructions, which may be loaded from the package or created as a custom data frame.

Usage

score(
  data,
  items,
  instrument,
  na.rm = TRUE,
  prefix = "",
  suffix = "",
  append = TRUE
)

Arguments

data

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

items

Required. The variable names or column numbers for the variables in .data that contain all the circumplex items from a single circumplex measure, in ascending order from item 1 to item N.

instrument

Required. An instrument object from the package. To see the available circumplex instruments, use instruments().

na.rm

Optional. A logical that determines if missing values should be omitted from the calculation of scores (default = TRUE). When set to TRUE, scales with missing data are essentially calculated with mean imputation.

prefix

Optional. A string to include at the beginning of the newly calculated scale variables' names, before Abbrev from key and suffix (default = "").

suffix

Optional. A string to include at the end of the newly calculated scale variables' names, after Abbrev from key and prefix (default = "").

append

Optional. A logical that determines whether the calculated score variables will be appended to data or returned on their own (default = TRUE).

Value

A data frame that matches .data except that new variables are appended that contain mean scores on each variable included in key.

See Also

Other tidying functions: ipsatize(), norm_standardize(), self_standardize()

Examples

data("raw_iipsc")
score(raw_iipsc, items = 1:32, instrument = iipsc, prefix = "IIPSC_")

Standardize circumplex scales using sample data

Description

Take in a data frame containing circumplex scales (or items) and return that same data frame with each specified variable transformed into standard scores (i.e., z-scores) based on observed means and SDs.

Usage

self_standardize(
  data,
  scales,
  na.rm = TRUE,
  prefix = "",
  suffix = "_z",
  append = TRUE
)

Arguments

data

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

scales

Required. A character vector containing the column names, or a numeric vector containing the column indexes, for the variables (scale scores) to be standardized.

na.rm

Optional. A logical that determines whether to remove missing values from scales when calculating the means and SDs used for standardization (default = TRUE).

prefix

Optional. A string to include at the beginning of the newly calculated scale variables' names, before the scale name and suffix (default = "").

suffix

Optional. A string to include at the end of the newly calculated scale variables' names, after the scale name and prefix (default = "_z").

append

Optional. A logical that determines whether the calculated standardized scores should be added as columns to data in the output or the standardized scores alone should be output (default = TRUE).

Value

A data frame that contains the self-standardized versions of scales.

See Also

Other tidying functions: ipsatize(), norm_standardize(), score()

Examples

self_standardize(aw2009, scales = 1:8)

Simulated item responses on octant circumplex scales

Description

A simulated item-level dataset for demonstrating axes_reliability(). It contains 1-7 Likert responses from 500 respondents on 32 items – four items on each of the eight octant circumplex scales (PA at 90 degrees through NO at 45 degrees, following octants()). The items were drawn from the five-component population of Strack, Jacobs, and Grosse Holtforth (2013): a general factor, two equal circumplex axes (axes variance .18), one shared scale-specificity component (.10), and free item error, giving an axes reliability of about .78. The data are synthetic – there is no public raw-data source for the method – and are generated by a seeded script (data-raw/simulated_items.R).

Usage

simulated_items

Format

A data frame with 500 observations and 32 variables named PA_1PA_4, BC_1BC_4, ..., NO_1NO_4 (four items per octant scale).

References

Strack, S., Jacobs, K. A., & Grosse Holtforth, M. (2013). The reliability of circumplex axes. SAGE Open, 3(2). doi:10.1177/2158244013486115


Perform analyses using the Structural Summary Method

Description

Calculate SSM parameters with confidence intervals (bootstrapped by default, or Monte Carlo via method) for a variety of different analysis types. Depending on what arguments are supplied, either mean-based or correlation-based analyses will be performed, one or more groups will be used to stratify the data, and contrasts between groups or measures will be calculated.

Usage

ssm_analyze(
  data,
  scales = NULL,
  angles = octants(),
  measures = NULL,
  grouping = NULL,
  contrast = FALSE,
  boots = 2000,
  interval = 0.95,
  listwise = TRUE,
  measures_labels = NULL,
  parallel = "no",
  ncpus = 1,
  method = "bootstrap",
  occasions = NULL
)

Arguments

data

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

scales

Required unless occasions is supplied (the two are mutually exclusive). A character vector of column names, or a numeric vector of column indexes, from data that contains the circumplex scale scores to be analyzed.

angles

Optional. A numeric vector containing the angular displacement of each circumplex scale included in scales (in degrees). (default = octants()). The closed-form SSM estimator used here equals the ordinary-least-squares cosine fit for equally spaced angles (e.g., octants at 45-degree intervals) – more generally, for any angle set satisfying first- and second-harmonic balance. For angle sets violating that balance (generic unequally spaced sets), it is the conventional Gurtman estimator, not a least-squares fit, and the reported model fit is then no longer a bounded R-squared in ⁠[0, 1]⁠ (it can fall below 0).

measures

Optional. Either NULL or a character vector of column names from data that contains one or more variables to be correlated with the circumplex scales and analyzed using correlation-based SSM analyses.

grouping

Optional. Either NULL or a string that contains the column name from data of the variable that indicates the group membership of each observation.

contrast

Optional. A logical indicating whether to output the difference between two measures', two groups', or two occasions' SSM parameters. Can only be set to TRUE when exactly one of these holds: two measures and one group; one measure and two groups; no measures and two groups; or two occasions and one group (default = FALSE). The contrast is always the second level minus the first. For two groups, this is the second level of grouping alphabetically, unless grouping is already a factor with an explicit level order, in which case that order is used. For two measures, this is simply the second entry of measures as given (no reordering). For two occasions, it is the second listed element of occasions minus the first (list order as supplied – temporal order – never alphabetical). The direction is shown in the result's Label (e.g., "Male - Female").

boots

Optional. A single positive whole number indicating how many bootstrap resamples (or, when method = "montecarlo", Monte Carlo draws) to use when estimating the confidence intervals (default = 2000).

interval

Optional. A single positive number between 0 and 1 (exclusive) that indicates what confidence level to use when estimating the confidence intervals (default = 0.95).

listwise

Optional. A logical indicating whether missing values should be handled by listwise deletion (TRUE) or pairwise deletion (FALSE). Note that pairwise deletion may result in different missing data patterns in each bootstrap resample and is slower to compute (default = TRUE). Occasions analyses require listwise = TRUE: a person missing any occasion is dropped from all occasions (complete cases across waves), so the paired contrast stays a within-person comparison. Note the selection caution: complete-cases-across-waves estimates completers' change, which can differ from population change when dropout relates to the outcome.

measures_labels

Optional. Either NULL or a character vector providing a label for each measure provided in measures (in the same order) to appear in the results as well as tables and plots derived from the results.

parallel

Optional. A string indicating whether to distribute the bootstrap computation across multiple CPU cores: "no" (default), "multicore" (process forking; available on macOS and Linux, ignored on Windows), or "snow" (a local PSOCK cluster; available on all platforms). Passed to boot. Because the bootstrap resample indices are drawn in the main R process before any work is distributed, results for a given set.seed() are identical regardless of the parallel and ncpus settings.

ncpus

Optional. A single positive whole number indicating how many CPU cores to use when parallel is not "no" (default = 1).

method

Optional. A string indicating how to estimate the confidence intervals: "bootstrap" (default) resamples the data, whereas "montecarlo" draws parameter replicates from the asymptotic sampling distribution of the group mean vector (mean-based analyses) or the measure-scale correlation vector (correlation-based analyses) – a multivariate normal with empirically estimated covariance – and propagates them through the SSM parameter transformation. The Monte Carlo method is much faster for large samples but relies on the asymptotic normality of the means or correlations, so prefer the bootstrap for small samples; it also requires listwise-complete data. Correlations are drawn jointly across measures within each group on the Fisher z scale and back-transformed. The parallel and ncpus arguments apply only to the bootstrap.

occasions

Optional. Either NULL or a named list of character or numeric vectors, each selecting the same circumplex scales measured at one occasion, in the same scale order, all of length length(angles) (e.g., occasions = list(T1 = c("PA_1", ..., "NO_1"), T2 = c("PA_2", ..., "NO_2"))). Mutually exclusive with scales (and not combinable with measures). Data must be wide – one row per person – so persons remain the resampling unit and within-person dependence across occasions is preserved in both engines. Results gain an Occasion column (labels are names(occasions), defaulting to T1..Tk); this column is present only for occasions analyses. Grouping is time-invariant by construction (one group per person-row). Cross-occasion column alignment is validated by stem matching; when the columns have no common stem structure, positional alignment is assumed and messaged.

Value

A list containing the results and description of the analysis.

results

A data frame with the SSM parameter estimates

details

A list with the number of bootstrap resamples or Monte Carlo draws (boots), the confidence interval percentage level (interval), the angular displacement of scales (angles), and the interval estimation method (method)

call

A language object containing the function call that created this object

scores

A data frame containing the mean scale scores

type

A string indicating what type of SSM analysis was done

The profile displacement parameter is reported in the half-open interval ⁠[0, 360)⁠ degrees. A profile that peaks exactly at the 0/360 degree boundary is reported as approximately 360 (equivalently 0, the same direction); which of the two appears is a floating-point detail and both denote the same pole. A displacement confidence-interval endpoint that lands exactly on that pole is always reported as 360 (never 0), matching the package's LM = 360 labeling. Contrast displacements are instead reported as a signed difference in ⁠(-180, 180]⁠ degrees (see the "Contrast" block in the printed output).

Degenerate profiles (flat or zero-amplitude) have undefined displacement (and fit, if flat), which is reported as NA with a warning. Bootstrap resamples that produce degenerate profiles (e.g., a resampled measure with zero variance) are excluded from the confidence intervals with a warning reporting how many were dropped; the intervals are then conditional on estimability.

[0, 360)⁠degrees. A profile that peaks exactly at the 0/360 degree boundary is reported as approximately 360 (equivalently 0, the same direction); which of the two appears is a floating-point detail and both denote the same pole. A displacement *confidence-interval endpoint* that lands exactly on that pole is always reported as 360 (never 0), matching the package's LM = 360 labeling. Contrast displacements are instead reported as a signed difference in⁠(-180, 180]: R:0,%20360)%60%20degrees.%20A%20profile%20that%20peaks%20exactly%20at%20the%200/360%20degree%0A%20%20boundary%20is%20reported%20as%20approximately%20360%20(equivalently%200,%20the%20same%0A%20%20direction);%20which%20of%20the%20two%20appears%20is%20a%20floating-point%20detail%20and%20both%0A%20%20denote%20the%20same%20pole.%20A%20displacement%20confidence-interval%20endpoint%20that%0A%20%20lands%20exactly%20on%20that%20pole%20is%20always%20reported%20as%20360%20(never%200),%20matching%0A%20%20the%20package's%20LM%20=%20360%20labeling.%20Contrast%20displacements%20are%20instead%0A%20%20reported%20as%20a%20signed%20difference%20in%20%60(-180,%20180

Reproducibility

This function consumes R's random number stream (so do cpm_fit(ci_method = "bootstrap"), cpm_simulate(), and ssm_ci_accuracy(); ssm_score()/ssm_parameters() and the tidying functions are deterministic). Call set.seed() immediately before ssm_analyze() for reproducible confidence intervals:

  • Bootstrap (method = "bootstrap", the default): the same seed gives byte-identical results, regardless of the parallel/ncpus settings (see their descriptions below), because boot::boot() draws all resample indices from the seed before any work is parallelized.

  • Monte Carlo (method = "montecarlo"): the same seed gives byte-identical results. Adding a group or measure, or reordering scales/measures, changes the random draw sequence, so results are reproducible for a fixed call but will not match after such structural edits even with the same seed.

  • The two methods are not expected to agree numerically for the same seed – they consume the random stream in unrelated ways. Their statistical agreement (validated on real data; see vignette("introduction-to-ssm-analysis")) is a separate property from RNG reproducibility.

  • Increasing boots changes the CI by design (more resamples/draws should tighten Monte Carlo error), so results are not expected to be stable across different boots values, only within a fixed call.

Occasions (repeated measures)

Supplying occasions analyzes the same circumplex scales measured at k >= 2 occasions on the same persons (wide data, one row per person). Each occasion yields its own profile row; with contrast = TRUE (exactly 2 occasions, single group) the paired within-person contrast is estimated with both engines preserving the within-person dependence (the bootstrap resamples persons; the Monte Carlo engine draws the stacked occasion mean vectors jointly).

Interpretation notes. A paired displacement-contrast CI is interpretable only when both occasions' amplitudes are reliably nonzero (both profiles print without the amplitude note); if only one occasion's profile is interpretable, do not read the contrast as directional change. Paired designs are not unconditionally more efficient than independent groups: the paired elevation contrast has a narrower CI exactly when the within-person elevation correlation is positive, while for the amplitude and displacement contrasts the paired CI is narrower only when the gradient-projected cross-occasion covariance is positive – under isotropic dependence this is proportional to cos(displacement change), so paired CIs are narrower for displacement changes under 90 degrees and can be wider than independent-groups CIs for changes beyond 90 degrees, even with strongly positive within-person correlation.

With method = "montecarlo" the per-group draw has dimension k x p (occasions times scales); group sizes should comfortably exceed k x p for the asymptotic covariance to be well estimated (the percentile bootstrap is the safer small-sample choice). Grouping is time-invariant by construction (one group per person-row).

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

# Load example data
data("jz2017")

# Single-group mean-based SSM
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
)

# Single-group correlation-based SSM
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  measures = c("NARPD", "ASPD")
)

# Monte Carlo confidence intervals (faster for large samples)
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  method = "montecarlo"
)

# Multiple-group mean-based SSM
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  grouping = "Gender"
)

# Multiple-group mean-based SSM with contrast
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  grouping = "Gender",
  contrast = TRUE
)

# Single-group correlation-based SSM with contrast
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  measures = c("NARPD", "ASPD"),
  contrast = TRUE
)

# Multiple-group correlation-based SSM
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  measures = "NARPD",
  grouping = "Gender"
)

# Multiple-group correlation-based SSM with contrast
ssm_analyze(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  measures = "NARPD",
  grouping = "Gender",
  contrast = TRUE
)

Perform SSM analyses on long-format repeated-measures data

Description

A convenience wrapper around the occasions interface of ssm_analyze() for data stored in long format (one row per person per occasion). It reshapes the data into the wide, one-row-per-person layout that ssm_analyze() consumes and then delegates to it; all estimation is performed by ssm_analyze() unchanged. See the occasions argument of ssm_analyze() for the analysis semantics – per-occasion profiles, paired within-person contrasts, and the listwise-only handling of missing waves (a person missing any occasion is dropped from all occasions).

Usage

ssm_analyze_long(
  data,
  scales,
  angles = octants(),
  id,
  occasion,
  grouping = NULL,
  contrast = FALSE,
  boots = 2000,
  interval = 0.95,
  parallel = "no",
  ncpus = 1,
  method = "bootstrap"
)

Arguments

data

Required. A data frame (or matrix) in long format containing an identifier column, an occasion column, and the circumplex scale scores (one set of score columns, repeated across occasions in different rows).

scales

Required. A character vector of column names, or a numeric vector of column indexes, giving the circumplex scale scores in data (the same scales measured at every occasion).

angles

Optional. A numeric vector containing the angular displacement of each circumplex scale included in scales (in degrees) (default = octants()).

id

Required. A single column name or index identifying the person that each row belongs to.

occasion

Required. A single column name or index identifying the occasion (wave) that each row belongs to. Occasion order – which governs the second-minus-first direction of a paired contrast – is taken from the factor levels of this column when it is a factor, and otherwise from the order in which the occasions first appear in data. It is never sorted alphabetically, so a T10/T2 pair keeps its supplied order.

grouping

Optional. A single column name or index giving a time-invariant grouping variable (one value per person; an error is raised if a person's grouping value varies across occasions).

contrast

Optional. A logical value; if TRUE (and the data contain exactly two occasions in a single group), the paired within-person contrast (second occasion minus first) is calculated (default = FALSE).

boots, interval, parallel, ncpus, method

Optional. Passed through to ssm_analyze(); see its documentation.

Value

A list containing the results and description of the analysis, as returned by ssm_analyze() (with an Occasion column). See ssm_analyze().

See Also

ssm_analyze() for the wide-format interface and the analysis semantics this wrapper delegates to.

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

# Build a small two-occasion dataset in long format (one row per person per
# occasion). In practice `data` already stores the repeated occasions this
# way; here we stack two copies of jz2017 as an illustration.
data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
t1 <- jz2017[, scales]
t1$id <- seq_len(nrow(t1))
t1$occasion <- "T1"
t2 <- t1
t2$occasion <- "T2"
long <- rbind(t1, t2)


# Per-occasion SSM profiles from long-format data
ssm_analyze_long(long, scales = scales, id = "id", occasion = "occasion")

Assess the accuracy of SSM confidence intervals by simulation

Description

Estimate, by simulation, whether the confidence intervals of a fitted ssm_analyze() object would cover the true SSM parameters at their nominal rate if the population looked like the fitted estimates, at the observed sample size(s). Following Zimmermann & Wright (2017), the population's scale intercorrelation structure is characterized by fitting Browne's (1992) circular process model (cpm_fit()) to the pooled within-group scale correlations; each of reps datasets is then simulated from that plug-in population at the object's exact group sizes and the object's own interval procedure (same engine, same boots, same interval) is rerun on it. Coverage is reported per profile row, parameter, and amplitude condition, with 95% Wilson score intervals classified against Bradley's (1978) liberal robustness band at the as-estimated condition.

Usage

ssm_ci_accuracy(
  ssm_object,
  reps = 1000,
  amplitude_factors = c(1, 0.5, 0.25, 0),
  structure = c("cpm", "observed"),
  m = NULL,
  cpm = NULL,
  data = NULL,
  parallel = "no",
  ncpus = 1
)

Arguments

ssm_object

Required. A circumplex_ssm object from ssm_analyze().

reps

Optional. The number of simulated datasets per amplitude condition (default = 1000, binomial SE about 0.7 percentage points; 500 is a reasonable quick-look floor).

amplitude_factors

Optional. Numeric vector of amplitude scaling factors in ⁠[0, 1]⁠ defining the ladder conditions (default = c(1, 0.5, 0.25, 0)). Must include 1, the as-estimated condition that the verdict is keyed to. Applied to every profile row jointly.

structure

Optional. "cpm" (default) simulates from the Browne model's model-implied scale correlations; "observed" bypasses the model and uses the pooled within-group correlation matrix directly (a sensitivity switch: if the two verdicts differ, structure uncertainty is itself material). Not accepted for occasions analyses, whose population is always the observed stacked cross-occasion covariance (no model is fit).

m

Optional. The number of harmonics passed to cpm_fit() (default NULL uses min(3, floor((p - 1) / 2))).

cpm

Optional. A pre-fitted circumplex_cpm object to reuse for the population structure instead of refitting (its scales must match the ssm object's). Must be a unit-scaling fit (the default cpm_fit() scaling); a free-scaling fit models a covariance structure and is not a valid population correlation structure for this diagnostic. Ignored when structure = "observed"; not accepted for occasions analyses.

data

Optional. The original data set, required only for ssm objects created before sufficient statistics were stored at analysis time; the statistics are then recomputed and checked against the stored profile vectors.

parallel

Optional. "no" (default), "multicore", or "snow"; distributes the simulation replicates across ncpus cores. Results are identical for a given seed regardless of these settings (see Reproducibility).

ncpus

Optional. Number of cores when parallel is not "no" (default = 1).

Details

Displacement coverage is angular: the truth is inside the reported interval as an arc (membership modulo 360 degrees), so populations peaking at the 0/360 boundary and contrast intervals reported beyond +/-180 degrees are handled without special-casing. Because displacement is only interpreted when the printed amplitude guardrail certifies it, displacement coverage is also reported conditional on certification under the shipped decision rule a_lci / (a_uci - a_lci) >= 0.35 (the rule the printed ssm_analyze() output applies): the amplitude CI's lower bound must sit at least 0.35 CI widths above zero. The rule is scale-free (invariant to the score metric) and print-independent, so no scale-dependent threshold is reported; the 0.35 constant is calibrated for the default 95% confidence interval. A contrast row is a signed difference, not a prototypicality measure, so print.circumplex_ssm() never certification-gates it; its displacement verdict and printed coverage are therefore reported unconditionally (matching that profiles-only stance). Its certification-conditional coverage – where "certified" means both profile rows were certified – is still computed and retained in the returned object as a descriptive that no display consumes.

The amplitude_factors ladder manufactures populations whose closed-form amplitude is scaled toward zero (the regime where percentile amplitude intervals are theoretically weakest) while keeping the residual profile content fixed. The ladder is defined through the estimator functional (a 3x3 solve on the images of 1, cos, and sin), so the condition-c truths are exact for any angle spacing: elevation is unchanged and the amplitude is exactly c times the estimate. Truths are nevertheless recomputed from each condition's population profile. At c = 0 amplitude coverage is structurally zero (a percentile interval of strictly positive amplitude replicates cannot contain 0; such rows are flagged in the Structural column) and displacement truth is undefined (reported NA); the guardrail certification rate carries the inferential weight there, and the informative rungs for amplitude coverage are the small c > 0 ones.

When a profile row's amplitude estimate is itself below half its observed CI width, the relative ladder degenerates: the analysis already sits in the near-zero regime. One absolute rung is then added at the certification margin (c chosen so c times the amplitude estimate equals the observed amplitude-CI half-width, the largest such c across affected rows) and summary() notes the regime. On the correlation path this rung is dropped with a warning if it would push a population correlation to +/-1.

Value

A circumplex_ci_accuracy object: a list with coverage (per Profile x Parameter x Condition: coverage, its Monte Carlo SE, the one-sided miss rates, median CI width, and for displacement the certification-conditional coverage with the number of certified replicates behind it – for a contrast row this conditional column is retained as a joint-certification descriptive that no display consumes; Structural flags the amplitude rows whose zero coverage is a theorem rather than a measurement), guardrail (per Profile x Condition: certification rate with its 95% Wilson score interval, the user-expectation benchmark (1 - interval) / 2, the stored false-certification caution decision at the c = 0 rung (Caution, true when the Wilson lower bound exceeds the benchmark; NA off that rung, and NA for a contrast row, which print.circumplex_ssm() never gates), fit-pass rate, and the branch-pathology rate – the rate at which a displacement point estimate falls geometrically outside its own interval), verdict (Wilson-vs-Bradley classification of elevation, amplitude, and displacement coverage at the as-estimated condition – a profile's displacement is classified certification-conditionally (Parameter "d_conditional"), a contrast's unconditionally (Parameter "d") – plus an overall worst-of row per profile; note the printed verdict headline additionally elevates to CAUTION whenever the guardrail Caution fired, so it can read worse than the overall coverage class), cpm (the embedded cpm_fit() object, or NULL when structure = "observed"), population (per profile row: the population profile vectors, truth parameters, and any positive-semidefiniteness repair magnitude, by condition), and details. The plot() method draws coverage against the amplitude ladder with the Bradley band shaded; summary() adds a plain-language verdict (see summary.circumplex_ci_accuracy()).

Reproducibility

This function is stochastic: call set.seed() immediately before it. It draws one sample.int() value from the caller's random number stream to seed an internal L'Ecuyer-CMRG stream, gives every simulated dataset its own deterministic substream, and then restores the caller's .Random.seed and generator kind on exit, so results for a given seed are identical regardless of parallel/ncpus and the caller's stream is advanced by exactly that one draw.

Limitations

Coverage is evaluated at the fitted structure, not the unknown truth ("would the procedure work in a population like your estimates", not "did your interval cover"). Simulated populations are multivariate normal with the fitted correlation structure; heavy tails or skew in the real data can degrade coverage further than reported. The diagnostic assesses the complete-data procedure (missing data are not simulated), and groups are assumed to share one circumplex structure. When the Browne model fits poorly, the simulated population may misrepresent the data; the embedded fit and its diagnostics are returned for inspection.

For an occasions (repeated-measures) analysis the population is instead a multivariate normal with the observed stacked cross-occasion covariance (no circular-model idealization): the within-person dependence across occasions is carried directly, and no structure/cpm alternative is offered. When the stacked covariance is rank-deficient (per-group sample size at or below the number of occasions times scales) the simulated population is a proper degenerate normal, so the reported coverage and width remain valid but the fit-statistic pass rate is descriptive only. For a paired contrast, the joint-certification rate (both occasions certified) is reported as a descriptive caveat on the contrast's interpretability. Assessing the occasions object per occasion via ⁠scales =⁠ one occasion's columns instead uses the default "cpm" structure and can give slightly different per-occasion verdicts – a structure-sensitivity fact, not a bug.

References

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.

Browne, M. W. (1992). Circumplex models for correlation matrices. Psychometrika, 57(4), 469-497.

Bradley, J. V. (1978). Robustness? British Journal of Mathematical and Statistical Psychology, 31(2), 144-152.

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

data("jz2017")
set.seed(12345)
res <- ssm_analyze(
  jz2017[1:200, ],
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  boots = 100
)
# Small reps/boots keep the example fast; use the defaults in practice
set.seed(23456)
acc <- ssm_ci_accuracy(res, reps = 25, amplitude_factors = c(1, 0.25))
acc
summary(acc)

Summarize posterior draws as SSM parameters

Description

Transform posterior draws from a user-fitted Bayesian model (e.g., a brms cosine regression) into Structural Summary Method parameter draws and summarize them with the package's circular-statistics machinery. Two draw shapes are accepted, distinguished explicitly (never guessed):

Usage

ssm_draws(draws, angles = NULL, interval = 0.95, type = NULL)

Arguments

draws

Required. A numeric matrix or data frame of posterior draws: one row per draw, columns per the shape rules above.

angles

Optional. A numeric vector of angular displacements (in degrees) for profile draws, one per column of draws; NULL (default) for parameter draws.

interval

Optional. A single number between 0 and 1 giving the credible level for the equal-tailed intervals (default = 0.95).

type

Optional. "parameters" or "profiles", required only where the shape is ambiguous (angles = NULL with exactly 3 columns); when given elsewhere it must not contradict angles.

Details

  • Parameter draws (angles = NULL, type = "parameters"): a numeric matrix or data frame with exactly three columns interpreted in column order as (e, x, y) – elevation (intercept), the cosine coefficient (x), and the sine coefficient (y). Each row is mapped to amplitude a = sqrt(x^2 + y^2) and displacement d = atan2(y, x) wrapped to [0, 360] (the 0/360 pole is reported as 360, the package's LM = 360 convention). Column names are not used to reorder: when names are present but do not look (intercept, cos, sin)-like, a message states the assumed mapping. A row with exactly zero amplitude has undefined displacement (NA); model fit is undefined for parameter draws (fit = NA) because no profile is available to measure it against.

  • Profile draws (angles supplied): a numeric matrix with one column per circumplex scale (ncol(draws) == length(angles)); each row goes through the closed-form SSM transform exactly as a bootstrap replicate would, inheriting the standing degenerate-profile NA semantics.

With angles = NULL and a column count other than 3 the input matches neither shape and an error explains both. With angles = NULL and exactly 3 columns the shape is ambiguous (a p = 3 instrument's profile draws look like parameter draws), so type = "parameters" is required.

Point estimates are posterior medians for e, x, y, a, and fit (amplitude is right-skewed, so a mean would be biased upward), and the circular mean for displacement. Marginal summaries are not jointly coherent: the reported a is not sqrt(x^2 + y^2) of the reported (x, y), and the reported d is not their direction – each is the honest marginal summary of its own posterior. Intervals are equal-tailed credible intervals (percentile quantiles of the draws), with displacement handled by the package's circular quantile machinery (centered on the circular mean, so intervals straddling 0/360 wrap correctly). Draws with undefined displacement are excluded from the displacement summaries only, which are therefore conditional on estimability (measure-zero for continuous parameter-draw posteriors; can bind for profile draws). A diffuse posterior with zero circular resultant has an undefined circular mean, reported as NA rather than invented.

Note that independent priors on (x, y) induce a non-uniform prior on (a, d) – roughly Rayleigh-shaped on amplitude, with mass pushed away from a = 0 – so the prior on the SSM scale should be inspected (e.g., by prior-predictive simulation) rather than assumed flat; see the package's Bayesian SSM vignette.

Value

An object of class "circumplex_ssm_draws" holding draws (the SSM parameter draws, one row per posterior draw, columns e, x, y, a, d, fit, displacement in degrees [0, 360], pole reported as 360), results (the point summaries and credible bounds), and details, whose certified field records the package's displacement-interpretability certification applied to the amplitude credible interval (a_lci / (a_uci - a_lci) >= 0.35): when it fails, the displacement interval is not interpretable and printing adds a note saying so. Printing shows the summary table; summary() adds the analysis details.

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

# Parameter draws (e.g., brms fixed-effect draws b_Intercept, b_cos, b_sin)
set.seed(1)
draws <- cbind(rnorm(500, 0.4, 0.1), rnorm(500, 0.9, 0.1),
               rnorm(500, -0.3, 0.1))
ssm_draws(draws, type = "parameters")

Calculate Structural Summary Method parameters for a set of scores

Description

Calculate SSM parameters (without confidence intervals) for a set of scores and generate a data frame with customizable labels for each parameter value. This function requires the input to be a numeric vector (or coercable to one) and returns only the parameters. See ssm_score() for a similar function that calculates SSM parameters for each row of a data frame.

Usage

ssm_parameters(
  scores,
  angles = octants(),
  prefix = "",
  suffix = "",
  e_label = "Elev",
  x_label = "Xval",
  y_label = "Yval",
  a_label = "Ampl",
  d_label = "Disp",
  f_label = "Fit"
)

Arguments

scores

Required. A numeric vector (or single row data frame) containing one score for each of a set of circumplex scales.

angles

Required. A numeric vector containing the angular displacement of each circumplex scale included in scores (in degrees). The closed-form SSM estimator used here equals the ordinary-least-squares cosine fit for equally spaced angles (e.g., octants at 45-degree intervals) – more generally, for any angle set satisfying first- and second-harmonic balance. For angle sets violating that balance (generic unequally spaced sets), it is the conventional Gurtman estimator, not a least-squares fit, and the reported fit is then no longer a bounded R-squared in ⁠[0, 1]⁠ (it can fall below 0).

prefix

Optional. A string to append to the beginning of all of the SSM parameters' variable names (default = "").

suffix

Optional. A string to append to the end of all of the SSM parameters' variable names (default = "").

e_label

Optional. A string representing the variable name of the SSM elevation parameter (default = "Elev").

x_label

Optional. A string representing the variable name of the SSM x-value parameter (default = "Xval").

y_label

Optional. A string representing the variable name of the SSM y-value parameter (default = "Yval").

a_label

Optional. A string representing the variable name of the SSM amplitude parameter (default = "Ampl").

d_label

Optional. A string representing the variable name of the SSM displacement parameter (default = "Disp").

f_label

Optional. A string representing the variable name of the SSM fit or R-squared value (default = "Fit"). This value is a bounded R-squared in ⁠[0, 1]⁠ when the closed form coincides with the least-squares fit (equally spaced or otherwise harmonic-balanced angles; see angles).

Value

A data frame containing the SSM parameters calculated from scores. For degenerate profiles the undefined parameters are returned as NA with a warning: a flat profile (zero variance) has undefined displacement and fit, and a profile with real variance but zero amplitude (i.e., no first-harmonic component) has undefined displacement and a fit of 0. Note that this applies only to amplitudes that are zero up to machine precision; small real amplitudes are always estimated, and their uncertainty is expressed through confidence intervals (see ssm_analyze()).

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

# Manually enter octant scores
scores <- c(0.55, 0.58, 0.62, 0.76, 1.21, 1.21, 1.48, 0.90)
ssm_parameters(scores)

# Customize several of the labels
ssm_parameters(scores, x_label = "LOV", y_label = "DOM")

# Add a prefix to all labels
ssm_parameters(scores, prefix = "IIP_")

Calculate SSM parameters for each person

Description

Score each person's own circumplex profile through the closed-form SSM transform and return a per-person parameter table. When id is NULL, every row of data is treated as one person's profile (like ssm_score(), but returning a fresh table rather than appending columns). When id names a column, rows sharing an id (e.g., occasions of intensive longitudinal data) are first averaged within person – each scale's mean uses that person's available (non-missing) rows – and the within-person mean profile is scored.

Usage

ssm_parameters_id(data, scales, angles = octants(), id = NULL)

Arguments

data

Required. A data frame or matrix containing at least circumplex scales, with one row per person or (with id) per person-occasion.

scales

Required. The variable names or column numbers for the variables in data that contain circumplex scales to be analyzed.

angles

Optional. A numeric vector containing the angular displacement of each circumplex scale included in scales, in degrees (default = octants()). The closed-form SSM estimator used here equals the ordinary-least-squares cosine fit for equally spaced angles – more generally, for any angle set satisfying first- and second-harmonic balance; see ssm_parameters().

id

Optional. A single variable name or column number identifying persons. If NULL (default), each row is scored as its own person; otherwise rows sharing an id are averaged within person before scoring. Missing id values are an error (a person cannot be silently dropped).

Details

Degenerate profiles keep their row and are reported as NA, never silently dropped: a flat (zero-variance) profile has undefined displacement and fit, a profile with real variance but zero first-harmonic amplitude has undefined displacement and a fit of 0, and a person with a completely missing scale has an undefined profile (all parameters NA). The na_rate column exposes each person's share of missing scale cells so missingness is visible alongside its consequences.

Value

A data frame of class "circumplex_ssm_id" with one row per person, in order of first appearance: the id column (named after id, or id when NULL), n_obs (rows contributing to that person), na_rate (proportion of missing scale cells among those rows), and the SSM parameters Elev, Xval, Yval, Ampl, Disp (degrees in [0, 360], with the 0/360 pole reported as 360 per the package's LM = 360 convention), and Fit. Use summary.circumplex_ssm_id() for group-level summaries with circular statistics for displacement.

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_score(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

data("aw2009")
ssm_parameters_id(
  aw2009,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
)

Create a Circular Plot of SSM Results

Description

Take in the results of a Structural Summary Method analysis and plot the point and interval estimate for each row (e.g., group or measure) in a circular space quantified by displacement and amplitude.

Usage

ssm_plot_circle(
  ssm_object,
  amax = NULL,
  legend_font_size = 12,
  scale_font_size = 12,
  drop_lowfit = FALSE,
  repel = FALSE,
  angle_labels = NULL,
  palette = "Set2",
  vary_shapes = FALSE,
  path = FALSE,
  ...
)

Arguments

ssm_object

Required. The output of ssm_analyze().

amax

A positive real number corresponding to the radius of the circle. It is used to scale the amplitude values and will determine which amplitude labels are drawn.

legend_font_size

A positive real number corresponding to the size (in pt) of the text labels in the legend (default = 12).

scale_font_size

A positive real number corresponding to the size (in pt) of the text labels for the amplitude and displacement scales (default = 12).

drop_lowfit

A logical determining whether profiles with low model fit (<.70) should be omitted or plotted with dashed borders (default = FALSE).

repel

A logical determining whether each profile is labelled with a repelled text label (placed on the circumplex canvas by coord_circumplex(), so labels avoid overlapping each other and the points) instead of distinguished by colour and a legend (default = FALSE). Requires the ggrepel package.

angle_labels

A character vector specifying text labels to plot around the circle for each scale. Can also specify NULL to default to numerical angle labels or a vector of empty strings ("") to hide the labels. If not NULL, must have the same length and ordering as the angles argument to ssm_analyze(). (default = NULL)

palette

A string corresponding to the palette to be used from ColorBrewer for the color and fill aesthetics. If set to NULL, all points will appear blue and no legend will be there (useful for showing the coverage of a high number of variables).

vary_shapes

A logical determining whether profiles should each get their own shape or vary only by fill color. This only works when the number of profiles is five or less. (default = FALSE)

path

A logical determining whether each series' movement across occasions is drawn as an arrowed path on the circle (default = FALSE). Requires an SSM object with occasions, from ssm_analyze() with the occasions argument or from ssm_analyze_long(); supplying TRUE for any other object is an error. Occasions are connected in the order they were supplied, never alphabetically, and the path is drawn the short way across the 0/360 boundary. An occasion whose displacement is undefined (a flat or zero-amplitude profile) breaks the path rather than being interpolated through. See geom_ssm_path() for the underlying layer.

...

Not used. Supplying an unrecognized argument produces a warning.

Value

A ggplot variable containing a completed circular plot.

See Also

Other visualization functions: plot.circumplex_ci_accuracy(), ssm_plot_contrast(), ssm_plot_curve(), ssm_plot_trajectory()

Examples

data("jz2017")
res <- ssm_analyze(
  jz2017,
  scales = 2:9,
  measures = c("NARPD", "ASPD")
)
ssm_plot_circle(res)

Create a Difference Plot of SSM Contrast Results

Description

Take in the results of a Structural Summary Method analysis with pairwise contrasts and plot the point and interval estimates for each parameter's contrast (e.g., between groups or measures).

Usage

ssm_plot_contrast(
  ssm_object,
  drop_xy = FALSE,
  sig_color = "#fc8d62",
  ns_color = "white",
  linesize = 1.25,
  fontsize = 12,
  ...
)

Arguments

ssm_object

Required. The results output of ssm_analyze().

drop_xy

A logical determining whether the X-Value and Y-Value parameters should be removed from the plot (default = FALSE).

sig_color

Optional. A string corresponding to the color to use to denote significant contrasts (default = "#fc8d62").

ns_color

Optional. A string corresponding to the color to use to denote non-significant contrasts (default = "white").

linesize

Optional. A positive number corresponding to the size of the point range elements in mm (default = 1.5).

fontsize

Optional. A positive number corresponding to the size of the axis labels, numbers, and facet headings in pt (default = 12).

...

Not used. Supplying an unrecognized argument produces a warning.

Value

A ggplot variable containing difference point-ranges faceted by SSM parameter. An interval that does not contain the value of zero has p<.05.

See Also

Other visualization functions: plot.circumplex_ci_accuracy(), ssm_plot_circle(), ssm_plot_curve(), ssm_plot_trajectory()

Examples

data("jz2017")
res <- ssm_analyze(
  jz2017,
  scales = 2:9,
  measures = c("NARPD", "ASPD"),
  contrast = TRUE
)
ssm_plot_contrast(res)

Create a Curve Plot of SSM Results

Description

Take in the results of a Structural Summary Method analysis and plot the scores by angle and the estimated SSM curve.

Usage

ssm_plot_curve(
  ssm_object,
  angle_labels = NULL,
  base_size = 11,
  drop_lowfit = FALSE,
  ...
)

Arguments

ssm_object

Required. The results output of ssm_analyze().

angle_labels

Optional. Either NULL or a character vector that determines the x-axis labels. If NULL, the labels will be the angle numbers. If a character vector, must be the same length and in the same order as the angles argument to ssm_analyze() (default = NULL).

base_size

Optional. A positive number corresponding to the base font size in pts (default = 11).

drop_lowfit

Optional. A logical indicating whether to omit profiles with low fit (<.70) or include them with dashed lines (default = FALSE).

...

Not used. Supplying an unrecognized argument produces a warning.

Value

A ggplot object depicting the SSM curve(s) of each profile.

See Also

Other visualization functions: plot.circumplex_ci_accuracy(), ssm_plot_circle(), ssm_plot_contrast(), ssm_plot_trajectory()

Examples

data("jz2017")
res <- ssm_analyze(
  jz2017,
  scales = 2:9,
  measures = 10:13
)
ssm_plot_curve(res)
ssm_plot_curve(res, angle_labels = PANO())

Create a Trajectory Plot of SSM Results Over Time

Description

Plot each Structural Summary Method parameter against time, one facet per parameter, with its confidence interval as a band. This is a Cartesian diagnostic plot, not a circumplex figure: the horizontal axis is time, not angle.

Usage

ssm_plot_trajectory(x, ...)

## Default S3 method:
ssm_plot_trajectory(x, ...)

## S3 method for class 'circumplex_ssm'
ssm_plot_trajectory(x, drop_xy = FALSE, base_size = 11, na.rm = TRUE, ...)

## S3 method for class 'data.frame'
ssm_plot_trajectory(
  x,
  time,
  drop_xy = FALSE,
  base_size = 11,
  na.rm = TRUE,
  ...
)

Arguments

x

An SSM results object produced by ssm_analyze() with the occasions argument or by ssm_analyze_long(), or a trajectory table (a data frame) as described above.

...

Not used. Supplying an unrecognized argument produces a warning.

drop_xy

A logical determining whether the X-value and Y-value panels should be omitted (default = FALSE), leaving elevation, amplitude, and displacement.

base_size

A positive number determining the base font size of the plot (default = 11).

na.rm

A logical determining whether time points that cannot be plotted (no defined displacement) are dropped silently (default = TRUE) or with a warning naming how many were removed (FALSE).

time

A string naming the numeric time column of a trajectory table. Required for the data frame method; unused for SSM objects.

Details

Two kinds of input are accepted, and they differ only in their time axis:

  • An SSM results object with occasions, from ssm_analyze() with the occasions argument or from ssm_analyze_long(). Occasions are discrete and ordered, so the axis is discrete.

  • A trajectory table: a data frame with one row per time point, a numeric time column named by time, and the columns a_est, a_lci, a_uci, d_est, d_lci, and d_uci (optionally the ⁠e_*⁠, ⁠x_*⁠, and ⁠y_*⁠ triples, and a logical certified column). This is the shape a model-based workflow assembles by evaluating a fitted growth model at each time point and passing the draws through ssm_draws(); see vignette("growth-ssm-analysis"). The axis is continuous, so unequally spaced time points are drawn at their actual spacing.

Both paths share one implementation of the displacement unwrap and the certification marking described below.

The displacement panel is drawn on an unwrapped branch, so a profile whose displacement crosses the 0/360 boundary renders as one continuous path rather than jumping a full turn. Values on that panel may therefore fall outside [0, 360); each confidence bound is placed at its signed angular distance from its own estimate. Unwrapping assumes the profile rotates less than a half-turn between consecutive time points at which its displacement is defined – no data can verify this, so time points that are far apart, or a series with a gap, should be read with that in mind.

Occasions appear in the order they were supplied to ssm_analyze() (or in the occasion factor's level order for ssm_analyze_long()), never in alphabetical order.

On the displacement panel, a time point whose amplitude confidence interval is too close to zero for its displacement to be interpretable is drawn as a hollow point; see ssm_analyze() for the certification rule. For an SSM object the verdict is computed from the amplitude interval; for a trajectory table it is read from the optional certified column, and when that column is absent no interpretability claim is made or shown. A profile with no defined displacement at all (a flat profile) leaves a gap in that panel.

A contrast row is never plotted as a time point – it is a difference, not a time point. Use ssm_plot_contrast() for it.

Value

A ggplot object depicting each SSM parameter's trajectory over time, with confidence bands.

See Also

geom_ssm_path() and ssm_plot_circle(path = TRUE), which draw the same change across occasions as movement on the circumplex canvas rather than as parameter-by-time panels.

Other visualization functions: plot.circumplex_ci_accuracy(), ssm_plot_circle(), ssm_plot_contrast(), ssm_plot_curve()

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
t1 <- jz2017[, scales]
t1$id <- seq_len(nrow(t1))
t1$occasion <- "T1"
t2 <- t1
t2$occasion <- "T2"
res <- ssm_analyze_long(rbind(t1, t2),
  scales = scales, id = "id", occasion = "occasion"
)
ssm_plot_trajectory(res)
ssm_plot_trajectory(res, drop_xy = TRUE)


# A model-based trajectory table, plotted on a continuous time axis
trajectory <- data.frame(
  wave = 0:4,
  a_est = c(0.60, 0.55, 0.52, 0.58, 0.63),
  a_lci = c(0.48, 0.43, 0.40, 0.46, 0.51),
  a_uci = c(0.72, 0.67, 0.64, 0.70, 0.75),
  d_est = c(350, 355, 2, 8, 12),
  d_lci = c(340, 345, 352, 358, 2),
  d_uci = c(0, 5, 12, 18, 22),
  certified = c(TRUE, TRUE, FALSE, TRUE, TRUE)
)
ssm_plot_trajectory(trajectory, time = "wave")

Calculate SSM parameters by row and add results as new columns

Description

Calculate the SSM parameters for each row of a data frame and add the results as additional columns. This can be useful when the SSM is being used for the description or visualization of individual data points rather than for statistical inference on groups of data points.

Usage

ssm_score(data, scales, angles = octants(), append = TRUE, ...)

Arguments

data

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

scales

Required. The variable names or column numbers for the variables in .data that contain circumplex scales to be analyzed.

angles

Required. A numeric vector containing the angular displacement of each circumplex scale included in scales (in degrees). The closed-form SSM estimator used here equals the ordinary-least-squares cosine fit for equally spaced angles (e.g., octants at 45-degree intervals) – more generally, for any angle set satisfying first- and second-harmonic balance. For angle sets violating that balance (generic unequally spaced sets), it is the conventional Gurtman estimator, not a least-squares fit, and the reported fit is then no longer a bounded R-squared in [0, 1] (it can fall below 0).

append

Optional. A logical indicating whether to append the output to data or simply return the output (default = "TRUE").

...

Optional. Additional named arguments passed to ssm_parameters(), such as prefix and suffix; each must be a single string. Unnamed or non-scalar arguments raise an error.

Value

A data frame containing .data plus six additional columns containing the SSM parameters (calculated rowwise).

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_sem(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_sem(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

data("aw2009")
ssm_score(
  aw2009,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
)

Perform SEM-based (latent-variable) SSM analyses

Description

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).

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.

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().

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.

See Also

ssm_analyze() for the observed-score SSM, ssm_sem_syntax() for the generated measurement model, and ssm_sem_parameters() to reuse a lavaan fit you have modified or fitted yourself.

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem_parameters(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem_parameters(), summary.circumplex_ssm_id()

Examples

data("jz2017")
set.seed(12345)
res <- ssm_sem(
  jz2017,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO"),
  measures = "NARPD",
  boots = 500
)
res
summary(res)

Calculate latent SSM parameters from a fitted lavaan measurement model

Description

The low-level adapter behind ssm_sem(): take an already fitted lavaan model of a fixed-angle circumplex measurement structure (as generated by ssm_sem_syntax(), possibly user-modified – e.g., a partial-invariance respecification) and compute latent SSM parameter estimates with in-package confidence intervals. Compatibility with the expected parameter structure is checked structurally (the named loading, factor-covariance, and measure-covariance parameters must be present), not by provenance.

Usage

ssm_sem_parameters(
  fit,
  scales,
  angles = octants(),
  measures = NULL,
  ci_method = c("mvn", "boot"),
  boots = 2000,
  interval = 0.95,
  contrast = FALSE,
  parallel = "no",
  ncpus = 1
)

Arguments

fit

Required. A fitted lavaan object whose model preserves the ssm_sem_syntax() parameter structure (factors g, cx, cy; the measures covarying with them). For ci_method = "mvn", fit the model with robust (sandwich) standard errors (lavaan's se = "robust.huber.white", ssm_sem()'s default) so the propagated covariance stays valid when the fixed-angle model is an approximation; see the se argument of ssm_sem().

scales

Required. A character vector with the scale (indicator) names, in the same order as angles.

angles

Optional. A numeric vector of the scales' theoretical angles in degrees (default = octants()). Must be the angles the model was generated with.

measures

Optional for multi-group fits, required otherwise. A character vector of the measure names; NULL on a multi-group fit selects the latent MEAN path (the fit must carry the mean structure: scale intercepts and latent means).

ci_method, boots, interval, contrast, parallel, ncpus

See ssm_sem(). Note that for a multi-group fit the CONTRAST DIRECTION (and the group labels in the output) follows the fit's own group order – lavaan's default is order of appearance in the data unless group.label was supplied at fitting time – so read the direction from the output's Group column, not from factor-level conventions.

Details

Important: multi-group fits are supported here as the partial-invariance escape hatch, and this path bypasses the invariance gating that ssm_sem() applies. Where ssm_sem() fits a configural-metric-scalar ladder and refuses a latent group contrast when the required rung is rejected, ssm_sem_parameters() computes the contrast from whatever multi-group fit you supply without testing invariance at all. You own the comparability claim: the groups are compared on this instrument's latent metric only to the extent the model you fitted makes them comparable.

Value

A circumplex_ssm_sem object; see ssm_sem().

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.

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_table(), summary.circumplex_ssm_id()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), summary.circumplex_ssm_id()

Examples

data("jz2017")
scales <- c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
syn <- ssm_sem_syntax(scales = scales, angles = octants(), measures = "NARPD")
# Robust (sandwich) SEs so the mvn engine propagates a
# misspecification-consistent covariance (ssm_sem()'s default)
fit <- lavaan::cfa(syn, data = jz2017, se = "robust.huber.white")
set.seed(12345)
ssm_sem_parameters(fit, scales = scales, measures = "NARPD", boots = 500)

Generate lavaan syntax for a fixed-angle circumplex measurement model

Description

Emit lavaan model syntax for a structural-equation-model formulation of the Structural Summary Method, with the circumplex scale angles held fixed at their theoretical values. This is the syntax-generation layer of the SEM-based SSM (see the package's design notes); it is a pure function of its arguments and does not require lavaan to be installed (only fitting the emitted model does).

Usage

ssm_sem_syntax(
  instrument = NULL,
  scales = NULL,
  angles = NULL,
  measures = NULL,
  model = c("scaled", "strict"),
  n_groups = 1,
  invariance = c("configural", "metric", "scalar", "strict_residuals"),
  include_defined = NULL
)

Arguments

instrument

Optional. A circumplex_instrument object; its scale abbreviations and angles are used. Supply this or both scales and angles.

scales

Optional. A character vector of circumplex scale (column) names. Ignored when instrument is supplied.

angles

Optional. A numeric vector of scale angles in degrees, the same length as scales. Ignored when instrument is supplied.

measures

Optional. Either NULL or a character vector of external measure (column) names to relate to the circumplex factors.

model

Optional. The measurement-model tier: "scaled" (default) or "strict". See Details.

n_groups

Optional. A single positive whole number: the number of groups for a multi-group model. 1 (default) emits the single-group model. When n_groups >= 2 the generator emits multi-group syntax with a mean structure and the invariance constraints selected by invariance; fitting it requires lavaan::cfa() called with ⁠group = ⁠ a grouping variable whose number of levels equals n_groups. Group ordering follows the factor-level order of that variable: the first level is the reference group, whose factor metric (and, from the scalar rung, whose latent means) is fixed.

invariance

Optional. The cross-group invariance rung to emit when n_groups >= 2: "configural" (default), "metric", "scalar", or "strict_residuals". Must be left at its default when n_groups == 1 (supplying it there is an error). Under the "strict" tier the "metric" rung is vacuous (all loadings are fixed) and emits the configural structure with an explanatory comment. See the package design notes (section 6.2) for the adapted fixed-angle invariance ladder.

include_defined

Optional. (Single-group models only: for n_groups >= 2 the lines are unavailable and an explicit TRUE is ignored with a warning.) Whether to append inspection-only ⁠:=⁠ definitions of the covariance-metric ⁠(e, x, y)⁠ coordinates for each measure. NULL (default) emits them automatically under the "strict" tier when at least one measure is present (there they are linear), and omits them otherwise. TRUE forces emission (an error under "scaled", where they would be nonlinear); FALSE always suppresses them.

Details

Two model tiers are available. The "scaled" tier frees a general saturation and a circumplex saturation per scale while fixing each scale's angle; the circumplex plane is held isotropic and orthogonal, and the general factor is held orthogonal to the plane (freeing the general-plane covariances alongside free saturations makes the model locally unidentified exactly at zero covariance, so they cannot be estimated in this tier). The "strict" tier fixes every loading to the unit cosine pattern ⁠(1, cos(angle), sin(angle))⁠ and frees the 3x3 factor covariance matrix – including the general-plane covariances, making it the tier that can model a general factor leaning into the plane. The angles enter only as evaluated cosine and sine constants; no angle is ever a free parameter.

The returned string always carries a weights attribute: the ordinary-least-squares projection matrix that maps a profile vector to the structural summary coordinates ⁠(e, x, y)⁠. For equally spaced angles this equals the conventional closed-form estimator; for unequally spaced angles it is the least-squares projection and can differ. The emitted syntax never contains ⁠:=⁠ definitions for amplitude or displacement: those are nonlinear functions whose confidence intervals must be constructed in-package, not by lavaan's delta method (which ignores the angular branch cut).

Value

A single character string of lavaan model syntax, with attributes angles (a circumplex_degree vector), scales, model, weights (the 3-by-p OLS projection matrix, rows e, x, y), n_groups, and (when n_groups >= 2) invariance.

See Also

ssm_analyze() for the observed-data SSM.

Examples

# Octant instrument, default scaled tier
syn <- ssm_sem_syntax(scales = paste0("s", 1:8), angles = octants())
attr(syn, "weights")
cat(syn)

Create HTML table from SSM results or contrasts

Description

Take in the results of an SSM analysis and return an HTML table with the desired formatting.

Usage

ssm_table(ssm_object, caption = NULL, drop_xy = FALSE, render = TRUE)

Arguments

ssm_object

Required. The results output of ssm_analyze().

caption

A string to be displayed above the table (default = NULL).

drop_xy

A logical indicating whether the x-value and y-value parameters should be omitted from the output (default = FALSE).

render

A logical indicating whether the table should be displayed in the RStudio viewer or web browser (default = TRUE).

Value

A data frame containing the information for the HTML table. As a side-effect, may also output the HTML table to the web viewer.

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), 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()

Other table functions: html_render()

Examples

# Load example data
data("jz2017")

# Create table of profile results
res <- ssm_analyze(
  jz2017,
  scales = 2:9,
  measures = c("NARPD", "ASPD")
)
ssm_table(res)

# Create table of contrast results
res <- ssm_analyze(
  jz2017,
  scales = 2:9,
  measures = c("NARPD", "ASPD"), 
  contrast = TRUE
)
ssm_table(res)

Summarize circumplex axes-reliability results

Description

Fuller display of an axes_reliability() object: everything print() shows plus the estimated variance components (with standard errors) and the global fit indices.

Usage

## S3 method for class 'circumplex_axes_reliability'
summary(object, digits = 3, ...)

Arguments

object

A circumplex_axes_reliability object.

digits

The number of decimal places to display (default = 3).

...

Not used.

Value

object, invisibly.


Summarize the accuracy of SSM confidence intervals

Description

Print the full report of an ssm_ci_accuracy() run: the assessed configuration, a structure note describing the simulated population (with cautions when the structural model converged badly or fits poorly – benchmarks per Browne & Cudeck, 1993, and Hu & Bentler, 1999), the per-profile verdict blocks (coverage of elevation, amplitude, and certification-conditional displacement classified against Bradley's liberal band; the guardrail false-certification caution), and the coverage and guardrail tables across the amplitude ladder.

Usage

## S3 method for class 'circumplex_ci_accuracy'
summary(object, digits = 3, ...)

Arguments

object

A circumplex_ci_accuracy object from ssm_ci_accuracy().

digits

Number of digits to which table entries are rounded (default = 3).

...

Currently ignored.

Value

The object, invisibly.

References

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). Sage.

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.


Summarize a circular process model fit

Description

Fuller display of a cpm_fit() object: adds the correlation-function weights, the full set of fit indices, a residual summary (the largest absolute residual and the pair it belongs to), and all boundary/identification diagnostics in plain language. When the confidence intervals are analytic, prints a coverage caution calibrated by simulation: unconditionally when the sample size is modest (N < 2000, where Wald intervals mis-covered for every configuration studied), and up to N = 50000 when the fitted solution shows a boundary or weak-identification marker (Heywood communality, removed harmonic, small correlation-function weight, ill-conditioning, or competing near-tied optima), the regime where they mis-covered even at large N (see cpm_fit()).

Usage

## S3 method for class 'circumplex_cpm'
summary(object, digits = 3, ...)

Arguments

object

A circumplex_cpm object.

digits

The number of decimal places to display (default = 3).

...

Not used.

Value

object, invisibly.


Summarize per-person SSM parameters at the group level

Description

Aggregate a per-person SSM parameter table (from ssm_parameters_id()) into group-level summaries, using circular statistics for displacement: arithmetic means are meaningless for angles, so displacement is summarized by its circular mean (the direction of the summed unit vectors) and the mean resultant length (a 0 to 1 measure of directional concentration).

Usage

## S3 method for class 'circumplex_ssm_id'
summary(object, ...)

Arguments

object

Required. An object of class "circumplex_ssm_id" created by ssm_parameters_id().

...

Ignored (S3 consistency).

Details

Persons with undefined (NA) displacement are stripped before the circular aggregation – n_na_d reports how many – while the arithmetic means of the other parameters use all persons with defined values. Two aggregation caveats apply. (1) The circular mean of per-person displacements weights every person's direction equally; it is a different quantity from the displacement of the group mean profile (e.g., from ssm_analyze()), which weights persons by amplitude – on heterogeneous samples the two can differ substantially. (2) By the triangle inequality, the amplitude of the group mean profile is at most the mean per-person amplitude (a_mean), strictly smaller when directions disperse; relatedly, the mean resultant length d_res falls below 1 as directions disperse.

Value

A one-row data frame with columns n (persons), n_na_d (persons with undefined displacement, excluded from the circular summaries), e_mean, x_mean, y_mean, a_mean (arithmetic means), d_mean (circular mean of displacement, degrees in [0, 360], the 0/360 pole reported as 360), and d_res (mean resultant length in [0, 1]; NA when no displacement is defined, and undefined direction at zero resultant reports d_mean = NA).

See Also

Other ssm functions: plot.circumplex_ci_accuracy(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters(), ssm_table()

Other analysis functions: cpm_fit(), cpm_simulate(), ssm_analyze(), ssm_analyze_long(), ssm_ci_accuracy(), ssm_draws(), ssm_parameters(), ssm_parameters_id(), ssm_score(), ssm_sem(), ssm_sem_parameters()

Examples

data("aw2009")
res <- ssm_parameters_id(
  aw2009,
  scales = c("PA", "BC", "DE", "FG", "HI", "JK", "LM", "NO")
)
summary(res)

Summarize circumplex-structure test results

Description

Fuller display of a fit_structure() object: adds the interpretive cutoffs behind each classification, the estimated angle and communality of each scale, and the analysis settings.

Usage

## S3 method for class 'circumplex_structure'
summary(object, digits = 3, ...)

Arguments

object

A circumplex_structure object.

digits

The number of decimal places to display (default = 3).

...

Not used.

Value

object, invisibly.


Circumplex canvas theme

Description

The ggplot2 theme applied to the circumplex canvas built by ggcircumplex(). It is built on ggplot2::theme_minimal() so that the amplitude rings, displacement spokes, and labels drawn by coord_circumplex() are themed panel furniture that respond to further theming. Apply it to a custom circumplex plot, and add ⁠+ theme_*()⁠ or + theme() on top to restyle the canvas.

Usage

theme_circumplex(base_size = 12)

Arguments

base_size

A single positive number giving the base font size (in pt) for the theme (default = 12).

Value

A ggplot2 theme object, to be added to a plot with +.

See Also

Other circumplex layers: coord_circumplex(), geom_ssm_arc(), geom_ssm_path(), geom_ssm_point(), ggcircumplex(), scale_x_circumplex()

Examples

# Restyle the canvas with a larger base font
ggcircumplex(octants()) + theme_circumplex(base_size = 16)