Bayesian Augmentation by Chained Equations (BACE) is an R package for imputing missing data in comparative (species-level) datasets using Bayesian chained equations with a phylogenetic random effect. Each per-variable imputation model is a phylogenetic mixed model fit with MCMCglmm, so closely related taxa inform each other's imputations — something general-purpose MI tools (e.g. mice, Amelia) do not do.
BACE handles mixed variable types in a single workflow:
- Continuous (Gaussian)
- Count (Poisson)
- Binary (modelled on the threshold / probit scale)
- Multinomial categorical
- Ordinal (threshold models with ≥ 3 ordered levels)
Variable types are detected automatically from column classes; users can also pass per-variable formulas when they want explicit control over which predictors enter each imputation model.
⚠️ BACE is under active development and the API may still change. It is usable for research workflows today, but please read the vignette carefully and sanity-check both the per-imputation MCMC convergence and the chained-equations convergence before relying on results for publication.
You can install the development version of BACE from GitHub with:
# install.packages("devtools")
devtools::install_github("daniel1noble/BACE")The example below is fully self-contained: sim_bace() simulates a comparative
dataset (two gaussian predictors by default) with missing values and a matching
phylogeny, so you can paste and run it as is — then swap in your own data and tree.
library(BACE)
# Simulate a dataset with 20% missingness in each variable, moderate
# phylogenetic signal, and a phylogeny (returned alongside the data)
set.seed(123)
sim <- sim_bace(
phylo_signal = c(0.6, 0.6, 0.6),
missingness = c(0.2, 0.2, 0.2),
n_cases = 100,
n_species = 100
)
# Full workflow: initial chained imputation -> convergence check -> final
# independent imputations -> pooled posterior.
result <- bace(
fixformula = "y ~ x1 + x2",
ran_phylo_form = "~ 1 | Species",
phylo = sim$tree,
data = sim$data,
runs = 15,
n_final = 10,
nitt = 100000,
burnin = 10000,
thin = 10
)
# Pooled posterior for the analysis model
summary(get_pooled_model(result, "y"))
# Imputed datasets (one per final run) for downstream analyses
imputed_list <- get_imputed_data(result)See ?bace, ?bace_imp, ?bace_final_imp, ?pool_posteriors, ?assess_convergence, ?get_pooled_model and ?get_imputed_data for details.
A full tutorial — including when BACE is appropriate relative to other MI tools, the four-step workflow, interpreting pooled output, and the distinction between within-chain MCMC convergence and chained-equations convergence — is at https://daniel1noble.github.io/BACE/.
- Chained-equations imputation for continuous, count, binary, multinomial and ordinal variables
- Phylogenetic random effect in every per-variable model via
MCMCglmm - Optional decomposition of phylogenetic and non-phylogenetic species effects (
species = TRUE) for datasets with replicated observations per species - Per-variable MCMC settings —
nitt,burnin,thincan be supplied as lists to use different values for different response models - One-vs-rest (OVR) categorical imputation — as an alternative to the default multinomial probit, unordered categorical variables can be modelled as J independent binary threshold models (one per level) via
ovr_categorical = TRUE -
nitt_cat_multparameter — integer multiplier applied tonittandburninfor categorical and ordinal variables only, for cases where harder-to-mix models need longer chains - Gelman / pseudo-Gelman prior options for categorical models to improve mixing, and fully user-settable priors per variable via the
priorsargument - Convergence diagnostics across the chained-equations loop (
assess_convergence()), with summary, Wasserstein and energy-distance methods - Auto-restart of initial imputation when chained-equations convergence is not reached (
bace()withmax_attempts) - Final independent imputations with posterior-predictive sampling (
bace_final_imp()), so each of then_finalimputed datasets is a proper draw rather than a repeated point estimate — continuous variables draw from the posterior predictive via the fixed-effect design matrix, categorical/ordinal variables sample from the posterior probability distribution - Posterior pooling across imputations by stacking per-imputation MCMC chains — a Monte Carlo approximation to the marginal posterior integrating over the imputation distribution; see
?pool_posteriorsfor the references and assumptions - Rubin's-rules pathway —
with_imputations()fits any downstream analysis model to each imputed dataset andpool_mi()combines the estimates with Rubin's rules (Barnard–Rubin small-sample degrees of freedom,fmi/rivdiagnostics; matchesmice::poolto machine precision on identical inputs) - Parallel execution of final imputation runs (
bace_final_imp(n_cores = …)) viaparallel::mclapply - Accessor helpers
get_pooled_model()andget_imputed_data()for extracting pooled models and imputed datasets frombace_complete/bace_pooled/bace_finalobjects - Simulation engine
sim_bace()for generating phylogenetically-structured comparative datasets with arbitrary response types, interaction terms and random slopes — useful for method validation
- Random slopes and more flexible random-effect structures per response variable (accept a list of random-effect formulas so each imputation model can have its own random-effect specification)
- Parallelisation within a single chained-equations iteration (currently only the
n_finalindependent runs are parallelised)
Bug reports, feature requests and worked examples are very welcome at https://github.com/daniel1noble/BACE/issues.
