
Run a Shift-Recovery Simulation Study
Source:R/simulation-studies.R
runShiftRecoverySimulationStudy.RdRepeatedly simulate known-shift datasets from a
createSimulationTemplate() object and analyze
each replicate with searchOptimalConfiguration() to estimate expected shift
recovery performance. The default "original" generator reproduces the
published simulation operations. The "empirical" generator remains
available explicitly for full-covariance draws and an empirically calibrated
integration-rate robustness scenario.
Arguments
- template
A
bifrost_simulation_templatereturned bycreateSimulationTemplate().- n_replicates
Integer number of simulation replicates to run.
- tree_tip_count
Optional integer tip count for random subtree sampling. If
NULL, each replicate uses the full empirical tree.- simulation_options
Named list of additional arguments passed to
simulateShiftedDataset(), including covariance and integration-rate trade-off controls. The manuscript-compatible"original"generator is used by default; requestsimulation_generator = "empirical"for the full-covariance option. Thesimulation_generatorentry must contain exactly one supported string. For replicated studies,simulation_options$seedis not allowed; use the wrapper-levelseedargument instead.- search_options
Named list of arguments passed to
searchOptimalConfiguration(). These override the default response-only intercept-only search settings assembled fromtemplate. Ifformulais omitted, the wrapper inheritstemplate$search_formula, which is intercept-only in the empirically calibrated simulation workflow.- fuzzy_distance
Integer node distance used for fuzzy matching in
evaluateShiftRecovery().- weighted
Logical; if
TRUE, compute weighted recovery summaries using IC weights when available.- num_cores
Integer number of workers used across replicate analyses. When greater than one, outer replicate parallelism takes precedence and each inner search is forced to
search_options$num_cores = 1.- seed
Optional integer random seed. When supplied, the wrapper restores the caller's previous RNG state before returning.
Value
A list of class bifrost_simulation_study containing the simulated
datasets, raw search results, per-replicate summaries, a study-level
recovery summary, and the output of evaluateShiftRecovery().
Details
By default, the search configuration uses uncertaintyweights_par = TRUE
when weighted = TRUE, so shift-recovery summaries can report both
unweighted and IC-weighted metrics.
Regardless of the global calibration model used to build template, the
downstream search is intentionally restricted to intercept-only formulas.
This keeps the study focused on shift recovery in the simulated response
block rather than re-estimating predictor effects within each replicate. The
simulated trait_data supplied to each search result therefore contains only
the regenerated response variables.
Templates calibrated with covariates are supported; those covariates influence
the fitted means and residual covariance used to generate each response block,
but they are not re-fit within each simulated search replicate.
Failed search replicates are retained in the output, but their inferred-shift
metrics are recorded as NA and excluded from recovery evaluation. Their
error messages and candidate counts remain available for diagnosis, and
completion and failure rates are reported separately. Reproducibility for
replicated studies is controlled by the wrapper-level seed argument. A
supplied seed deterministically creates separate per-replicate simulation
and search streams, so serial and parallel runs use the same replicate-level
random draws. Parallel execution also uses future.seed = TRUE;
per-replicate simulator seeds are intentionally disallowed here.
When num_cores > 1, namespace-level workers receive only their current
replicate and compact shared settings; replicate call records use a literal
template placeholder so the complete calibration template is not serialized
again inside every simulated object.
Examples
if (FALSE) { # \dontrun{
set.seed(1)
tr <- ape::rtree(40)
X <- matrix(rnorm(40 * 3), ncol = 3)
rownames(X) <- tr$tip.label
tmpl <- createSimulationTemplate(tr, X, formula = "trait_data ~ 1", method = "LL")
recovery_study <- runShiftRecoverySimulationStudy(
tmpl,
n_replicates = 2,
tree_tip_count = 25,
simulation_options = list(
num_shifts = 2,
min_shift_tips = 3,
max_shift_tips = 8,
scale_mode = "proportional"
),
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 2
)
recovery_study
} # }