Skip to contents

Measures how well each factor at each level of a bass-ackwards hierarchy replicates across random split-halves of the sample – Everett's (1983) factor comparability coefficients, reviving the split-half replication gate of the research program that produced the bass-ackwards method: Saucier (1997) screened factor solutions by their split-half stability, and Saucier, Georgiades, Tsaousis, and Goldberg (2005) chose the optimal hierarchical level by requiring split-half replication above a .90 threshold. It is also the direct instrument for the overextraction caution in suggest_k(): non-replicable structure concentrates in the deeper levels of an overextracted hierarchy (Forbes, 2023).

Usage

comparability(
  data,
  k_max,
  engine = "pca",
  cor = "pearson",
  fm = "minres",
  n_splits = 10L,
  seed = NULL,
  ...
)

Arguments

data

A data frame or numeric matrix of observed variables (items in columns, observations in rows). Raw data only – splitting needs rows, so a correlation matrix is not accepted. Missing values are handled pairwise throughout (as in ackwards()'s default).

k_max

Maximum number of factors/components to evaluate – normally the same value (or one or two above it) you intend to pass to ackwards(). Required.

engine

Extraction engine: "pca" (default) or "efa". "esem" is not yet supported here (fitting 2 * n_splits lavaan hierarchies needs its own performance treatment); for ESEM workflows, run comparability() with engine = "efa" as a structural screen.

cor

Correlation basis: "pearson" (default) or "spearman". As with suggest_k(), "polychoric" is not supported (estimating polychoric matrices in every half-sample is slow and unstable); users analysing ordinal data should screen replicability on the Pearson basis and fit the final model with cor = "polychoric" in ackwards().

fm

Factor extraction method passed to psych::fa(); only used when engine = "efa". One of "minres" (default), "ml", or "pa".

n_splits

Number of random split-half replicates. Default 10L. The published precedents used a single split (Saucier et al., 2005); repeating the split guards against the luck of one draw and is this implementation's robustness choice. Each replicate fits 2 * k_max solutions, so the default costs 20 hierarchy fits; PCA and EFA are fast enough that this is typically a few seconds.

seed

Integer seed for reproducible splits. NULL (default) uses the current RNG state.

...

Reserved for future arguments.

Value

An object of class "comparability". Print it for a per-level summary; call autoplot() on it for a diagnostic plot. The list contains:

coefficients

Data frame with one row per split x level x factor: split, level, factor (full-sample m{k}f{j} label), r (score comparability), phi (Tucker's congruence of the matched loading columns). NA when the level did not converge in one of the halves.

summary

Data frame with one row per level x factor: level, factor, r_median, r_min, phi_median, phi_min (across splits), and n_splits_ok (splits in which both halves converged).

k_max

Deepest level evaluated. Can be lower than the k_max you asked for when the full-sample fit truncated (non-convergence at deep levels); the original request is kept in k_requested.

k_requested, n_splits, n_half, engine, cor, fm, n_obs, n_vars, seed

Metadata.

Details

For each of n_splits random half-splits, solutions at every level 1..k_max are fit independently in each half. Each half-solution's factors are matched to the full-sample solution's factors (so coefficients are reported under the same m{k}f{j} labels you get from ackwards()), and the comparability coefficient for a factor is the correlation between its two matched half-solution scores, computed on the pooled correlation matrix via the same W'RW algebra used for between-level edges – applying both halves' scoring weights to the full sample, exactly Everett's procedure. Tucker's congruence coefficient (phi) between the matched half-solution loading columns is reported alongside: comparability asks whether the two halves' scores agree; phi asks whether their loading patterns agree.

Interpreting the output

Coefficients near 1 mean the factor re-emerges in independent half-samples; a factor whose comparability is low is sample-idiosyncratic and should not anchor substantive interpretation. Conventional benchmarks: .90 is the split-half replication threshold of Goldberg's lexical research program (Saucier et al., 2005) and follows from Everett's (1983) rationale (split-half factors sharing at least 81% of their variance); .95 is the stricter bound at which two factors are conventionally treated as interchangeable (Lorenzo-Seva & ten Berge, 2006). These are conventions, not tests, so comparability() reports every coefficient and flags nothing. The deepest level at which all factors replicate is a natural hierarchy floor for ackwards()'s k_max; see vignette("ackwards-girard") for the full workflow.

A level that fails to converge in a half-sample yields NA coefficients for that split (convergence is data, not an error); the number of usable splits per factor is reported in summary$n_splits_ok and a message summarises any shortfall.

References

Everett, J. E. (1983). Factor comparability as a means of determining the number of factors and their rotation. Multivariate Behavioral Research, 18(2), 197–218. doi:10.1207/s15327906mbr1802_5

Saucier, G. (1997). Effects of variable selection on the factor structure of person descriptors. Journal of Personality and Social Psychology, 73(6), 1296–1312. doi:10.1037/0022-3514.73.6.1296

Saucier, G., Georgiades, S., Tsaousis, I., & Goldberg, L. R. (2005). The factor structure of Greek personality adjectives. Journal of Personality and Social Psychology, 88(5), 856–875. doi:10.1037/0022-3514.88.5.856

Lorenzo-Seva, U., & ten Berge, J. M. F. (2006). Tucker's congruence coefficient as a meaningful index of factor similarity. Methodology, 2(2), 57–64. doi:10.1027/1614-2241.2.2.57

Forbes, M. K. (2023). Improving hierarchical models of individual differences: An extension of Goldberg's bass-ackward method. Psychological Methods. doi:10.1037/met0000546

See also

suggest_k() for the plausible depth range (eigenstructure), factorability() for sampling adequacy before you fit, prune() for factors that perpetuate without differentiating (redundancy), and ackwards() for the extraction itself.

Examples

# \donttest{
cmp <- comparability(sim16, k_max = 5, n_splits = 5, seed = 1)
#>  Fitting 5 split-half replicates (pca, k = 1-5)...
#>  Fitting 5 split-half replicates (pca, k = 1-5)... [218ms]
#> 
cmp
#> 
#> ── Split-Half Factor Comparability (ackwards) ──────────────────────────────────
#> Engine: pca
#> Basis: pearson
#> n: 1,000 (500 per half)
#> Splits: 5
#> Levels: 1-5
#> 
#> ── Comparability by level (median across splits) ──
#> 
#> k = 1: median r 1.00, min r 1.00 (m1f1)
#> k = 2: median r 1.00, min r 1.00 (m2f1)
#> k = 3: median r .79, min r .54 (m3f2)
#> k = 4: median r 1.00, min r 1.00 (m4f1)
#> k = 5: median r 1.00, min r .09 (m5f5)
#> ────────────────────────────────────────────────────────────────────────────────
#> Per-factor detail (incl. Tucker's φ) in `$summary`; per-split values in
#> `$coefficients`.
#> Conventional benchmarks: ≥ .90 replication floor (Everett, 1983; Saucier et
#> al., 2005), ≥ .95 factors interchangeable (Lorenzo-Seva & ten Berge, 2006) --
#> conventions, not tests. Interpret levels whose factors all replicate.
cmp$summary
#>    level factor   r_median      r_min phi_median    phi_min n_splits_ok
#> 1      1   m1f1 0.99897441 0.99601208 0.99649052 0.99229173           5
#> 2      2   m2f1 0.99812229 0.99717568 0.99456494 0.99096434           5
#> 3      2   m2f2 0.99850742 0.99600301 0.99601594 0.99407301           5
#> 4      3   m3f1 0.78659814 0.73422936 0.85231449 0.82714548           5
#> 5      3   m3f2 0.54081241 0.28312435 0.59080882 0.37403301           5
#> 6      3   m3f3 0.82233169 0.74886533 0.87304335 0.81227471           5
#> 7      4   m4f1 0.99751505 0.99459289 0.99356134 0.98733427           5
#> 8      4   m4f2 0.99756135 0.99455678 0.99197260 0.99050142           5
#> 9      4   m4f3 0.99753490 0.99620300 0.99384481 0.99266075           5
#> 10     4   m4f4 0.99795705 0.99723533 0.99492648 0.99367497           5
#> 11     5   m5f1 0.99742903 0.99288874 0.99363079 0.98729318           5
#> 12     5   m5f2 0.99604617 0.97938857 0.99122516 0.98620797           5
#> 13     5   m5f3 0.99596034 0.97771195 0.99181348 0.98687112           5
#> 14     5   m5f4 0.99748783 0.99463997 0.99493919 0.99365708           5
#> 15     5   m5f5 0.09432914 0.07241386 0.05763385 0.03246931           5
# }