Skip to contents

Returns imputed trait values on the original scale for data used to fit the model. Supports continuous, binary, categorical, ordinal, count, proportion, zero-inflated count, and multi-proportion traits.

Multiple draws are diagnostic only. With n_imputations > 1, returned draws are not supported for downstream inference. For multi-proportion traits, pooled point values and simplex probabilities are omitted; use a single-run prediction when you need the simplex output.

Usage

# S3 method for class 'pigauto_fit'
predict(
  object,
  newdata = NULL,
  return_se = TRUE,
  n_imputations = 1L,
  baseline_override = NULL,
  pool_method = c("median", "mean", "mode"),
  clamp_outliers = FALSE,
  clamp_factor = 5,
  match_observed = c("none", "pmm"),
  pmm_K = 5L,
  evaluation = FALSE,
  ...
)

# S3 method for class 'pigauto_pred'
print(x, ...)

Arguments

object

object of class "pigauto_fit".

newdata

Must be NULL: predictions use the fitted data. Any non-NULL value is rejected; new-species prediction is not implemented.

return_se

logical. Return type-dependent uncertainty summaries? Default TRUE; see the se return description below.

n_imputations

integer. Number of stochastic prediction-diagnostic draws (default 1L). With multiple draws, independent Gaussian perturbations are added per latent cell using the selected baseline SD; cells with zero selected baseline SD receive no perturbation. GNN dropout also varies across runs when the GNN is enabled. These are not joint phylogenetic BM posterior draws or validated analysis-aware imputations.

baseline_override

