Non-parametric case bootstrap
Description
Resample whole subjects with replacement, refit the same model to each replicate, and summarise the spread of the estimates into bias, standard errors and confidence intervals. Feature target: PsN’s bootstrap.
Usage
ferx_bootstrap(
model,
data = NULL,
samples = 200,
seed = 1,
threads = NULL,
stratify_on = NULL,
sample_size = NULL,
update_inits = TRUE,
run_base_model = TRUE,
keep_covariance = FALSE,
dofv = FALSE,
skip_minimization_terminated = TRUE,
skip_estimate_near_boundary = TRUE,
skip_covariance_step_terminated = FALSE,
skip_with_covstep_warnings = FALSE,
ci = 95,
directory = NULL,
verbose = FALSE
)Arguments
model: Path to a.ferxmodel file, or aferx_modelobject from[ferx_model](ferx_model.qmd).data: Path to a NONMEM-format CSV.NULL(the default) uses the model’s[data]block.samples: Number of bootstrap datasets. Default 200, PsN’s default and its stated rule of thumb for standard errors.seed: Master seed. Each replicate’s draw is derived from this and its own index, so a run is reproducible and independent ofthreads.threads: Replicates to fit concurrently.NULL(the default) uses the engine default.stratify_on: Name of a data column defining the resampling strata, orNULL(the default) for an unstratified run. Stratifying on study or arm keeps each replicate’s composition close to the original dataset’s.sample_size: How many subjects each replicate draws.NULL(the default) draws as many as the original dataset has - the only case where a stratified proportional split is guaranteed to sum back to the request. A single number sets one total for the replicate; a named numeric vector (c("1001" = 12, "1002" = 24)) sets an explicit count per stratum and is only meaningful together withstratify_on. Every count must be a whole number >= 1. It is PsN’s-sample_size=1001=>12,1002=>24, spelled the R way.update_inits: Start each replicate from the base fit’s final estimates (PsN default,TRUE). Requiresrun_base_model = TRUE.run_base_model: Fit the original dataset first. Required forupdate_inits, for the bias column, and for the normal-approximation intervals. DefaultTRUE.keep_covariance: Run the covariance step for each replicate. Off by default: it is most of the cost, and the bootstrap standard error comes from the spread of the estimates, not from any per-replicateR^-1. Turning it on addsse_<parameter>columns to$rawand is what the two covariance-step exclusion filters read.dofv: Compute the change in objective function value: evaluate each replicate’s parameter vector on the original dataset with no estimation (NONMEMMAXEVAL=0) and subtract the original fit’s OFV. Roughly doubles the run time. DefaultFALSE.skip_minimization_terminated: Exclude replicates whose minimization terminated. DefaultTRUE(PsN’s default).skip_estimate_near_boundary: Exclude replicates whose estimate sits on a boundary. DefaultTRUE(PsN’s default).skip_covariance_step_terminated, skip_with_covstep_warnings: Exclude replicates on the covariance step’s outcome. Both defaultFALSE, and both requirekeep_covariance = TRUE- asking for one without it is an error rather than a silently dropped filter.ci: Two-sided confidence level, in percent. Default 95.directory: Where to write the CSV artefacts (raw_results.csv,bootstrap_results.csv,bootstrap_diagnostics.csv, the individual and key files, anddelta_ofv.csvwhendofv = TRUE).NULL, the default, computes everything in memory and writes nothing - an R user has the data frames in hand and rarely wants eight files appearing in the working directory. The CLI defaults the other way. Set it if you want to be able to call[ferx_bootstrap_summarize](ferx_bootstrap_summarize.qmd)later.verbose: Print a one-line run header to stderr. DefaultFALSE.
Details
The bootstrap runs in the engine (ferx-core’s ferx-tools crate); this function is a thin wrapper. The percentile estimator, the exclusion filters, the parameter naming and the sample_size syntax all live there, so an R session and the ferx bootstrap CLI produce the same numbers from the same seed.
What the bootstrap buys over the covariance step
ferx’s standard errors are the asymptotic R^-1 matrix, symmetric by construction. The bootstrap distribution assumes neither normality nor symmetry: it survives a failed or non-positive-definite covariance step, and it shows asymmetry in poorly identified parameters instead of averaging it away. Both intervals are returned side by side (ci_lower / ci_upper for the percentile interval, ci_lower_normal / ci_upper_normal for the normal approximation built from the bootstrap standard error) precisely so the disagreement between them is visible.
Exclusions
A replicate whose minimization terminated, or whose estimate sits on a boundary, is not a draw from the sampling distribution of a converged fit, so by default it is excluded from the statistics (PsN’s defaults). The replicate is still fitted and still appears in $raw; only the summary drops it. $diagnostics reports how many were dropped and why. To change the criteria after a run has finished, use [ferx_bootstrap_summarize](ferx_bootstrap_summarize.qmd)instead of refitting - but that needs directory to have been set.
Cost
This is samples (+ 1) complete fits. At PsN’s rule-of-thumb 200 samples a model that takes a minute to fit takes over three hours, so threads is the argument that matters most. Note that the run is not interruptible with Ctrl-C once the replicates are underway.
Seealso
[ferx_bootstrap_summarize](ferx_bootstrap_summarize.qmd) to change the exclusion criteria on a finished run, [ferx_sir](ferx_sir.qmd) and [ferx_covariance](ferx_covariance.qmd) for the parametric uncertainty routes. Other fitting: [ferx_bootstrap_summarize](ferx_bootstrap_summarize.qmd), [ferx_check_init](ferx_check_init.qmd), [ferx_collect](ferx_collect.qmd), [ferx_covariance](ferx_covariance.qmd), [ferx_fit](ferx_fit.qmd), [ferx_inits_from_nca](ferx_inits_from_nca.qmd), [ferx_sir](ferx_sir.qmd), [ferx_stop](ferx_stop.qmd), [print.ferx_job](ferx_fit_async.qmd)
Concept
fitting
Value
An object of class ferx_bootstrap, a list with:
- parameters: Data frame, one row per parameter:
parameter,original,mean,bias,standard_error,median,ci_lower,ci_upper,ci_lower_normal,ci_upper_normal. This isbootstrap_results.csv. - raw: Data frame, one row per fit with the original dataset first (
sample = 0), carrying the estimates and the termination diagnostics the exclusion filters read. This israw_results.csv, and it is what makes a custom R-side filter or re-summarisation possible. - diagnostics: Data frame of
statistic/value: the run counts, the exclusion tallies (excluded: ...) and the diagnostic means (mean: ...). - delta_ofv: Data frame of
sample/delta_ofvwhendofv = TRUE, otherwiseNULL. - parameter_names, subject_ids, n_completed, n_included, chi_square_df, confidence_level, samples, seed, model, data, directory: Run metadata.
chi_square_dfis the number of estimated parameters, the reference degrees of freedom for thedofvpanel of[plot.ferx_bootstrap](plot.ferx_bootstrap.qmd).
Examples
ex <- ferx_example("warfarin")
bs <- ferx_bootstrap(ex$model, ex$data, samples = 200, seed = 12345,
threads = 8)
bs
bs$parameters
plot(bs)
# Stratified, with artefacts on disk so the run can be re-summarised later
bs <- ferx_bootstrap(ex$model, ex$data, samples = 200,
stratify_on = "SEX", directory = "warfarin-bootstrap")
ferx_bootstrap_summarize("warfarin-bootstrap",
skip_estimate_near_boundary = FALSE)