
Warning: pigauto is experimental; use at your own risk. It needs further validation. Point estimates are the supported claim. Prediction intervals are nominal held-out diagnostics, not package-wide certification; covariance routes have focused-test evidence only.
pigauto fills missing species trait values using a phylogenetic tree, other traits, and optional covariates. It supports continuous, count, binary, categorical, ordinal, proportion, zero-inflated-count, and compositional traits.
The workflow below uses functions and defaults from pigauto 0.11.0.
Check packageVersion("pigauto") after installation: the
CRAN release can lag behind the GitHub version described on this
site.
For the released version:
install.packages("pigauto")
packageVersion("pigauto")If CRAN has an earlier version, install the GitHub version to use this workflow:
# install.packages("pak") # once, if needed
pak::pak("itchyshin/pigauto")
# torch::install_torch() # once, if you opt into gnn = TRUEPut a CSV trait table (with a unique species column) and
a Newick or NEXUS tree beside your R script. Then start with this short
workflow:
library(pigauto)
traits <- read_traits("traits.csv")
tree <- read_tree("tree.nwk")
check_pigauto(traits, tree)
result <- impute(traits, tree)
completed <- completed_data(result)
pigauto_report(result)BirdTree distributes its tree files in Newick format. Download one
from BirdTree and read it
with read_tree(); read_tree() also accepts
NEXUS files from other sources. Cite Jetz et al. (2012) for the tree,
and cite BirdTree.org when you use its website. pigauto uses the tree
you provide and does not download BirdTree data automatically. The
bundled tree300 is a teaching example; it is not a
consensus or recommended analysis tree.
impute() now uses the phylogenetic baseline by default
(gnn = FALSE), estimates Pagel’s lambda for eligible
traits, and leaves the mean safety floor and phylogenetic-signal gate
off. To train the optional graph neural network, install the torch
runtime once and call impute(traits, tree, gnn = TRUE). The
former GNN-on behaviour is an explicit choice in 0.11.0.
check_pigauto() and completed_data() were
added in 0.11.0. If your installed version is 0.10.0, call
impute(traits, tree) directly; that version does not
include check_pigauto().
check_pigauto() runs before fitting: it reports input
errors, species/tree matching, trait declarations, and estimated size.
Its default gnn = FALSE matches impute() and
does not probe torch. Pass gnn = TRUE when planning a GNN
fit to include runtime availability. Resolve an "error"
status before fitting; a fully observed target table does not need
imputation, so use cross_validate() instead.
The output roles are deliberately separate:
completed is the input-shaped trait data with observed
values retained and modeled missing cells filled.result$prediction contains all-cell diagnostic
predictions, not a second completed dataset.result$prediction$se is type-dependent uncertainty;
discrete values are not Gaussian standard errors. Conformal bounds are
nominal held-out diagnostics.pigauto_result does not itself authorize downstream
inference. The supported pooling entries begin with
multi_impute_analysis() in its documented narrow regime or,
for continuous traits,
multi_impute(draws_method = "posterior").
multi_impute()’s default,
draws_method = "auto", picks "posterior"
whenever the data allow it and otherwise says why it fell back to
non-poolable conformal draws.Tiny installed example inputs are available at
system.file("extdata", "novice_traits.csv", package = "pigauto")
and
system.file("extdata", "novice_tree.nwk", package = "pigauto").
The matching installed six-expression script is
system.file("examples", "novice-workflow.R", package = "pigauto").
Use an ordered factor when states have a known order.
traits$threat_status <- ordered(
traits$threat_status,
levels = c("LC", "NT", "VU", "EN", "CR")
)
result <- impute(traits, tree)An integer column is otherwise read as a count. Declare a measurement stored as whole numbers explicitly.
result <- impute(
traits, tree,
trait_types = c(body_length_mm = "continuous")
)Declare proportions only when their numeric 0–1 scale is semantically
a proportion. Declare zi_count only when zero is a separate
process from the positive count magnitude.
result <- impute(
traits, tree,
trait_types = c(habitat_cover = "proportion", parasite_load = "zi_count")
)Each declared composition is one trait: every row must have all components or all components missing, and observed rows must sum to one.
result <- impute(
traits, tree,
multi_proportion_groups = list(diet = c("diet_insect", "diet_fruit", "diet_seed"))
)read_traits() requires unique species names. For
repeated observations, read the CSV directly and supply
species_col.
traits_obs <- read.csv("traits_repeated.csv", stringsAsFactors = FALSE)
check_pigauto(traits_obs, tree, species_col = "species")
result <- impute(traits_obs, tree, species_col = "species")Inspect the structured species report before changing data:
check <- check_pigauto(traits, tree)
check$species$matched
check$species$data_only
check$species$tree_onlydata_only rows remain in completed but are
not modeled or filled. tree_only tips are internal
all-missing rows used only while fitting.
impute(traits, tree) with its defaults is the starting
point. The table says which route to take for each need; reach for
another route only for the need in the left-hand column.
| You want | Use | Default? |
|---|---|---|
| Filled-in traits | impute(traits, tree) |
Yes |
| Uncertainty for one imputed value | the per-cell conformal interval in
result$prediction |
Yes |
| A linear downstream analysis of imputed continuous traits on their imputation scale | multi_impute(traits, tree), then
with_imputations() and pool_mi() |
Yes, when every trait is continuous, with one row per species and no
covariates: the default draws_method = "auto" then uses
posterior draws |
One incomplete covariate in lm, binomial-logit
glm, or Gaussian random-intercept lmer |
multi_impute_analysis() |
No |
For other data, draws_method = "auto" falls back to
"conformal" draws and says so. Those draws, like
"mc_dropout", describe the spread of plausible values but
are not proper multiple imputations: in a simulation of a phylogenetic
regression they biased the pooled slope towards zero, and
with_imputations() refuses them. Bayesian downstream fits
(brms, MCMCglmm) are combined by stacking posterior draws, for example
with brms::brm_multiple(), not with pool_mi().
Worked examples for nlme, lme4, glmmTMB, drmTMB, gllvmTMB and brms are
in the multiple
imputation article. The ability to fit and extract coefficients from
a model class does not by itself validate the imputation model for that
analysis; check the article’s conditions before interpreting pooled
estimates.
The default journey above is the supported starting point. These controls are for an explicit technical workflow and are kept separate from it.
# Solver, EM, and refinement controls
result <- impute(
traits, tree,
joint_solver = "rphylopars",
em_iterations = 2L,
joint_refine_iter = 1L,
conformal_split_val = TRUE
)
# Prediction route: the default "auto" chooses per trait between the
# cross-trait "exact" conditional and "per_column"; force one with
result <- impute(traits, tree, predict_method = "exact")See ?impute, ?fit_baseline, and the
articles for all calibration, refinement, and prediction controls.
Nakagawa S (2026). pigauto: Phylogenetic Imputation via Graph Autoencoder.