| predict.sdmTMB | R Documentation |
Make predictions from a model fitted with sdmTMB(), either for the fitted
data or for new data (e.g., a prediction grid). At new locations, the random
fields are interpolated from their estimated values at the mesh vertices.
Besides the overall prediction (est), the output separates the linear
predictor into the contribution of the spatial and spatiotemporal random
fields and everything else (see Value).
## S3 method for class 'sdmTMB'
predict(
object,
newdata = NULL,
type = c("link", "response"),
se_fit = FALSE,
re_form = NULL,
re_form_iid = NULL,
allow_new_levels = NULL,
nsim = 0,
sims_var = "est",
sample_fe = TRUE,
model = c(NA, 1, 2),
offset = NULL,
mcmc_samples = NULL,
nonlocal_newdata = NULL,
return_tmb_object = deprecated(),
return_tmb_report = FALSE,
return_tmb_data = FALSE,
...
)
object |
A model fitted with |
newdata |
A data frame to predict on. If |
type |
The scale of |
se_fit |
Logical: calculate standard errors of |
re_form |
Include the spatial and spatiotemporal random fields
(including spatially varying coefficient fields)? |
re_form_iid |
Include the IID random intercepts and slopes (e.g.,
|
allow_new_levels |
Allow levels of random effect grouping factors in
|
nsim |
Number of draws. If |
sims_var |
Which quantity to return when |
sample_fe |
Logical. When |
model |
For delta models, what |
offset |
A numeric vector of offset values, one per row of |
mcmc_samples |
A matrix of posterior samples from a model passed to
tmbstan (see |
nonlocal_newdata |
An optional data frame of the |
return_tmb_object |
|
return_tmb_report |
Logical: return the TMB report (a list of all
reported quantities at the estimated parameters) instead of a data frame?
With |
return_tmb_data |
Logical: return the data list passed to TMB instead of predicting? Used internally. |
... |
Unused. |
By default, newdata (or the fitted data) with these columns added:
est: The prediction on the scale set by type.
est_se: The standard error of est on the link scale, if
se_fit = TRUE.
est_non_rf: The linear predictor excluding the spatial and
spatiotemporal random fields: fixed effects, smoothers, IID random
effects, time-varying coefficients, and the offset.
est_rf: The sum of all random field terms, including spatially varying
coefficient fields multiplied by their covariates. On the link scale,
est_non_rf + est_rf equals est.
omega_s: The spatial random field.
zeta_s_<x>: The spatially varying coefficient field for covariate <x>
in spatial_varying: the local deviation from the average coefficient,
not multiplied by the covariate.
epsilon_st: The spatiotemporal random field.
nl_*: The transformed covariate values for each nonlocal_formula
term.
Columns for terms not in the model are left out, as are the random field
columns with re_form = NA.
Delta models instead return each column (other than est and est_se)
per component, with suffixes 1 and 2 for the first and second
components (e.g., est1, est2, omega_s1, omega_s2). The identity
above then holds within each component, and est combines the components
(or gives one of them; see model).
If nsim > 0 or mcmc_samples is supplied: a matrix with one row per row
of newdata (or the fitted data) and one column per draw. Row names are
the time values.
If return_tmb_object = TRUE (deprecated): a list with elements data
(the data frame above), report (the TMB report), obj (the TMB object
from the prediction), and fit_obj (the fitted model).
d <- pcod_2011
mesh <- make_mesh(d, c("X", "Y"), cutoff = 30) # a coarse mesh for example speed
m <- sdmTMB(
data = d, formula = density ~ 0 + as.factor(year) + depth_scaled + depth_scaled2,
time = "year", mesh = mesh, family = tweedie(link = "log")
)
# Predictions at original data locations -------------------------------
predictions <- predict(m)
head(predictions)
predictions$resids <- residuals(m) # randomized quantile residuals
library(ggplot2)
ggplot(predictions, aes(X, Y, col = resids)) + scale_colour_gradient2() +
geom_point() + facet_wrap(~year)
hist(predictions$resids)
qqnorm(predictions$resids); abline(a = 0, b = 1)
# Predictions on new data ----------------------------------------------
qcs_grid_2011 <- replicate_df(qcs_grid, "year", unique(pcod_2011$year))
predictions <- predict(m, newdata = qcs_grid_2011)
# A short function for plotting predictions:
plot_map <- function(dat, column = est) {
ggplot(dat, aes(X, Y, fill = {{ column }})) +
geom_raster() +
facet_wrap(~year) +
coord_fixed()
}
plot_map(predictions, exp(est)) +
scale_fill_viridis_c(trans = "sqrt") +
ggtitle("Prediction (fixed effects + all random effects)")
plot_map(predictions, exp(est_non_rf)) +
ggtitle("Prediction without random fields (fixed effects only here)") +
scale_fill_viridis_c(trans = "sqrt")
plot_map(predictions, est_rf) +
ggtitle("All random field estimates") +
scale_fill_gradient2()
plot_map(predictions, omega_s) +
ggtitle("Spatial random effects only") +
scale_fill_gradient2()
plot_map(predictions, epsilon_st) +
ggtitle("Spatiotemporal random effects only") +
scale_fill_gradient2()
# Visualizing a marginal effect ----------------------------------------
# See the visreg package or the ggeffects::ggeffect() or
# ggeffects::ggpredict() functions
# To do this manually:
nd <- data.frame(depth_scaled =
seq(min(d$depth_scaled), max(d$depth_scaled), length.out = 100))
nd$depth_scaled2 <- nd$depth_scaled^2
# Because this is a spatiotemporal model, you'll need at least one time
# value. For these population-level predictions, if time isn't also a fixed
# effect, it doesn't matter what you pick:
nd$year <- 2011L # L: integer to match original data
p <- predict(m, newdata = nd, se_fit = TRUE, re_form = NA)
ggplot(p, aes(depth_scaled, exp(est),
ymin = exp(est - 1.96 * est_se), ymax = exp(est + 1.96 * est_se))) +
geom_line() + geom_ribbon(alpha = 0.4)
# Plotting marginal effect of a spline ---------------------------------
m_gam <- sdmTMB(
data = d, formula = density ~ 0 + as.factor(year) + s(depth_scaled, k = 5),
time = "year", mesh = mesh, family = tweedie(link = "log")
)
if (require("visreg", quietly = TRUE)) {
visreg::visreg(m_gam, "depth_scaled")
}
# or manually:
nd <- data.frame(depth_scaled =
seq(min(d$depth_scaled), max(d$depth_scaled), length.out = 100))
nd$year <- 2011L
p <- predict(m_gam, newdata = nd, se_fit = TRUE, re_form = NA)
ggplot(p, aes(depth_scaled, exp(est),
ymin = exp(est - 1.96 * est_se), ymax = exp(est + 1.96 * est_se))) +
geom_line() + geom_ribbon(alpha = 0.4)
# Forecasting ----------------------------------------------------------
mesh <- make_mesh(d, c("X", "Y"), cutoff = 15)
unique(d$year)
m <- sdmTMB(
data = d, formula = density ~ 1,
spatiotemporal = "AR1", # using AR(1) to have something to forecast with
extra_time = 2019L, # `L` for integer to match our data
spatial = "off",
time = "year", mesh = mesh, family = tweedie(link = "log")
)
# Add a year to our grid:
grid2019 <- qcs_grid_2011[qcs_grid_2011$year == max(qcs_grid_2011$year), ]
grid2019$year <- 2019L # `L` because `year` is an integer in the data
qcsgrid_forecast <- rbind(qcs_grid_2011, grid2019)
predictions <- predict(m, newdata = qcsgrid_forecast)
plot_map(predictions, exp(est)) +
scale_fill_viridis_c(trans = "log10")
plot_map(predictions, epsilon_st) +
scale_fill_gradient2()
# Estimating local trends ----------------------------------------------
d <- pcod
d$year_scaled <- as.numeric(scale(d$year))
mesh <- make_mesh(pcod, c("X", "Y"), cutoff = 25)
m <- sdmTMB(data = d, formula = density ~ depth_scaled + depth_scaled2,
mesh = mesh, family = tweedie(link = "log"),
spatial_varying = ~ 0 + year_scaled, time = "year", spatiotemporal = "off")
nd <- replicate_df(qcs_grid, "year", unique(pcod$year))
nd$year_scaled <- (nd$year - mean(d$year)) / sd(d$year)
p <- predict(m, newdata = nd)
plot_map(subset(p, year == 2003), zeta_s_year_scaled) + # pick any year
ggtitle("Spatial slopes") +
scale_fill_gradient2()
plot_map(p, est_rf) +
ggtitle("Random field estimates") +
scale_fill_gradient2()
plot_map(p, exp(est_non_rf)) +
ggtitle("Prediction without random fields (fixed effects only here)") +
scale_fill_viridis_c(trans = "sqrt")
plot_map(p, exp(est)) +
ggtitle("Prediction (fixed effects + all random effects)") +
scale_fill_viridis_c(trans = "sqrt")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.