Measures how well each factor at each level of a bass-ackwards hierarchy
replicates across random split-halves of the sample. A factor is a
summary variable standing in for a group of items that move together. In a
split-half analysis the sample is split into two random halves and each
half is analysed separately. The coefficients are Everett's (1983) factor
comparability coefficients. They revive 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. This is
also the direct instrument for the overextraction caution in suggest_k(),
because 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, because 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 or components to evaluate. Normally this is 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, because fitting2 * n_splitslavaan hierarchies needs its own performance treatment. For ESEM (exploratory structural equation modeling) workflows, runcomparability()withengine = "efa"as a structural screen.- cor
Correlation basis:
"pearson"(default) or"spearman". As withsuggest_k(),"polychoric"is not supported, because estimating polychoric matrices in every half-sample is slow and unstable. Users analysing ordinal items (a few ordered categories, such as a 1 to 5 rating) should screen replicability on the Pearson basis. They should then fit the final model withcor = "polychoric"inackwards(), which estimates the correlation between the continuous traits assumed to underlie the ordered responses.- fm
Factor extraction method passed to
psych::fa(). It is only used whenengine = "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, so the coefficients are summarised over replicates. Each replicate fits2 * k_maxsolutions, so the default costs 20 hierarchy fits. PCA (principal component analysis) and EFA (exploratory factor analysis) 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, or call autoplot() on it for a diagnostic plot. The list
contains:
- coefficients
Data frame with one row per split x level x factor. Its columns are
split,level,factor(full-samplem{k}f{j}label),r(score comparability), andphi(Tucker's congruence of the matched loading columns). A value isNAwhen the level did not converge in one of the halves.- summary
Data frame with one row per level x factor. Its columns are
level,factor,r_median,r_min,phi_median,phi_min(across splits), andn_splits_ok(splits in which both halves converged).- k_max
Deepest level evaluated. It can be lower than the
k_maxyou asked for when the full-sample fit truncated, that is, when deep levels did not converge. The original request is kept ink_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 from 1
to 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(). The
comparability coefficient for a factor is the correlation between its two
matched half-solution scores. It is 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. A loading is the
correlation between an item and a factor, and congruence is a 0 to 1 index
of how similar two loading patterns are. So comparability asks whether the
two halves' scores agree, and 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. Two benchmarks are conventional. The
first, .90, is the split-half replication threshold of Goldberg's
lexical research program (Saucier et al., 2005). It follows from Everett's
(1983) rationale, under which split-half factors share at least 81% of
their variance. The second, .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, because 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)... [244ms]
#>
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
# }
