CRAN resubmission of the first release, addressing reviewer feedback on the 0.1.0 submission; also picks up everything added since that submission.
Fixed compatibility with lavaan 0.7. lavaan 0.7 renamed its
sample-statistics slot argument (breaking the ESEM engine's multi-level
reuse of anchor-level sample statistics — every level beyond k = 1 failed
to build) and now requires an explicit ordered = FALSE to use WLSMV/ULSMV
with continuous data. The ESEM engine detects the installed lavaan's
argument vocabulary and works with both lavaan >= 0.7 and >= 0.6-13.
New vignette: "Reproducing Forbes (2023): The AMH Applied Example"
(vignette("ackwards-forbes2023")). A full worked reproduction of the
paper's 155-variable applied example on the bundled forbes2023 dataset:
the 10-level hierarchy, skip-level correlations, the redundancy chase
(including where the default direct criterion and the adjacent opt-in
disagree), and the pruned-factor diagram in the paper's publication style.
Corrected the Forbes (2023) article title in the forbes2023 help page
("bass-ackward method", per the published title).
Corrected the n_obs advisory for PCA on correlation-matrix input. The
message (and the n_obs help text) claimed supplying n_obs would enable
chi-square/RMSEA/TLI, but the PCA engine's level fit is eigenvalue-based and
never computes them; n_obs is recorded in the result metadata and feeds
the N-based sampling-adequacy checks only. The message now says so. No
behavior changes.
Completed the Goldberg (2006) reference to its full published title ("Doing
it all Bass-Ackwards: The development of hierarchical factor structures from
the top down") in the ackwards() help page and four vignettes.
Corrected the historical citations for comparability()'s split-half
benchmarks. The .90 replication threshold traces to Everett (1983) and
to its use in Goldberg's lexical research program by Saucier (1997) and
Saucier, Georgiades, Tsaousis, and Goldberg (2005) — not to Goldberg
(1990), which contains no split-half analyses and is no longer cited for
this purpose. The .95 reference line is now sourced to Lorenzo-Seva and
ten Berge (2006). Affects the roxygen help page, print()/autoplot()
footer text, the README, and the replicability-workflow vignette; no
behavior changes.
Sourced suggest_k()'s k-selection guidance. The consensus-range stance
now cites Lim and Jahng (2019) with Achim's (2021) counterpoint, and the
"PA-PC tends to overextract" note cites Saucier (1997) alongside Forbes
(2023), in both the help page and the suggest-k vignette; no behavior changes.
label_template() now returns its scaffold visibly (behavior change).
The named character vector carries class "ackwards_labels", and the
editable c(...) literal is rendered by its print() method instead of
being written to the console unconditionally. A top-level call looks the
same as before; assigning the result (labs <- label_template(x)) or
passing it inline (e.g. inside autoplot()) is now silent, per CRAN
policy on console output.
DESCRIPTION now spells out principal component analysis (PCA), exploratory factor analysis (EFA), and exploratory structural equation modeling (ESEM) per CRAN feedback.
New bundled dataset forbes2023. The 155-variable "Assessing Mental Health"
Spearman correlation matrix that forms Forbes's (2023) applied example is now
exported, so ackwards(forbes2023, k_max = 10) reproduces her worked hierarchy
directly. It joins bfi25 and sim16. The matrix is redistributed under
CC-BY 4.0 with attribution to M. K. Forbes (see LICENSE.note).
prune("redundant") gains redundancy_criterion, defaulting to "direct"
(behavior change). Redundancy chains are now traced by the direct
(skip-level) correlation between a factor and each ancestor level — Forbes's
(2023) actual ChaseCorrPaths rule — rather than the previous adjacent-hop
walk. Because correlation is non-transitive, the two can differ in deep
(many-level) hierarchies: on shallow ones (e.g. the bundled sim16) results
are unchanged, but a factor can now be flagged redundant with an ancestor it
correlates with directly even if an intermediate step is weak (and vice
versa). Pass redundancy_criterion = "adjacent" for the old behavior. This
makes prune("redundant") reproduce Forbes's published applied example
exactly. print() and summary() name the active criterion. Note that under
"direct", a chain's r_to_prev column reports the adjacent-level
correlation and can sit below redundancy_r (membership is set by the direct
skip-level link; see ?prune).
Validation. The Forbes (2023) fidelity suite now also reproduces her
155-variable "Assessing Mental Health" applied example (k_max = 10), not just
the three simulation studies: between-level correlations match her reference
implementation to 1.3e-14 across all 45 level-pairs, loading congruences agree
within her two-decimal rounding, and her redundancy chase is reproduced for all
54 components. The published matrix ships as a test fixture under CC-BY 4.0
(see LICENSE.note).
suggest_k() now reads Comparison Data (CD) results from EFAtools >= 0.8.0,
which restructured CD()'s return value (the per-iteration RMSE matrix moved
from the top-level RMSE_eigenvalues field into results[[1]]$rmse_eigenvalues).
Without this, the CD criterion and its autoplot() panel silently dropped out
when a current EFAtools was installed. Older EFAtools versions still work.
Console output consistency. summary()'s per-level fit-index pass/fail
mark is now the same terminal-adaptive cli glyph as print()'s convergence
mark (a tick/cross that degrades to v/x in a non-UTF-8 console), replacing
a hard-coded Unicode ✔/✘. And print()'s cumulative-variance percentages
now carry a fixed single decimal (e.g. 20.0%, where a whole-number value
previously printed as 20%), matching summary(). Cosmetic only; the
reported values are unchanged.
First public release. ackwards implements Goldberg's (2006) bass-ackwards
method and its modern extensions: it fits factor solutions at every level from 1
to k and characterizes the hierarchy through the between-level factor-score
correlations that connect them. Initial features, roughly in order of importance:
ackwards() — fit the hierarchy with a PCA, EFA, or ESEM engine;
between-level edges from Waller's (2007) exact W′RW algebra.suggest_k() — bracket a plausible depth range from five retention
criteria (parallel analysis, MAP, VSS, Comparison Data).comparability() — gate hierarchy depth on split-half replicability
(Everett 1983; Goldberg 1990).factorability() — screen a dataset (or correlation matrix) before you
fit: Kaiser-Meyer-Olkin sampling adequacy (overall and per item), Bartlett's
test of sphericity, the N:p ratio, and the Ledermann bound on identifiable
factors, reported as numbers-and-bands rather than pass/fail. ackwards()
runs a light version internally and warns only at the consequential extreme
(k_max above the Ledermann bound for EFA/ESEM, or poor sampling adequacy).pairs = "all" skip-level edges, prune() for
redundant/artifactual factors, and boot_edges() bootstrap edge CIs.cor = "polychoric" (WLSMV for ESEM), check_items()
pre-analysis screening, and near-singularity diagnostics.top_items() for reading factors;
label_template()/set_factor_labels()/factor_labels() to attach persistent
substantive names shown across print(), summary(), autoplot(), tidy(),
and top_items(); augment()/predict() for factor scores, in and out of
sample.autoplot() hierarchy diagrams and tidy()/glance()/summary().bfi25 (ordinal Big Five) and sim16 (continuous), plus
eight vignettes.Beyond base R, psych is the only hard dependency; lavaan, ggplot2, and
others are optional.