optional list(mu, se) with the same shape as object$baseline. When supplied, predictions use this baseline instead of the one saved in the fit. Used internally by multi_impute_trees() to reuse a trained GNN across posterior trees. Most users can ignore this. Default NULL (use the fit's own baseline).

pool_method

character. One of "median" (default), "mean", or "mode". Controls pooling when n_imputations > 1; see "Pooling decoded draws" below. Some types use the same rule for every setting.

clamp_outliers

logical. When TRUE, cap back-transformed predictions for log-transformed continuous, count, and zi_count magnitude traits at tm$obs_max * clamp_factor, where tm$obs_max is the observed maximum on the original scale, recorded during preprocessing. This optional cap limits extrapolation after exp() or expm1(); it is not an uncertainty bound. Default FALSE leaves these predictions uncapped.

clamp_factor

numeric scalar (>= 1). User-selected multiplier of the observed maximum for the upper cap when clamping is enabled. Default 5. Ignored when clamp_outliers = FALSE.

match_observed

character, one of c("none", "pmm"). When "pmm", uses predictive Mean Matching (Little 1988; see References) on the at-risk types (log-transformed continuous, count, zi_count magnitude, proportion). For each missing cell, finds the pmm_K observed 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 mc_dropout prediction-diagnostic 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.

Donor matching can reduce extrapolation but also replaces accurate predictions with donor values, so it is not a general RMSE improvement.

Discrete-class types (binary / categorical / ordinal / multi_proportion) and un-log continuous: no-op. Default "none" leaves predictions unmatched.

pmm_K

integer scalar (>= 1). Donor pool size for PMM. Default 5L (mice convention). Ignored when match_observed = "none".

evaluation

Logical. Use TRUE to predict validation and test cells using the fit's held-out baseline and masked input context. Requires stored splits and newdata = NULL. Default FALSE uses all observed data for production imputation. Use evaluation = TRUE before passing predictions to evaluate_imputation.

...

Internal compatibility arguments. Unrecognised arguments are an error, including misspelled argument names.

x

A pigauto prediction object.

Value

A list of class "pigauto_pred" with:

imputed

data.frame of model predictions for every fitted row (observed and missing cells), on the original scale with proper R types (numeric, integer, factor, ordered). Observed values are not retained in this component. Use impute() and its $completed component for a data.frame that preserves observed values and fills missing cells when predictions are available.

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 $se means per trait type" section below. Single-run and multi-draw constructions differ. These are diagnostic summaries, not calibrated total predictive SDs or valid inputs to downstream pooling. NULL if return_se = FALSE.

se_latent

Numeric matrix on the latent scale, with one column per latent trait column. Returned when return_se = TRUE for current trait-map fits; otherwise NULL. Binary and categorical entries are NA; for zi_count, only the magnitude column has a summary.

probabilities

Named list. Binary traits: numeric probability vector; categorical traits: n x K class-probability matrix; zi_count traits: probability of nonzero. A single-run multi_proportion prediction includes its n x K simplex matrix. Compositional entries are absent from pooled multi-draw output.

conformal_lower, conformal_upper

Matrices of lower and upper conformal limits when the fitted model has conformal scores. Values are on the original trait scale except for ordinal traits, whose bounds are rounded zero-based indices. The lower limit is floored at 0 and the upper limit capped at K - 1; these one-sided limits do not guarantee both endpoints are in range or that the interval is non-empty. Check bounds before mapping an index to a label using the corresponding ordered factor levels (index + 1 in R). Entries can be NA for unsupported traits or unavailable scores; both are NULL when scores are absent.

conformal_scores

Named numeric vector of the scores stored in the fitted model, or NULL when the fit has no scores.

imputed_datasets

List of M stochastic prediction data.frames when n_imputations > 1; NULL otherwise. 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.

evaluation_safe_idx

Latent indices excluded from fitting and prediction input, used to check held-out scoring.

The print method returns x invisibly.

Details

With n_imputations > 1, predictions include stochastic diagnostic draws, not joint phylogenetic BM posterior draws. On each run, independent Gaussian perturbations are added per latent cell to the selected baseline component, scaled by that component's standard deviation (the second parameter in N(mu, sd) is an SD, not a variance). A route that supplies zero uncertainty placeholders adds no Gaussian perturbation for those cells; a zero placeholder does not indicate certainty. When the GNN is enabled, dropout also varies across runs. Because predictions use the phylogenetic graph, predictions across species need not be independent. The calibrated latent prediction combines the selected baseline, GNN prediction and optional mean baseline using their calibrated weights; an applicable direct covariate contribution is then added. In stochastic runs the selected baseline term uses its perturbed value. A zero GNN weight removes only the neural contribution. The output equals the baseline draw only when the baseline weight is one and every other contribution is absent. Point predictions and these stochastic diagnostic draws are distinct outputs. Point estimates follow the type-specific "Pooling decoded draws" table below. 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.

gnn = FALSE fits (traditional-stats mode): when the fit was produced with gnn = FALSE, no GNN was ever trained, so this function makes no torch:: calls at all – prediction is the calibrated baseline blend r_cal_bm * baseline + r_cal_mean * mean_baseline_per_col (r_cal_gnn is always zero) computed on plain R matrices. Two baselines are available: in production mode (the default, evaluation = FALSE) predictions use baseline_full – fit with splits = NULL, so every observed cell can inform every other cell; in evaluation mode (evaluation = TRUE) predictions use the held-out baseline instead, so scored cells never see their own value. n_imputations > 1 adds independent Gaussian perturbations per latent cell, scaled by the selected baseline standard deviation. Cells with zero selected baseline SD receive no Gaussian perturbation. These are stochastic prediction diagnostics, not joint phylogenetic BM posterior draws. The gnn = FALSE path has no GNN-dropout contribution.

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. These are stratum-specific intervals; the far-stratum score is not necessarily larger than the near-stratum score. 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.

Pooling decoded draws

These rules apply to n_imputations > 1, on the decoded scale.

Typemedianmeanmode
continuous, unloggedmeanmeanmean
continuous, loggedmedianmedianmedian
count / proportion / zi_countmedianmeanmedian
ordinalrounded mean class indexrounded mean class indexmodal class
binarymean probability, then threshold 0.5samesame
categoricalmean class-probability vector, then argmaxsamesame
multi_proportionpooled output unavailableunavailableunavailable
Counts and zi_count values are rounded and clipped to nonnegative integers; the zi_count nonzero probability is always averaged separately. Single-run compositional output is a simplex vector; its pooled MC-dropout counterpart is not populated, although individual decoded compositions are returned in imputed_datasets. Do not interpret this omission as simplex averaging.

What $se means per trait type

For fits with a trait_map, pred$se is an n x n_original_traits matrix of type-dependent diagnostic summaries. Its construction also depends on n_imputations. It is not a uniformly Gaussian standard error, a calibrated total predictive SD, or an input to Rubin pooling.

TypeSingle runMore than one draw
continuous / count / ordinal / proportionSelected-baseline latent uncertainty scaled to the original scale, using delta-method back-transformation where applicable.Square root of transformed baseline variance plus the between-decoded-draw variance. Logged continuous, count, and proportion transformations use the first latent run as their anchor.
binarymin(p, 1-p)The same score using the probability averaged across draws.
categorical1 - max(p_k)The same score using the class-probability vector averaged across draws.
zi_countA delta-method product summary for P(nonzero) * E[count | nonzero], combining gate and magnitude terms.Between-draw SD of decoded expected counts, without an additional baseline-variance term.
multi_proportionNANA

For a BM Gaussian baseline, the single-run continuous-family source is a model-dependent BM/joint conditional SD. It is not total final blended-prediction uncertainty: it describes uncertainty under the selected baseline, not prediction error in the final baseline–GNN blend. Other route summaries do not inherit that interpretation automatically. Discrete scores measure distance from a certain class prediction, not a Gaussian SE. For compositions, inspect the separate CLR latent summary in se_latent. The multi-draw construction can contain baseline-draw variation with gnn = FALSE; it should not generally be described as an MC-dropout SE.

Older saved fits without a trait_map use a separate continuous-only legacy prediction path and are not described by this table. For supported downstream multiple-imputation routes, consult multi_impute_analysis or multi_impute with draws_method = "posterior", then use with_imputations and pool_mi under their documented eligibility conditions.

Printing

Prints dimensions, trait types, draw count and available probability/bounds components. Component presence does not establish interval coverage. The ... argument is currently unused.

References

Little RJA (1988). "Missing-Data Adjustments in Large Surveys." Journal of Business & Economic Statistics 6(3): 287-296. doi:10.1080/07350015.1988.10509663 . This is a source for predictive mean matching, not validation of pigauto's implementation.

van Buuren S, Groothuis-Oudshoorn K (2011). "mice: Multivariate Imputation by Chained Equations in R." Journal of Statistical Software 45(3), 1-67. doi:10.18637/jss.v045.i03 . The official mice PMM documentation describes that software's method; it does not validate pigauto's PMM.

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)
#> Warning: Small validation set for 1 trait(s): Wing.Length (n=3). Calibrated gate and conformal scores will be noisy for these trait(s). 95% split-conformal coverage is NOT achievable for 1 trait(s) with fewer than 19 validation cells (Wing.Length (n=3)): the achievable ceiling is n_val / (n_val + 1), which only reaches 0.95 at n_val >= 19. See `?fit_pigauto` under 'Calibration at small n' for smoothing options.
pred <- predict(fit, return_se = TRUE)
pred$imputed
#>                               Mass Wing.Length
#> Nothoprocta_pentlandii       300.7       148.2
#> Eudromia_formosa             772.9       223.9
#> Rhea_americana             23000.0       604.5
#> Ptilopachus_petrosus         193.0       117.2
#> Bambusicola_fytchii          313.7       142.8
#> Francolinus_psilolaemus      478.3       167.3
#> Meleagris_ocellata          5525.0       362.5
#> Dendragapus_obscurus        1047.3       226.5
#> Tympanuchus_phasianellus     882.4       200.6
#> Tragopan_temminckii         1163.4       236.8
#> Arborophila_campbelli        336.0       129.5
#> Megapodius_nicobariensis     836.7       226.8
#> Dendrocygna_guttata          800.0       206.6
#> Chloephaga_rubidiceps       2086.0       325.6
#> Somateria_spectabilis       1616.7       266.3
#> Rhynochetos_jubatus          860.0       264.3
#> Caprimulgus_longirostris      45.6       151.6
#> Caprimulgus_saturatus         52.0       144.5
#> Aegotheles_cristatus          42.8       135.8
#> Lampornis_clemenciae           7.6        73.7
#> Lampornis_calolaemus           5.1        62.6
#> Stellula_calliope              2.6        41.4
#> Hylocharis_sapphirina          4.4        49.5
#> Hylocharis_chrysura            4.5        51.8
#> Amazilia_cyanifrons            5.0        55.6
#> Campylopterus_phainopeplus     7.7        68.1
#> Metallura_iracunda             3.9        58.1
#> Anthracothorax_viridis         6.6        62.8
#> Polytmus_theresiae             3.8        56.6
#> Phaethornis_striigularis       3.0        39.1
pred$se
#>                            Mass Wing.Length
#> Nothoprocta_pentlandii        0           0
#> Eudromia_formosa              0           0
#> Rhea_americana                0           0
#> Ptilopachus_petrosus          0           0
#> Bambusicola_fytchii           0           0
#> Francolinus_psilolaemus       0           0
#> Meleagris_ocellata            0           0
#> Dendragapus_obscurus          0           0
#> Tympanuchus_phasianellus      0           0
#> Tragopan_temminckii           0           0
#> Arborophila_campbelli         0           0
#> Megapodius_nicobariensis      0           0
#> Dendrocygna_guttata           0           0
#> Chloephaga_rubidiceps         0           0
#> Somateria_spectabilis         0           0
#> Rhynochetos_jubatus           0           0
#> Caprimulgus_longirostris      0           0
#> Caprimulgus_saturatus         0           0
#> Aegotheles_cristatus          0           0
#> Lampornis_clemenciae          0           0
#> Lampornis_calolaemus          0           0
#> Stellula_calliope             0           0
#> Hylocharis_sapphirina         0           0
#> Hylocharis_chrysura           0           0
#> Amazilia_cyanifrons           0           0
#> Campylopterus_phainopeplus    0           0
#> Metallura_iracunda            0           0
#> Anthracothorax_viridis        0           0
#> Polytmus_theresiae            0           0
#> Phaethornis_striigularis      0           0
pred$probabilities
#> list()
pred2 <- predict(fit, n_imputations = 2L)
pred2$imputed_datasets
#> [[1]]
#>                               Mass Wing.Length
#> Nothoprocta_pentlandii       300.7       148.2
#> Eudromia_formosa             772.9       223.9
#> Rhea_americana             23000.0       604.5
#> Ptilopachus_petrosus         193.0       117.2
#> Bambusicola_fytchii          313.7       142.8
#> Francolinus_psilolaemus      478.3       167.3
#> Meleagris_ocellata          5525.0       362.5
#> Dendragapus_obscurus        1047.3       226.5
#> Tympanuchus_phasianellus     882.4       200.6
#> Tragopan_temminckii         1163.4       236.8
#> Arborophila_campbelli        336.0       129.5
#> Megapodius_nicobariensis     836.7       226.8
#> Dendrocygna_guttata          800.0       206.6
#> Chloephaga_rubidiceps       2086.0       325.6
#> Somateria_spectabilis       1616.7       266.3
#> Rhynochetos_jubatus          860.0       264.3
#> Caprimulgus_longirostris      45.6       151.6
#> Caprimulgus_saturatus         52.0       144.5
#> Aegotheles_cristatus          42.8       135.8
#> Lampornis_clemenciae           7.6        73.7
#> Lampornis_calolaemus           5.1        62.6
#> Stellula_calliope              2.6        41.4
#> Hylocharis_sapphirina          4.4        49.5
#> Hylocharis_chrysura            4.5        51.8
#> Amazilia_cyanifrons            5.0        55.6
#> Campylopterus_phainopeplus     7.7        68.1
#> Metallura_iracunda             3.9        58.1
#> Anthracothorax_viridis         6.6        62.8
#> Polytmus_theresiae             3.8        56.6
#> Phaethornis_striigularis       3.0        39.1
#> 
#> [[2]]
#>                               Mass Wing.Length
#> Nothoprocta_pentlandii       300.7       148.2
#> Eudromia_formosa             772.9       223.9
#> Rhea_americana             23000.0       604.5
#> Ptilopachus_petrosus         193.0       117.2
#> Bambusicola_fytchii          313.7       142.8
#> Francolinus_psilolaemus      478.3       167.3
#> Meleagris_ocellata          5525.0       362.5
#> Dendragapus_obscurus        1047.3       226.5
#> Tympanuchus_phasianellus     882.4       200.6
#> Tragopan_temminckii         1163.4       236.8
#> Arborophila_campbelli        336.0       129.5
#> Megapodius_nicobariensis     836.7       226.8
#> Dendrocygna_guttata          800.0       206.6
#> Chloephaga_rubidiceps       2086.0       325.6
#> Somateria_spectabilis       1616.7       266.3
#> Rhynochetos_jubatus          860.0       264.3
#> Caprimulgus_longirostris      45.6       151.6
#> Caprimulgus_saturatus         52.0       144.5
#> Aegotheles_cristatus          42.8       135.8
#> Lampornis_clemenciae           7.6        73.7
#> Lampornis_calolaemus           5.1        62.6
#> Stellula_calliope              2.6        41.4
#> Hylocharis_sapphirina          4.4        49.5
#> Hylocharis_chrysura            4.5        51.8
#> Amazilia_cyanifrons            5.0        55.6
#> Campylopterus_phainopeplus     7.7        68.1
#> Metallura_iracunda             3.9        58.1
#> Anthracothorax_viridis         6.6        62.8
#> Polytmus_theresiae             3.8        56.6
#> Phaethornis_striigularis       3.0        39.1
#> 
# }