Skip to content

ackwards 0.2.0

Choose a tag to compare

@jmgirard jmgirard released this 27 Jul 20:37

New publication-figure controls for autoplot(), secondary correlation edges
in the pruned view, a near-redundant band in prune(), and cleaner layouts for
deep hierarchies. Also fixes an error on degenerate hierarchies, and a crash in
the package's own test suite — both of which surfaced only on particular
numerical platforms after 0.1.1 was published.

  • Publication-figure controls for autoplot(). Three additions make
    hand-tuned figures easier. show_items = TRUE lists the salient items (top
    n_items by |loading|, via the same extraction as top_items()) beneath
    each deepest-level factor box, so a figure shows what each most-granular factor
    is made of. node_width / node_height now also accept a named vector
    keyed by factor ID, sizing individual boxes to fit long manual labels. And
    order = (also on ba_layout()) fixes the deepest level's left-to-right order
    by hand — every factor above stays centred over its primary children, so any
    arrangement of the hierarchy is reachable from the leaf order. All are opt-in;
    defaults are unchanged. The visualization vignette demonstrates each.

  • autoplot(drop_pruned = TRUE) can now draw secondary correlation edges.
    A new show_secondary = TRUE adds the between-level correlations the pruned
    view otherwise hides — every kept cross-level factor pair with
    |r| >= cut_show that is not the single strongest-ancestor primary edge,
    including a factor's weaker second parents and direct skip-level
    correlations (a skip-level |r| is its own non-transitive fact). They render
    in a channel deliberately distinct from the primary edges — dimmed and thinner,
    drawn beneath them — while still inheriting the sign encoding (sign_by), so
    the sign color/linetype is never conflated with the secondary channel. Default
    FALSE leaves the pruned view unchanged. The visualization vignette
    illustrates the new argument.

  • prune(x, "artifact") now reports a near-redundant band. A new
    x$prune$near_redundant table flags cross-level factor pairs that sit just
    below
    the redundancy thresholds — where prune(x, "redundant") drops full
    redundancy (|r| >= redundancy_r), the band surfaces the messier candidates a
    hair under it (e.g. |r| = 0.89 / phi = 0.94), which Forbes (2023) treats as
    the main use of the artifact flags. A pair is flagged when its direct
    (skip-level) |r| or its Tucker phi falls within the new near_margin
    argument (default 0.1) below the corresponding threshold, and the pair is not
    itself fully redundant. The band is report-only — no factor is dropped on its
    basis. Under EFA/ESEM, redundancy_phi now auto-resolves in artifact mode too
    (announced via cli), so the phi band is active; under PCA only the |r| band
    applies. The Forbes-extension vignette's artifact example now illustrates a
    genuinely near-redundant pair rather than one redundancy already drops.

  • Cleaner deep-hierarchy diagrams (k >= 10). ba_layout() now orders each
    level by a traversal of the primary-parent forest, laying every subtree out as
    a contiguous block. This drives primary-tree edge crossings to zero in deep
    hierarchies (the "bent levels" the previous single-pass ordering left behind —
    e.g. 3 crossings down to 0 on the 155-variable AMH example at k_max = 10),
    with no change to shallow layouts and the primary-child x-placement unchanged.
    Separately, autoplot(show_r = TRUE) now dodges overlapping edge-correlation
    labels apart so dense diagrams stay legible. The layout stays fully
    deterministic.

  • print() for suggest_k() now renders an aligned criteria table. The
    per-criterion evidence prints as a column-aligned grid (one row per k, one
    column per requested criterion) with a header row and a glyph legend, instead
    of the previous per-k concatenated lines. Numeric columns are right-aligned so
    the optimal-k star never shifts the decimals, and the "retained" tick is drawn
    in text presentation so terminals that render it as a wide emoji keep the
    columns aligned. The returned object and all criteria values are unchanged;
    only the printed layout is new.

  • Clarified documentation (no behavior change). The ?prune help and the
    bass-ackward vignette now explain the default redundancy_criterion = "direct"
    as a star anchored on the chain's deepest factor — each ancestor correlates
    directly with that leaf — distinct from adjacent-hop chaining and from an
    all-pairs screen. The ?ackwards rationale for varimax now states the reason
    correctly: the between-level edge algebra is exact for any linear scoring, so
    orthogonality is an interpretive choice (it keeps within-level factors
    uncorrelated, so between-level edges are not confounded by within-level factor
    intercorrelation), not a numerical necessity. The artifact-mode discussion now
    frames automated flags as removing investigator degrees of freedom, leaving
    only the substantive drop decision to the researcher.

  • Fixed an error when a level of the hierarchy is degenerate. If an
    extraction produced a factor whose scores carry no variance — reachable when
    k_max exceeds what the data can identify — ackwards() aborted with an
    opaque invalid subscript type 'list' message instead of handling it. Such a
    level is now recorded, warned about, and skipped, with every level above it
    kept, which is how a non-converged level has always been treated. The failure
    was platform-dependent: the same fit is merely ill-conditioned under most
    numerical libraries and fully degenerate under others, so it surfaced only on
    some check platforms (ATLAS and no-long-double builds). A hierarchy left with
    fewer than two usable levels now reports that directly.

  • The package's own tests no longer require two identically seeded
    boot_edges() runs to agree bit-for-bit. A multi-threaded linear-algebra
    library may reassociate its reductions between runs, which moves aggregated
    bootstrap quantities in the last unit of precision (~1e-16, seen on ATLAS
    builds); the test now allows that while still holding the seed to a far
    tighter standard than any real reproducibility failure would pass. Nothing
    user-facing changed.

  • Fixed a crash in the package's own test suite on macOS. Two tests set a
    forking parallel plan (future::multicore) to verify that parallel and
    serial fits agree exactly. Forking does not mix with the multi-threaded
    numerical libraries R's linear algebra runs through — ?mclapply warns against
    the combination — and R segfaulted inside the forked worker on one of CRAN's
    macOS check flavours. Both tests now skip macOS and continue to run everywhere
    else. Nothing user-facing changed: ackwards() and boot_edges() never set a
    parallel plan themselves — the default plan is sequential, and choosing one is
    the caller's business.