predict() returns fitted or predicted values for one distributional
parameter of a drmTMB fit.
Arguments
- object
A
drmTMBfit.- newdata
Optional data frame for prediction. If omitted, fitted rows are used. When supplied,
newdatamust include the predictors used by the requesteddpar; required predictor values must be complete, required numeric predictors must be finite, and factor predictors must use fitted levels. Transformed predictor terms, such aslog(size), must also evaluate to finite design-matrix values.- dpar
Distributional parameter to predict. If
NULL, the first fitted distributional parameter is used. Fortype = "quantile"on a bivariatebiv_gaussianfit,dparinstead selects which response's marginal quantile to compute (see Details).- type
Prediction scale:
"response","link","quantile", or"mean"."mean"returns the response meanE[Y]and takes nodpar(see Details).- prob
Numeric vector of probabilities in (0, 1), used only when
type = "quantile".- re.form
Must be
NULL(the default), which is the only behaviour: training rows are predicted conditionally on the fitted random effects andnewdatarows at the population level. Any other value is an error.- ...
Reserved for future prediction options; any value is an error (for example
se.fit, whichpredict()does not compute; usepredict_parameters()withconf.int = TRUEfor standard errors).
Value
A numeric vector for type "response"/"link"/"mean". For
type = "quantile", a numeric matrix with one row per observation and
one column per prob (columns named as percentages, e.g. "2.5%"), with
attr(., "calibrated") == FALSE.
Details
By default, predictions are returned on the distributional parameter's
response scale. For positive scale parameters such as sigma, this means
the exponentiated value. For bivariate residual correlation rho12 or a
fitted corpair() model, this means the correlation scale. Use
type = "link" to return the linear predictor instead.
When newdata = NULL, predictions are for the fitted rows and include
currently implemented conditional random-effect contributions for mu,
including registry-backed q > 2 ordinary covariance blocks, bivariate
mu1/mu2, phylogenetic mu, and residual-scale sigma including
bivariate sigma1/sigma2 blocks. Fitted-row predictions also include
ordinary zero-one-beta zoi and coi random-effect contributions. When
newdata is supplied, predictions are fixed-effect, population-level
predictions for the supplied rows.
type = "quantile" returns per-row conditional quantiles of the fitted
RESPONSE distribution (not of a linear predictor): qnorm-style inverse
CDF evaluation via fitted_distribution()$q() at predict_parameters()'s
fixed-effect, population-level parameter estimates – see
fitted_distribution() for the fixed-effect-only scope and the
"spike"/"unimplemented" status rules this inherits (a "spike"-status
family emits a one-time warning; an unregistered model_type raises a
clear error). For bivariate biv_gaussian fits, dpar selects which
response's MARGINAL quantile to return ("mu1"/"sigma1" for response 1,
"mu2"/"sigma2" for response 2); the joint rho12 correlation, any joint
tail structure, and any known bivariate sampling covariance are ignored –
this is a marginal-only computation, not a joint bivariate quantile. The
result carries attr(., "calibrated") <- FALSE: this is a distributional
(plug-in) interval at the point estimate theta_hat, not a
calibrated-coverage interval, and it does not propagate theta_hat
uncertainty.
For retained training data with a modelled missing predictor, prediction uses that predictor's finalized conditional plug-in in the fixed-effect design. This is a distributional-parameter prediction, not an integrated response mean, and fixed-effect covariance does not propagate imputation-parameter uncertainty through the design basis.
More generally, type = "response" means "on the response scale of the
requested distributional parameter", not always E[Y]. For
zero-inflated and hurdle count families it returns the component count mean
when dpar = "mu", not the unconditional mean after structural-zero or
hurdle mixing. For lognormal fits it returns mu on the log-response scale,
not exp(mu + sigma^2 / 2). For cumulative-logit fits it returns the
location linear predictor on its response scale, not an expected ordinal
score. Use type = "mean" for E[Y].
type = "mean" returns the response mean E[Y] for each row, so it differs
from type = "response" exactly where the two answer different questions:
exp(mu + sigma^2 / 2) for lognormal fits; (1 - zi) * mu for
zero-inflated count fits; the hurdle mean for hurdle fits; and the expected
score sum(k * Pr(y = k)) on the category indices 1:K for
cumulative-logit fits. Truncated and zero-one-beta fits use their own mean
formulas, and families whose mean is mu return mu. With
newdata = NULL it equals fitted.drmTMB(); with newdata it uses the
population-level parameter predictions for the supplied rows. dpar must be
left NULL, and bivariate fits are an error.
Binary predictor labels follow the fitted encoding, regardless of the levels present in the new batch. Numeric new values match raw numeric fitted labels; for nonnumeric fitted labels, numeric 0/1 values specify the encoded states. If distinct labels become identical as numbers (for example, "01" and "1"), supply character or factor values to preserve their identity.
For families in drm_clamped_scale_families(), the log(sigma) linear
predictor is soft-clamped inside the TMB likelihood to keep the objective
finite. predict(dpar = "sigma") (and the bivariate sigma1/sigma2)
reports that same clamped scale, on both type = "link" and
type = "response", so the value matches what the likelihood actually
evaluated. When check_drm() reports the clamp active, this makes the
fit's own diagnostics honest, not correct: the estimate itself is still
unreliable near the clamp (see the rescaling advice there).
For predictor-dependent random-effect SD parameters (for example
dpar = "sd(id)" or "sd_animal(id)"), the value is the SD multiplier
exp(W beta) on the latent effect, not a marginal SD. When the effect is
structured (animal(), relmat(), phylo(), spatial()), the multiplier
applies to the supplied kernel as given, so the marginal SD of group g is
multiplier * sqrt(C_gg); predict() never returns that product. For a
unit-diagonal kernel the two agree. type = "link" is the log SD after the
same soft clamp the likelihood applies (the identity inside [-12, 12],
saturating towards [-15, 15]), not the raw W beta; type = "response"
is its exponential. With newdata = NULL the result has one value per fitted
group, named by group level. With newdata, each row is one group-level row
(not an observation row): the result has one value per row, named by
rownames(newdata), and a structured SD for such a row is a population
multiplier with no kernel node and no sqrt(C_gg) factor.
Examples
dat <- data.frame(
y = c(0.2, 0.5, 1.1, 1.4, 1.8, 2.2),
x = c(-1, -0.5, 0, 0.5, 1, 1.5)
)
fit <- drmTMB(bf(y ~ x, sigma ~ x), data = dat)
#> Warning: `drmTMB()`: the fitted `log(sigma)` spans 21.7 across observations, more than
#> `log(1e4)` = 9.2.
#> ℹ A scale range wider than 10^4 usually means the scale is running off (or the
#> design is extreme), so the reported convergence, estimates and standard
#> errors may be unreliable even when the clamp is not hit. Rescale the
#> response, simplify the `sigma` formula, or use a penalized/MAP fit;
#> `check_drm()` reports the fit state.
predict(fit, dpar = "mu")
#> [1] 0.2 0.6 1.0 1.4 1.8 2.2
predict(fit, dpar = "sigma")
#> [1] 9.103562e+02 6.392210e+00 4.488391e-02 3.151595e-04 2.297952e-06
#> [6] 3.412479e-07
predict(fit, dpar = "sigma", type = "link")
#> [1] 6.813836 1.855080 -3.103676 -8.062432 -12.983492 -14.890657
predict(fit, newdata = data.frame(x = c(0, 1)), dpar = "mu")
#> [1] 1.0 1.8
predict(fit, type = "quantile", prob = c(0.025, 0.5, 0.975))
#> 2.5% 50% 97.5%
#> [1,] -1784.0653817 0.2 1784.465382
#> [2,] -11.9285012 0.6 13.128501
#> [3,] 0.9120292 1.0 1.087971
#> [4,] 1.3993823 1.4 1.400618
#> [5,] 1.7999955 1.8 1.800005
#> [6,] 2.1999993 2.2 2.200001
#> attr(,"calibrated")
#> [1] FALSE
#> attr(,"prob")
#> [1] 0.025 0.500 0.975
#> attr(,"label")
#> [1] "distributional (plug-in) interval"
predict(fit, type = "mean")
#> [1] 0.2 0.6 1.0 1.4 1.8 2.2