
Bootstrap covariance, correlation, communality, and ICC summaries
Source:R/bootstrap-sigma.R
bootstrap_Sigma.RdUse bootstrap_Sigma() when Hessian, Wald, or profile intervals are
unavailable or unsafe but the fitted model still has useful point
estimates. A pdHess = FALSE or skipped sdreport() is an
inference warning, not automatic proof that the fitted mean or
rotation-invariant covariance summaries are unusable. Inspect
check_gllvmTMB() / gllvmTMB_diagnose() first, then use this
helper for parametric simulate-refit uncertainty.
Arguments
- fit
A fit returned by
gllvmTMB().- n_boot
Integer; number of bootstrap replicates. Default 200.
- level
Character vector; which tier(s) to bootstrap. Use the canonical levels
c("unit", "unit_obs", "phy"); legacy aliases"B"and"W"are still accepted. Levels absent from the fit are silently dropped. Default: all available levels.- what
Character vector; which summaries to compute. Subset of
c("Sigma", "R", "communality", "ICC", "cross_corr"). Default: all."ICC"only makes sense at the site level and requires bothBandWtiers in the fit."cross_corr"bootstraps the aggregatemultiple_rbetween amultinomial()trait and each partner (seeextract_cross_correlations()); it is stored as a plain named numeric per tier (multiple_r_B, ...) and is silently skipped for fits without a nominal trait.- conf
Numeric in
(0, 1); confidence level for percentile CIs. Default 0.95.- seed
Optional RNG seed for reproducibility.
- n_cores
Integer; number of cores for parallel refits. Default 1 (sequential).
>= 2usesfuture::multisession.- progress
Logical; print a one-line status message at each replicate (sequential only). Default
TRUE.- keep_draws
Logical; if
TRUE, the fulln_bootx ... matrices of bootstrap draws are returned as$draws. DefaultFALSE(CIs only — saves memory for large n_boot).- link_residual
How to treat family-specific link-implicit residual variance when extracting
Sigma,R,communality, andICC."auto"(default) matchesextract_Sigma()and adds the family/link residual to non-Gaussian trait diagonals;"none"returns the fitted model covariance without link residuals. Use"none"when validating against a DGP target defined as \(\Lambda\Lambda^\top + \Psi\).
Value
A list with components:
point_estNamed list of point estimates for each requested summary at each requested level (e.g.
Sigma_B,R_B,communality_B,ICC_site).ci_lower,ci_upperNamed lists of percentile CI bounds, element-wise the same shape as the corresponding
point_est.n_effectiveNamed list (vector summaries only) giving the per-element count of finite bootstrap draws. For
multiple_r_*entries, any element whose effective count is below 80% ofn_boothas its CI bounds set toNA(minimum-effective-B floor).boot_medianNamed list (
multiple_r_*entries only) of the per-element bootstrap median – a cheap sanity comparator againstpoint_est; a large gap flags gross bootstrap corruption and is not a coverage certifier.ci_methodCharacter; currently
"percentile".link_residualCharacter; the link-residual convention used in point estimates and bootstrap refit summaries.
conf,n_boot,n_failedConfiguration metadata.
drawsNULLunlesskeep_draws = TRUE; otherwise a named list of bootstrap draw arrays.
Details
The function generates n_boot parametric bootstrap replicates of a
fitted model and returns percentile confidence intervals for the
canonical biological summaries: trait covariance matrices
\(\hat\Sigma_\mathrm{unit}\), \(\hat\Sigma_\mathrm{unit\_obs}\);
the corresponding correlation matrices; per-trait communalities
\(c_t^2 = (\Lambda \Lambda^\top)_{tt} / \Sigma_{tt}\); and
per-trait site-level ICCs
\(R_t = (\Sigma_\mathrm{unit})_{tt} /
[(\Sigma_\mathrm{unit})_{tt} + (\Sigma_\mathrm{unit\_obs})_{tt}]\).
Scope: Gaussian bootstrap summaries and mixed-family refit plumbing are covered by current tests. Non-Gaussian bootstrap calibration is experimental: its repeated-sampling behaviour has not been certified, and there is no production calibration evidence for mixed-family intervals. Treat those intervals as indicative.
Each bootstrap replicate (1) draws a new response vector from
simulate(fit, nsim = 1), (2) refits the model with the same formula
on the simulated data, (3) extracts the requested summaries via
extract_Sigma(), extract_communality(), and extract_ICC_site().
Replicates whose refit fails to converge are recorded but excluded
from CI calculation.
Multicore is dispatched via future + future.apply; pass
n_cores >= 2 to enable parallel refits. When parallel, replicates
use future.apply's L'Ecuyer-CMRG seed stream so the answers are
reproducible given a fixed seed, but they are NOT bit-identical to
an n_cores = 1 run with the same seed (different RNG streams).
Caveats
Uses the existing
simulate.gllvmTMB_multi()method. By default that method REDRAWS the random effects from the fitted covariance, which is what makes these intervals span between-unit variability. CIs reflect parametric simulate-refit variability, not a Bayesian posterior distribution for variance components.Intervals are too narrow when the simulator cannot redraw a tier. Redraw is not implemented for every random-effect tier — notably the SPDE spatial tier and the diagonal phylogenetic tier. For a fit using one of those,
simulate.gllvmTMB_multi()falls back to reusing the fitted random-effect modes and emits a one-shot warning. That fallback understates between-unit variability, so the intervals returned here are not calibrated for such fits. Treat the warning as a signal that these intervals cannot be trusted. Unsupported families fall back through the simulator's own warning path.Refits use the same
formulareconstructed fromfit$formulaandfit$covstructs, and forward the fit's auxiliary structure (phylo_vcv,phylo_tree,mesh,lambda_constraint) so each refit matches the original model.Convergence: replicates whose refit fails or whose optimiser does not return
convergence == 0are counted inn_failedand excluded from CIs.
Examples
if (FALSE) { # \dontrun{
set.seed(1)
s <- simulate_site_trait(n_sites = 30, n_species = 1, n_traits = 3,
mean_species_per_site = 1,
Lambda_B = matrix(c(1, .5, -.4), 3, 1),
psi_B = c(.2, .15, .1))
fit <- gllvmTMB(value ~ 0 + trait + latent(0 + trait | site, d = 1),
data = s$data,
trait = "trait",
unit = "site")
boot <- bootstrap_Sigma(fit, n_boot = 50, level = "unit",
what = c("Sigma", "R"), seed = 42)
boot$point_est$Sigma_B
boot$ci_lower$Sigma_B
boot$ci_upper$Sigma_B
} # }