Hardened parallel execution for unavailable core counts and CRAN’s two-core check limit.
Preserved the caller’s complete RNG kind and
.Random.seed across seeded simulations.
Replaced duplicated grid-parallel code with the common parallel helper.
Added deterministic tests for parallel RNG streams, RNG restoration, and core limits.
Normalized benchmark reference files to UTF-8/LF and excluded the archival one-off analysis script from CRAN builds.
Fixed the benchmark-suite summary so artifact-specific validation tables with different columns are combined safely. ## Benchmark and validation module
Added a non-exported benchmark suite under
inst/benchmarks/ and a reproducible
vignette("benchmark-validation").
The suite reproduces the manuscript reference values and
calculations for Table 2, Figure 3, Table 3, and Figure 5 in Lin et
al. (2026), with machine-readable reference values, prespecified
tolerances, package-version metadata, sessionInfo(), and
strict or non-strict execution modes.
Table 2 reruns swCRTdesign and swdpwr
when installed, while retaining PASS and Shiny CRT Calculator values as
reference-only comparisons. Table 3 reruns the marginal GEE grid in
swdpwr.
Figure 3 uses an independent base-R matrix-inversion implementation and includes the maximal non-overlap delay. Figure 5 evaluates the Appendix C closed-form scaled-variance expressions and verifies them independently by WLS matrix inversion for non-boundary ICC values.
Source inconsistencies are documented rather than silently reconciled, including the Figure 3 treatment-prevalence discrepancy between the manuscript prose and public code. No benchmark helper is exported, so the public API is unchanged.
sw_batched_design() and
as_batched_design(). Batch-aware design objects retain the
treatment schedule and observation mask while adding batch labels, batch
initiation periods, delays from the first batch, gaps from the preceding
batch, calendar period, and relative time since batch initiation
(time_on_trial). Batch labels can be supplied or inferred
from first observed periods.sw_batched_assumptions() for data generation
under a calendar-time, shared time-on-trial, or separate batch-specific
time model.simulate_batched_swcrt(),
fit_batched_model(), and
audit_batched_design(). The separate time model uses a
categorical batch-by-local-time factor and supports batches with unequal
observed lengths; the calendar model shares secular effects by calendar
period; and the time-on-trial model shares relative-time effects across
batches.power_batched_swcrt() and
type1_batched_swcrt() so the generating and fitted time
models can be matched or intentionally differed in a reproducible
simulation study.compare_batched_designs(),
compare_swd_bswd(), and
compare_batched_time_models() for equal-resource
comparisons of classic SWD and BSWD schedules and for sensitivity
analysis across the three time parameterizations.B_vs_A,
completing the standard comparisons needed for paths such as Control
-> A -> B -> A+B.vignette("batched-stepped-wedge-designs") and updated the
installed SWD/BSWD demonstration to use the batch-aware interface.sw_component_design() for arbitrary asynchronous
schedules containing Control, A, B, and A+B. Schedules may be supplied
as a four-state matrix or as separate binary component-assignment
matrices. Unlike the cumulative interface, component schedules may
include withdrawal and reintroduction.as_component_design() to convert the version
0.3.0 cumulative Control/A/A+B design into the general
representation.observed mask to
sw_component_design(). Cells marked FALSE
retain their latent treatment history but contribute no outcome and no
row to the fitted model.sw_incomplete_component_design() for schedules
written with -, blank cells, or NA. The
constructor accepts manuscript labels such as 0,
1, and 1+2, distinguishes missing periods from
Control, and infers latent leading or trailing states when they are
unambiguous.component_resource_summary() to report calendar
and observed sequence-periods, cluster-periods, and total individual
observations.sw_component_assumptions() with separate A and B
main effects, an A-by-B interaction, component-specific wash-in periods,
restart rules, and user-defined non-increasing carryover weights after
withdrawal.simulate_component_swcrt() with complete
assignment and effect-history columns, including exposure episodes,
withdrawals, restarts, periods since withdrawal, current effects,
residual carryover, and true component contributions.fit_component_model() with standard contrasts for
A versus Control, B versus Control, A+B versus Control, A+B versus A,
A+B versus B, and the A-by-B interaction. Linear-contrast standard
errors use the full fitted covariance matrix.audit_component_design() to check state support,
concurrent treatment comparisons, withdrawal and restart patterns,
fixed-effect rank, and formal estimability of requested contrasts under
the planned wash-in and carryover rules.power_component_swcrt() and
type1_component_swcrt() with exact Monte Carlo intervals,
multiplicity-adjusted tests, joint-success probability, conditional and
failure-aware power, bias, standard-error calibration, coverage,
convergence, singularity, and warning diagnostics.compare_component_designs() for equal-resource or
unequal-resource comparisons of two or more candidate component
schedules.fit_diagnostics, per-simulation
replicate_diagnostics, retained error and convergence
messages, and the same breakdown in every power-table row. Singularity
is reported as a non-exclusive property and does not by itself make an
otherwise evaluable fit unsuccessful.sw_multistage_design() for schedules in which
sequences transition from Control to A and later to A+B at different
calendar periods. Start periods may be supplied directly or through an
explicit 0/1/2 state matrix.sw_multistage_assumptions() and
simulate_multistage_swcrt() with separate wash-in delays
for A and B, an A-versus-Control effect, an incremental B effect, and
the implied total A+B effect.audit_multistage_design() to identify weak or
aliased schedules, including a common B calendar start, a constant
A-to-B lag, absent concurrent Control/A or A/A+B comparisons, and
rank-deficient fixed-effect models.fit_multistage_model(),
power_multistage_swcrt(), and
type1_multistage_swcrt(). Results include raw and
multiplicity-adjusted component tests, the total A+B contrast,
joint-success probability, Monte Carlo intervals, estimation
diagnostics, convergence and singularity rates, conditional power, and
failure-aware power that counts unusable fits as unsuccessful
trials.compare_multistage_designs() for a like-for-like
comparison of a Control-to-A design with a Control-to-A-to-A+B
design.vignette("asynchronous-a-ab") and an installed
demonstration script.power_grid() runs power_swcrt() across a
Cartesian grid of assumptions – effect size, ICC, cluster-period size,
and the number of clusters per sequence – and returns an
sw_power_grid object with print(),
summary(), and plot() methods. The plot draws
power curves with exact Monte Carlo intervals.power_swcrt() and power_grid() gain an
n_cores argument. Each replicate is assigned its own
L’Ecuyer-CMRG random-number stream, so a run is reproducible under a
given seed regardless of the number of
cores.validate_engine() re-runs a power calculation with an
independently written reference implementation that shares no code with
the main engine, and reports whether the two agree within Monte Carlo
error.compare_with_swdpwr() lines the simulation up against
the closed-form calculation in the swdpwr package
(Suggests). This is offered for information, not as a
validation target: closed-form stepped-wedge power is asymptotic in the
number of clusters and can be markedly optimistic at the small cluster
counts these trials typically use. Where the two disagree, prefer the
simulated value.fit_stepwedge_model() now defaults to
adjust_sequence = FALSE, giving the standard Hussey-Hughes
model: treatment, a categorical period effect, and a cluster random
intercept.
In a stepped-wedge design a cluster belongs to exactly one sequence
for the whole trial, so sequence is a cluster-level attribute already
absorbed by the cluster random intercept. Including
factor(sequence) as a fixed effect is close to redundant:
in testing it lowered power (0.32 vs 0.44 in one design) and roughly
doubled the rate of singular fits. Baseline differences between
sequences still enter the simulation through baseline_prob,
where they belong.
This changes the default output of fit_stepwedge_model()
and analyze_swcrt(). Pass
adjust_sequence = TRUE to recover the previous model. The
legacy run_stepwedge_analysis() is unchanged and still fits
the sequence term, so version 0.1.x code keeps its original
behaviour.
prepare_cluster_data(),
summarize_by_group(),
fit_grouped_rate_model(),
estimate_group_rates(), and
analyze_aggregated_outcomes(): the application-neutral
forms of the physician/specialty helpers. Clusters and groups may be
anything.prepare_physician_data(),
summarize_by_specialty(),
fit_specialty_rate_model(),
estimate_specialty_rates(), and
analyze_lpa_outcomes() are retained as thin application
wrappers over the generic functions. They are no longer the package’s
central interface.vignette("stepped-wedge-design") – designing and
powering a stepped-wedge trial in general terms.vignette("lpa-case-study") – the original Lp(a)
physician testing study, as one application of the generic engine.sw_design() constructs a stepped-wedge design from
either per-sequence crossover periods or an explicit 0/1 treatment
matrix. Supports multiple baseline periods, unequal clusters per
sequence, and custom, incomplete, or simultaneously crossing
schedules.sw_assumptions() collects the data-generating
assumptions (baseline risk, treatment effect, ICC / cluster SD, secular
period trend, cluster-period sample size). Baseline and sample size may
be scalar, per-sequence, or per sequence-period; sample size may also be
a function.simulate_swcrt(design, assumptions) is the generic
simulation engine and returns application-neutral columns:
cluster_id, sequence,
sequence_idx, period,
intervention, n, events.fit_stepwedge_model() / analyze_swcrt()
fit a configurable binomial random-intercept model by variable name or a
user-supplied formula.power_swcrt() returns an sw_power object
carrying power, mcse, conf.int,
failure_rate, per-simulation estimated_effects
/ estimated_ses, convergence_status,
singular_fit, coverage, and bias,
with print(), summary(), and
plot() methods.simulate_stepwedge_trial(),
run_stepwedge_analysis(), estimate_power(),
and estimate_type1_error() retain their 0.1.x interfaces
and delegate to the new engine. Legacy simulated columns are still
produced.icc_to_cluster_sd() and
cluster_sd_to_icc(), and an icc argument.