
Impute missing traits using a fitted pigauto model
Source:R/predict_pigauto.R
predict.pigauto_fit.RdRuns a single forward pass through the fitted model and returns imputed
trait values back-transformed to the original scale. Supports all
trait types (continuous, binary, categorical, ordinal, count, proportion,
zero-inflated count, multi-proportion)
and MC dropout for stochastic prediction diagnostics (when
n_imputations > 1). The fitted model is a gated ensemble
of a phylogenetic baseline and a graph neural network correction;
prediction is the per-trait blend
(1 - r_cal) * baseline + r_cal * delta_GNN.
Arguments
- object
object of class
"pigauto_fit".- newdata
NULL(use the training data) or a"pigauto_data"object for new species.- return_se
logical. Compute standard errors? (default
TRUE).- n_imputations
integer. Number of stochastic imputation draws — BM posterior samples plus GNN dropout — (default
1L). Set to e.g. 10 or 20 to inspect stochastic prediction variation. These are not validated analysis-aware multiple imputations.- baseline_override
optional
list(mu, se)with the same shape asobject$baseline. When supplied, predictions use this baseline instead of the one saved in the fit. Used internally bymulti_impute_trees()to reuse a trained GNN across posterior trees. Most users can ignore this. DefaultNULL(use the fit's own baseline).- pool_method
character. How to pool the M decoded draws when
n_imputations > 1:"median"(default) takes the per-cell median for count / proportion / zi_count magnitude traits — robust to single dropout-noisy draws amplified by non-linear decoders (expm1/plogis)."mean"restores the pre-v0.9.2 arithmetic-mean pooling. Continuous / ordinal / binary / categorical pooling is unchanged (linear / probability-averaged). See issue #40.- clamp_outliers
logical. Phase G (v0.9.1.9011+). When
TRUE, post-back-transform predictions for log-transformed continuous, count, and zi_count magnitude traits are capped attm$obs_max * clamp_factor(tm$obs_maxis the observed maximum on the original scale, set at preprocess time). Targets tail-extrapolation modes amplified byexp()/expm1()back-transforms. DefaultFALSEpreserves v0.9.1 behaviour exactly.- clamp_factor
numeric scalar (>= 1). Multiplicative factor on the observed maximum used by
clamp_outliers. Default5. Ignored whenclamp_outliers = FALSE.- match_observed
character, one of
c("none", "pmm"). Phase G' (v0.9.1.9012+). When"pmm", uses Predictive Mean Matching (Little 1988; Buuren mice) on the at-risk types (log-transformed continuous, count, zi_count magnitude, proportion). For each missing cell, finds thepmm_Kobserved cells whose own predictions are closest to the missing cell's prediction, samples one, and returns its observed value. Imputed values are guaranteed to lie in the observed data range – no extrapolation is possible by construction.When to use: PMM is a niche feature in pigauto. The package already provides conformal prediction intervals (calibrated against held-out residuals) and stochastic conformal-width and Brownian/MC-dropout prediction draws. PMM is only worth enabling for: (a) methodological comparison against mice / equivalent packages, or (b) workflows that specifically require imputed values to come from the observed data pool. For tail safety on single-imputation point estimates, prefer
clamp_outliers = TRUE. PMM failed the downstream fixed-effect redesign pilot and is unsupported for inference.The Phase G' acceptance bench (
useful/MEMO_2026-05-01_phase_g_prime_results.md) confirmed PMM does not strictly improve point-estimate RMSE over the no-PMM default: it wins on extrapolating cells (e.g. AVONET Casuarius) but loses on cells where the GNN's prediction is already accurate (donor-mismatch noise).Discrete-class types (binary / categorical / ordinal / multi_proportion) and un-log continuous: no-op. Default
"none"preserves v0.9.1.9011 behaviour exactly.- pmm_K
integer scalar (>= 1). Donor pool size for PMM. Default
5L(mice convention). Ignored whenmatch_observed = "none".- ...
ignored.
Value
A list of class "pigauto_pred" with:
- imputed
data.frame of imputed values in original scale with proper R types (numeric, integer, factor, ordered).
- imputed_latent
Numeric matrix (n x p_latent) of predictions in latent scale.
- se
Numeric matrix (n x n_original_traits) of per-cell uncertainty. See the "What
$semeans per trait type" section below for what each trait type's column actually contains.NULLifreturn_se = FALSE.- probabilities
Named list. Binary traits: numeric probability vector. Categorical traits: n x K probability matrix. Other types: not present.
- imputed_datasets
List of M stochastic prediction data.frames when
n_imputations > 1;NULLotherwise. Not supported for downstream inference.- trait_map
Trait map from the fitted model.
- species_names
Character vector.
- trait_names
Character vector.
- n_imputations
Integer, number of imputations performed.
Details
When n_imputations > 1, each imputation m draws a BM
posterior sample t_BM_draw ~ N(BM_mu, BM_se) on the latent scale
for originally-missing cells (BM_se = 0 for observed cells so they
are never perturbed). The model runs in train mode (GNN dropout active)
using t_BM_draw as input. The final blend is
(1 - r_cal) * t_BM_draw + r_cal * GNN_delta(t_BM_draw): when the
calibrated gate is zero the imputation is a pure BM posterior draw; when
r_cal > 0 both BM draws and GNN dropout contribute variance. Point
estimates are the mean (continuous, count) or mode (binary, categorical,
ordinal) across passes. The M complete datasets are returned in
imputed_datasets for prediction diagnostics. These datasets are not
supported for downstream inference. Use multi_impute_analysis() for
the narrow analysis-aware backend after consulting its supported-model and
lifecycle documentation.
Decoding per type:
- continuous
reverse z-score, then
exp()if log-transformed- binary
sigmoid(latent)to probability, round to 0/1- count
reverse z-score of log1p,
expm1(), round, clip >= 0- ordinal
reverse z-score, round to nearest valid integer level
- categorical
softmax()over K latent columns, argmax
Conformal intervals: conformal_lower / conformal_upper
use whatever conformal_method the fit was trained with
(fit_pigauto). For "mondrian", the half-width is not
constant across rows: each target cell's phylogenetic locality (mean
cophenetic distance to its 5 nearest training-observed species for that
trait) picks the near- or far-stratum score stored on the fit, so
predictions in undersampled clades get wider intervals. See
fit_pigauto's conformal_method argument for details.
zi_count conformal intervals are conditional on non-zero.
conformal_lower[, nm] / conformal_upper[, nm] for a
zi_count trait back-transform the magnitude latent (log1p-z of the
count given it is non-zero) plus/minus the conformal half-width
that was calibrated on that same magnitude column
(fit_pigauto's compute_conformal_scores() scores
zi_count on latent_cols[2], never on the decoded E[X]).
They are not an interval for the expected value
E[X] = P(nonzero) * E[count | nonzero] – constructing a naive
\(\pm\)quantile interval directly on E[X] would conflate gate
and magnitude uncertainty into one number with no valid coverage
interpretation. The gate probability P(nonzero) is available
separately in pred$probabilities[[nm]]; combine it with the
conditional interval yourself if you need an E[X]-scale bound.
What $se means per trait type
pred$se is a single n x n_original_traits matrix, but its
per-column meaning differs by trait type — do not treat every column as
a Gaussian standard error. This table is the definitive reference; other
pigauto documentation (e.g. impute's return value) points
here instead of repeating it.
| Type | Value | Is it a Gaussian SE? |
| continuous / count / ordinal / proportion | BM conditional SD, delta-method back-transformed to original scale | Yes — safe for interval arithmetic. |
| binary | min(p, 1-p) | No. Probability of being wrong (0 = certain, 0.5 = maximally uncertain). |
| categorical | 1 - max(p_k) | No. Margin from certainty (0 = certain, (K-1)/K = maximally uncertain). |
| zi_count | delta-method SE of E[X] = P(nonzero) * E[count | nonzero] | No. Mixes gate and magnitude uncertainty into one number; not a magnitude-scale SE. Use conformal_lower / conformal_upper (conditional-on-nonzero; see above) plus probabilities (the gate) for interval-scale zi_count uncertainty instead. |
| multi_proportion | NA | Not computed; use the CLR latent SE (se_latent) instead. |
These families are incompatible objects sharing one column name:
only the continuous-family entries are standard errors in the Gaussian
sense, and none of the binary / categorical / zi_count entries
may be used in Rubin's-rules arithmetic. For valid downstream
multiple-imputation inference use multi_impute +
with_imputations + pool_mi.
Examples
# \donttest{
data(avonet300, tree300)
tree <- ape::keep.tip(tree300, tree300$tip.label[seq_len(30L)])
traits <- avonet300[match(tree$tip.label, avonet300$Species_Key),
c("Mass", "Wing.Length"), drop = FALSE]
rownames(traits) <- tree$tip.label
data <- preprocess_traits(traits, tree)
splits <- make_missing_splits(data$X_scaled, trait_map = data$trait_map)
fit <- fit_pigauto(data, tree, splits = splits, epochs = 5L,
verbose = FALSE)
#> Error: Lantern is not loaded. Please use `install_torch()` to install additional dependencies.
pred <- predict(fit, return_se = TRUE)
#> Error: object 'fit' not found
pred$imputed
#> Error: object 'pred' not found
pred$se
#> Error: object 'pred' not found
pred$probabilities
#> Error: object 'pred' not found
pred2 <- predict(fit, n_imputations = 2L)
#> Error: object 'fit' not found
pred2$imputed_datasets
#> Error: object 'pred2' not found
# }