| Title: | Bayesian Geostatistics Using Predictive Stacking |
|---|---|
| Description: | Fits Bayesian hierarchical spatial and spatial-temporal process models for point-referenced Gaussian, Poisson, binomial, and binary data using stacking of predictive densities. It involves sampling from analytically available posterior distributions conditional upon candidate values of the spatial process parameters and, subsequently assimilate inference from these individual posterior distributions using Bayesian predictive stacking. Our algorithm is highly parallelizable and hence, much faster than traditional Markov chain Monte Carlo algorithms while delivering competitive predictive performance. See Zhang, Tang, and Banerjee (2025) <doi:10.1080/01621459.2025.2566449>, and, Pan, Zhang, Bradley, and Banerjee (2025) <doi:10.1214/25-BA1582> for details. |
| Authors: | Soumyakanti Pan [aut, cre] (ORCID: <https://orcid.org/0009-0005-9889-7112>), Sudipto Banerjee [aut] |
| Maintainer: | Soumyakanti Pan <[email protected]> |
| License: | GPL-3 |
| Version: | 1.1.3.99 |
| Built: | 2026-10-12 23:16:17 UTC |
| Source: | https://github.com/span-18/spstack-dev |
This package delivers functions to fit Bayesian hierarchical spatial process models for point-referenced Gaussian, Poisson, binomial, and binary data using stacking of predictive densities. It involves sampling from analytically available posterior distributions conditional upon some candidate values of the spatial process parameters for both Gaussian response model as well as non-Gaussian responses, and, subsequently assimilate inference from these individual posterior distributions using Bayesian predictive stacking. Our algorithm is highly parallelizable and hence, much faster than traditional Markov chain Monte Carlo algorithms while delivering competitive predictive performance.
In context of inference for spatial point-referenced data, Bayesian hierarchical models involve latent spatial processes characterized by spatial process parameters, which besides lacking substantive relevance in scientific contexts, are also weakly identified and hence, impedes convergence of MCMC algorithms. This motivates us to build methodology that involves fast sampling from posterior distributions conditioned on a grid of the weakly identified model parameters and combine the inference by stacking of predictive densities (Yao et. al 2018). We exploit the Bayesian conjugate linear modeling framework for the Gaussian case (Zhang, Tang and Banerjee 2025) and the generalized conjugate multivariate distribution theory (Pan, Zhang, Bradley and Banerjee 2025) to analytically derive the individual posterior distributions.
| Package: | spStack |
| Type: | Package |
| Version: | 1.1.0 |
| License: | GPL-3 |
Accepts a formula, e.g., y~x1+x2, for most regression models
accompanied by candidate values of spatial process parameters, and returns
posterior samples of the regression coefficients and the latent spatial
random effects. Posterior inference or prediction of any quantity of interest
proceed from these samples. Main functions are - spLMexact()spGLMexact()spLMstack()spGLMstack()
Maintainer: Soumyakanti Pan [email protected] (ORCID)
Authors:
Soumyakanti Pan [email protected] (ORCID)
Sudipto Banerjee [email protected]
Zhang L, Tang W, Banerjee S (2025). "Bayesian Geostatistics Using Predictive Stacking." Journal of the American Statistical Association, In press. doi:10.1080/01621459.2025.2566449.
Pan S, Zhang L, Bradley JR, Banerjee S (2025). "Bayesian Inference for Spatial-temporal Non-Gaussian Data Using Predictive Stacking." Bayesian Analysis, In Press. doi:10.1214/25-BA1582.
Yao Y, Vehtari A, Simpson D, Gelman A (2018). "Using Stacking to Average Bayesian Predictive Distributions (with Discussion)." Bayesian Analysis, 13(3), 917-1007. doi:10.1214/17-BA1091.
Useful links:
Creates an object of class 'candidateModels' that
contains a list of candidate models for stacking. The function takes a list
of candidate values for each model parameter and returns a list of possible
combinations of these values based on either simple aggregation or Cartesian
product of indivdual candidate values.
candidateModels(params_list, aggregation = "simple")candidateModels(params_list, aggregation = "simple")
params_list |
a list of candidate values for each model parameter. See examples for details. |
aggregation |
a character string specifying the type of aggregation to
be used. Options are |
an object of class 'candidateModels'
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
m1 <- candidateModels(list(phi_s = c(1, 1), phi_t = c(1, 2)), "simple") m1 m2 <- candidateModels(list(phi_s = c(1, 1), phi_t = c(1, 2)), "cartesian") m2 m3 <- candidateModels(list(phi_s = list(c(1, 1), c(1, 2)), phi_t = list(c(1, 3), c(2, 3)), boundary = c(0.5, 0.75)), "simple")m1 <- candidateModels(list(phi_s = c(1, 1), phi_t = c(1, 2)), "simple") m1 m2 <- candidateModels(list(phi_s = c(1, 1), phi_t = c(1, 2)), "cartesian") m2 m3 <- candidateModels(list(phi_s = list(c(1, 1), c(1, 2)), phi_t = list(c(1, 3), c(2, 3)), boundary = c(0.5, 0.75)), "simple")
Provides functions that implements different types of updates of a Cholesky factor that includes rank-one update, single row/column deletion update and a block deletion update.
cholUpdateRankOne(A, v, alpha, beta, lower = TRUE) cholUpdateDel(A, del.index, lower = TRUE) cholUpdateDelBlock(A, del.start, del.end, lower = TRUE)cholUpdateRankOne(A, v, alpha, beta, lower = TRUE) cholUpdateDel(A, del.index, lower = TRUE) cholUpdateDelBlock(A, del.start, del.end, lower = TRUE)
A |
an |
v |
an |
alpha |
scalar; if not supplied, default is 1 |
beta |
scalar; if not supplied, default is 1 |
lower |
logical; if |
del.index |
an integer from 1 to |
del.start |
an integer from 1 to |
del.end |
an integer from 1 to |
Suppose is a matrix with
being its lower-triangular Cholesky factor. Then rank-one update corresponds
to finding the Cholesky factor of the matrix
for some
given (see, Krause and Igel 2015). Similarly, single row/column
deletion update corresponds to finding the Cholesky factor of the
matrix which is obtained by removing the
-th row and column of , given for some
. Lastly, block deletion corresponds to finding the
Cholesky factor of the matrix for a
subset of containing consecutive
indices, given the factor .
An lower-triangular matrix with in
case of cholUpdateRankOne(), in case of cholUpdateDel(),
and, in case of cholUpdateDelBlock() where is
the size of the block removed.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Oswin Krause and Christian Igel. 2015. "A More Efficient Rank-one Covariance Matrix Update for Evolution Strategies". In Proceedings of the 2015 ACM Conference on Foundations of Genetic Algorithms XIII (FOGA '15). Association for Computing Machinery, New York, NY, USA, 129-136. doi:10.1145/2725494.2725496.
n <- 10 A <- matrix(rnorm(n^2), n, n) A <- crossprod(A) cholA <- chol(A) ## Rank-1 update v <- 1:n APlusvvT <- A + tcrossprod(v) cholA1 <- t(chol(APlusvvT)) cholA2 <- cholUpdateRankOne(cholA, v, lower = FALSE) print(all(abs(cholA1 - cholA2) < 1E-9)) ## Single Row-deletion update ind <- 2 A1 <- A[-ind, -ind] cholA1 <- t(chol(A1)) cholA2 <- cholUpdateDel(cholA, del.index = ind, lower = FALSE) print(all(abs(cholA1 - cholA2) < 1E-9)) ## Block-deletion update start_ind <- 2 end_ind <- 6 del_ind <- c(start_ind:end_ind) A1 <- A[-del_ind, -del_ind] cholA1 <- t(chol(A1)) cholA2 <- cholUpdateDelBlock(cholA, start_ind, end_ind, lower = FALSE) print(all(abs(cholA1 - cholA2) < 1E-9))n <- 10 A <- matrix(rnorm(n^2), n, n) A <- crossprod(A) cholA <- chol(A) ## Rank-1 update v <- 1:n APlusvvT <- A + tcrossprod(v) cholA1 <- t(chol(APlusvvT)) cholA2 <- cholUpdateRankOne(cholA, v, lower = FALSE) print(all(abs(cholA1 - cholA2) < 1E-9)) ## Single Row-deletion update ind <- 2 A1 <- A[-ind, -ind] cholA1 <- t(chol(A1)) cholA2 <- cholUpdateDel(cholA, del.index = ind, lower = FALSE) print(all(abs(cholA1 - cholA2) < 1E-9)) ## Block-deletion update start_ind <- 2 end_ind <- 6 del_ind <- c(start_ind:end_ind) A1 <- A[-del_ind, -del_ind] cholA1 <- t(chol(A1)) cholA2 <- cholUpdateDelBlock(cholA, start_ind, end_ind, lower = FALSE) print(all(abs(cholA1 - cholA2) < 1E-9))
Obtains optimal stacking weights given leave-one-out predictive densities for each candidate model.
get_stacking_weights(log_loopd, solver = NULL, verbose = TRUE)get_stacking_weights(log_loopd, solver = NULL, verbose = TRUE)
log_loopd |
an |
solver |
specifies the solver to use for obtaining optimal weights.
Default is |
verbose |
if |
The weights maximize the log score of the stacked leave-one-out
predictive densities (Yao et al. 2018) over the simplex, using the CVXR
solvers in the order given above. If none of them reaches an optimal
solution, loo::stacking_weights() is used as a fallback when the
package loo is installed; otherwise the weights are returned as
NA with status "failed".
A list with elements:
weightsoptimal stacking weights as a numeric vector of
length (NA if no solver succeeded, see Details).
statussolver status, returns "optimal" if solver
succeeded, and "failed" if no solver succeeded.
solvername of the solver used ("none" if no
solver succeeded).
detailsa list with the installed CVXR solvers
(installed), the requested solver(s) (requested) and those
of them not installed (missing.requested), the order in which the
solvers were tried (search.order), a data frame of the attempts
with the status or error of each solver (attempts), and whether
the fallback loo::stacking_weights() was used (fallback).
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Yao Y, Vehtari A, Simpson D, Gelman A (2018). "Using Stacking to Average Bayesian Predictive Distributions (with Discussion)." Bayesian Analysis, 13(3), 917-1007. doi:10.1214/17-BA1091.
CVXR::psolve(), spLMstack(), spGLMstack()
set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) loopd_mat <- do.call('cbind', mod1$loopd) w_hat <- get_stacking_weights(loopd_mat) print(round(w_hat$weights, 4)) print(w_hat$solver) print(w_hat$status)set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) loopd_mat <- do.call('cbind', mod1$loopd) w_hat <- get_stacking_weights(loopd_mat) print(round(w_hat$weights, 4)) print(w_hat$solver) print(w_hat$status)
Computes the inter-site Euclidean distance matrix for one or two sets of points.
iDist(coords.1, coords.2, ...)iDist(coords.1, coords.2, ...)
coords.1 |
an |
coords.2 |
an |
... |
currently no additional arguments. |
The or inter-site Euclidean
distance matrix.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
n <- 10 p1 <- cbind(runif(n),runif(n)) m <- 5 p2 <- cbind(runif(m),runif(m)) D <- iDist(p1, p2)n <- 10 p1 <- cbind(runif(n),runif(n)) m <- 5 p2 <- cbind(runif(m),runif(m)) D <- iDist(p1, p2)
A function to sample from the posterior predictive distribution of the latent spatial or spatial-temporal process.
posteriorPredict(mod_out, coords_new, covars_new, joint = FALSE, nBinom_new)posteriorPredict(mod_out, coords_new, covars_new, joint = FALSE, nBinom_new)
mod_out |
an object returned by any model fit under fixed
hyperparameters or using predictive stacking, i.e., |
coords_new |
new spatial coordinates (an |
covars_new |
new covariates at the new coordinates: a matrix or, for
the varying coefficients models (svc and stvc), a list with tags |
joint |
a logical value indicating whether to return the joint posterior
predictive samples of the latent process at the new locations or times.
Defaults to |
nBinom_new |
a vector of the number of trials for each new prediction
location or time. Only required if the model family is |
A modified object with the class name preceeded by the identifier
pp separated by a .. For example, if input is of class spLMstack, then
the output of this prediction function would be pp.spLMstack. The entry
with the tag samples is updated and will include samples from the posterior
predictive distribution of the latent process, the mean, and the response at
the new locations or times. An entry with the tag prediction is added
and contains the new coordinates and covariates, and whether the joint
posterior predictive samples were requested.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
spLMexact(), spLMstack(), spGLMexact(), spGLMstack(),
svcLMexact(), svcLMstack(), svcGLMexact(), svcGLMstack(),
stvcGLMexact(), stvcGLMstack(), stvcLMexact(), stvcLMstack()
set.seed(1234) # training and test data sizes n_train <- 100 n_pred <- 10 # Example 1: Spatial linear model # split the data into training and prediction sets data(simSpatial) dat_train <- simSpatial[1:n_train, ] dat_pred <- simSpatial[n_train + 1:n_pred, ] # fit a spatial linear model using predictive stacking cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1, 0.25)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat_train, coords = as.matrix(dat_train[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) # prepare new coordinates and covariates for prediction sp_pred <- as.matrix(dat_pred[, c("s1", "s2")]) X_new <- cbind(1, dat_pred$x1, dat_pred$x2) # carry out posterior prediction mod.pred <- posteriorPredict(mod1, coords_new = sp_pred, covars_new = X_new, joint = TRUE) # sample from the stacked posterior and posterior predictive distribution post_samps <- stackedSampler(mod.pred) # compare the predicted spatial effects with the truth z_pred <- apply(post_samps$z.pred, 1, median) cor(z_pred, dat_pred$z_true)set.seed(1234) # training and test data sizes n_train <- 100 n_pred <- 10 # Example 1: Spatial linear model # split the data into training and prediction sets data(simSpatial) dat_train <- simSpatial[1:n_train, ] dat_pred <- simSpatial[n_train + 1:n_pred, ] # fit a spatial linear model using predictive stacking cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1, 0.25)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat_train, coords = as.matrix(dat_train[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) # prepare new coordinates and covariates for prediction sp_pred <- as.matrix(dat_pred[, c("s1", "s2")]) X_new <- cbind(1, dat_pred$x1, dat_pred$x2) # carry out posterior prediction mod.pred <- posteriorPredict(mod1, coords_new = sp_pred, covars_new = X_new, joint = TRUE) # sample from the stacked posterior and posterior predictive distribution post_samps <- stackedSampler(mod.pred) # compare the predicted spatial effects with the truth z_pred <- apply(post_samps$z.pred, 1, median) cor(z_pred, dat_pred$z_true)
A function to recover posterior samples of scale parameters that
were marginalized out during model fit. This is only applicable for spatial
or, spatial-temporal generalized linear models. This function applies on
outputs of functions that fits a spatial/spatial-temporal generalized linear
model, such as spGLMexact(), spGLMstack(), svcGLMexact(),
svcGLMstack(), stvcGLMexact(), and stvcGLMstack().
recoverGLMscale(mod_out)recoverGLMscale(mod_out)
mod_out |
an object returned by a fitting a spatial or spatial-temporal GLM. |
An object of the same class as input, and updates the list tagged
samples with the posterior samples of the scale parameters. The new tags
are sigmasq.beta and z.scale.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
spGLMexact(), spGLMstack(), svcGLMexact(), svcGLMstack(),
stvcGLMexact(), stvcGLMstack()
set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 8), nu = c(1.5, 1.75), boundary = c(0.5)), "cartesian") mod1 <- spGLMstack(y_pois ~ x1 + x2, data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 100, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), verbose = TRUE) # Recover posterior samples of scale parameters mod1.1 <- recoverGLMscale(mod1) # sample from the stacked posterior distribution post_samps <- stackedSampler(mod1.1)set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 8), nu = c(1.5, 1.75), boundary = c(0.5)), "cartesian") mod1 <- spGLMstack(y_pois ~ x1 + x2, data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 100, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), verbose = TRUE) # Recover posterior samples of scale parameters mod1.1 <- recoverGLMscale(mod1) # sample from the stacked posterior distribution post_samps <- stackedSampler(mod1.1)
Dataset of size 500 with spatial coordinates sampled uniformly
from the unit square and temporal coordinates sampled uniformly from the
unit interval, two covariates, an intercept and a slope of x1 that vary
over space and time, and Gaussian and Poisson responses that share them.
data(simSpaceTime)data(simSpaceTime)
a data.frame object with 500 rows and columns
s1, s22-D coordinates in the unit square.
t_coordstemporal coordinates in the unit interval.
x1, x2covariates sampled from the standard normal distribution.
y_gaussGaussian response.
y_poisPoisson count response.
z1_truetrue spatial-temporal effect associated with the intercept.
z2_truetrue spatial-temporal effect associated with x1.
With , the varying intercept is a wave
travelling across space over time and the varying slope of
changes with and ,
deterministic surfaces that are not draws from Gaussian processes. The responses are generated as
This data can be generated with the code given in the example.
Soumyakanti Pan [email protected]
set.seed(1726) n <- 500 s1 <- runif(n) s2 <- runif(n) t_coords <- runif(n) x1 <- rnorm(n) x2 <- rnorm(n) z1 <- sin(2 * pi * s1 - pi * t_coords) z2 <- cos(2 * pi * s2) * cos(pi * t_coords) dat <- data.frame( s1 = s1, s2 = s2, t_coords = t_coords, x1 = x1, x2 = x2, y_gauss = rnorm(n, 2 + 5 * x1 - x2 + z1 + x1 * z2, sd = 0.5), y_pois = rpois(n, exp(2 - 0.5 * x1 + 0.3 * x2 + z1 + x1 * z2)), z1_true = z1, z2_true = z2 ) all.equal(dat, simSpaceTime)set.seed(1726) n <- 500 s1 <- runif(n) s2 <- runif(n) t_coords <- runif(n) x1 <- rnorm(n) x2 <- rnorm(n) z1 <- sin(2 * pi * s1 - pi * t_coords) z2 <- cos(2 * pi * s2) * cos(pi * t_coords) dat <- data.frame( s1 = s1, s2 = s2, t_coords = t_coords, x1 = x1, x2 = x2, y_gauss = rnorm(n, 2 + 5 * x1 - x2 + z1 + x1 * z2, sd = 0.5), y_pois = rpois(n, exp(2 - 0.5 * x1 + 0.3 * x2 + z1 + x1 * z2)), z1_true = z1, z2_true = z2 ) all.equal(dat, simSpaceTime)
Dataset of size 500 with spatial coordinates sampled uniformly
from the unit square, two covariates, a spatial effect with a checkerboard pattern
and one response for each of the Gaussian, Poisson, binomial and binary
families, plus a Gaussian and a Poisson response with spatially varying
coefficients (a varying intercept with a ring pattern and a varying slope
of x1). All the responses share the covariates and the spatial effects,
so that every spatial model in the package can be fitted to the same data.
data(simSpatial)data(simSpatial)
a data.frame object with 500 rows and 13 columns
s1, s22-D coordinates in the unit square.
x1, x2covariates sampled from the standard normal distribution.
y_gaussGaussian response.
y_poisPoisson count response.
y_binombinomial count response, out of n_trials trials.
n_trialsnumber of trials of the binomial response (5 to 20).
y_binbinary response.
y_svcGaussian response with the spatially varying intercept
z2 and the spatially varying slope 5 + z of x1.
y_svc_poisPoisson count response with the spatially varying
intercept z2 and the spatially varying slope -0.5 + z of x1.
z_truetrue spatial effect (checkerboard) that generated the
data; the spatially varying part of the slope of x1 in y_svc and
y_svc_pois.
z2_truetrue spatially varying intercept (rings) of y_svc and
y_svc_pois.
The spatial effect is the checkerboard
and the spatially varying intercept is the rings
where the constant makes the mean of over
the unit square zero (the mean of is zero by symmetry, and the two
surfaces are orthogonal on the unit square). Both are deterministic surfaces,
not draws from a Gaussian process. The responses are generated as
where is the number of trials. This data can be generated with
the code given in the example.
Soumyakanti Pan [email protected]
set.seed(1729) n <- 500 s1 <- runif(n) s2 <- runif(n) x1 <- rnorm(n) x2 <- rnorm(n) z <- 1.5 * sin(2 * pi * s1) * sin(2 * pi * s2) ring <- function(s1, s2) cos(4 * pi * sqrt((s1 - 0.5)^2 + (s2 - 0.5)^2)) g <- (seq_len(1000) - 0.5) / 1000 z2 <- ring(s1, s2) - mean(outer(g, g, ring)) n_trials <- sample(5:20, n, replace = TRUE) dat <- data.frame( s1 = s1, s2 = s2, x1 = x1, x2 = x2, y_gauss = rnorm(n, 2 + 5 * x1 - x2 + z, sd = 0.5), y_pois = rpois(n, exp(2 - 0.5 * x1 + 0.3 * x2 + z)), y_binom = rbinom(n, n_trials, plogis(0.5 - 0.5 * x1 + 0.5 * x2 + z)), n_trials = n_trials, y_bin = rbinom(n, 1, plogis(0.5 - 0.5 * x1 + 0.5 * x2 + z)), y_svc = rnorm(n, 2 + z2 + (5 + z) * x1 - x2, sd = 0.5), y_svc_pois = rpois(n, exp(2 + z2 + (-0.5 + z) * x1 + 0.3 * x2)), z_true = z, z2_true = z2 ) all.equal(dat, simSpatial)set.seed(1729) n <- 500 s1 <- runif(n) s2 <- runif(n) x1 <- rnorm(n) x2 <- rnorm(n) z <- 1.5 * sin(2 * pi * s1) * sin(2 * pi * s2) ring <- function(s1, s2) cos(4 * pi * sqrt((s1 - 0.5)^2 + (s2 - 0.5)^2)) g <- (seq_len(1000) - 0.5) / 1000 z2 <- ring(s1, s2) - mean(outer(g, g, ring)) n_trials <- sample(5:20, n, replace = TRUE) dat <- data.frame( s1 = s1, s2 = s2, x1 = x1, x2 = x2, y_gauss = rnorm(n, 2 + 5 * x1 - x2 + z, sd = 0.5), y_pois = rpois(n, exp(2 - 0.5 * x1 + 0.3 * x2 + z)), y_binom = rbinom(n, n_trials, plogis(0.5 - 0.5 * x1 + 0.5 * x2 + z)), n_trials = n_trials, y_bin = rbinom(n, 1, plogis(0.5 - 0.5 * x1 + 0.5 * x2 + z)), y_svc = rnorm(n, 2 + z2 + (5 + z) * x1 - x2, sd = 0.5), y_svc_pois = rpois(n, exp(2 + z2 + (-0.5 + z) * x1 + 0.3 * x2)), z_true = z, z2_true = z2 ) all.equal(dat, simSpatial)
Fits a Bayesian spatial generalized linear model with fixed values of spatial process parameters and some auxiliary model parameters. The output contains posterior samples of the fixed effects, spatial random effects and, if required, finds leave-one-out predictive densities.
spGLMexact( formula, data = parent.frame(), family, coords, cor.fn, priors, spParams, boundary = 0.5, n.samples, loopd = FALSE, loopd.method = "exact", CV.K = 10, loopd.nMC = 500, verbose = TRUE, ... )spGLMexact( formula, data = parent.frame(), family, coords, cor.fn, priors, spParams, boundary = 0.5, n.samples, loopd = FALSE, loopd.method = "exact", CV.K = 10, loopd.nMC = 500, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. See example below. |
data |
an optional data frame containing the variables in the model.
If not found in |
family |
Specifies the distribution of the response as a member of the
exponential family. Supported options are |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
priors |
(optional) a list with each tag corresponding to a
hyperparameter name and containing hyperprior details. Valid tags include
|
spParams |
fixed values of spatial process parameters. |
boundary |
Specifies the boundary adjustment parameter. Must be a real number between 0 and 1. Default is 0.5. |
n.samples |
number of posterior samples to be generated. |
loopd |
logical. If |
loopd.method |
character. Ignored if |
CV.K |
An integer between 10 and 20. Considered only if
|
loopd.nMC |
Number of Monte Carlo samples to be used to evaluate
leave-one-out predictive densities when |
verbose |
logical. If |
... |
currently no additional argument. |
With this function, we fit a Bayesian hierarchical spatial
generalized linear model by sampling exactly from the joint posterior
distribution utilizing the generalized conjugate multivariate distribution
theory (Bradley and Clinch 2024). Suppose
denotes the spatial locations the response is observed. Let
be the outcome at location endowed with a probability law
from the natural exponential family, which we denote by
for some positive parameter and unit log partition function
. We consider the following response models based on the input
supplied to the argument family.
'poisson'It considers point-referenced Poisson responses
. Here,
and .
'binomial'It considers point-referenced binomial counts
where, denotes
the total number of trials and probability of success
at location .
Here, and .
'binary'It considers point-referenced binary data (0 or, 1) i.e.,
, where probability of success
at location .
Here, and .
The hierarchical model is given as
where denotes the discrepancy
parameter. We fix the spatial process parameters and and
the hyperparameters , , and
. The term is known as the fine-scale variation
term which is given a conditional generalized conjugate multivariate
distribution as prior. For more details, see Pan et al. 2025. Default
values for , , ,
are diagonal with each diagonal element 100, 2.1, 2.1 and 0.1 respectively.
An object of class spGLMexact, which is a list with the
following tags -
details of the priors used, containing the values of the
boundary adjustment parameter (boundary), the variance parameter of the
fine-scale variation term (simasq.xi) and others.
a list of length 3, containing posterior samples of fixed
effects (beta), spatial effects (z) and the fine-scale
variation term (xi).
If loopd=TRUE, contains leave-one-out predictive
densities.
Values of the fixed parameters that includes
phi (spatial decay), nu (spatial smoothness; NA for
the exponential correlation function).
a list of diagnostics. Element numerical is a
data frame with one row and columns min.pivot (the smallest
relative Cholesky pivot of the correlation
matrix; values below 1e-8 indicate a nearly singular correlation matrix),
min.cor and max.cor (the correlations of the two
farthest-apart and of the two closest locations; values of min.cor
above 0.95 suggest an effective range far exceeding the extent of the
data, values of max.cor below 0.05 nearly uncorrelated locations),
obtained from quantities the fit computes anyway. If verbose =
TRUE, a "Diagnostics" section is printed when any threshold is crossed.
The return object might include additional data that can be used for subsequent prediction and/or model fit evaluation.
Soumyakanti Pan [email protected]
Bradley JR, Clinch M (2024). "Generating Independent Replicates Directly from the Posterior Distribution for a Class of Spatial Hierarchical Models." Journal of Computational and Graphical Statistics, 0(0), 1-17. doi:10.1080/10618600.2024.2365728.
Pan S, Zhang L, Bradley JR, Banerjee S (2025). "Bayesian Inference for Spatial-temporal Non-Gaussian Data Using Predictive Stacking." Bayesian Analysis, In Press. doi:10.1214/25-BA1582.
Vehtari A, Gelman A, Gabry J (2017). "Practical Bayesian Model Evaluation Using Leave-One-out Cross-Validation and WAIC." Statistics and Computing, 27(5), 1413-1432. ISSN 0960-3174. doi:10.1007/s11222-016-9696-4.
data(simSpatial) dat <- simSpatial[1:100, ] coords <- as.matrix(dat[, c("s1", "s2")]) # Example 1: spatial Poisson count data mod1 <- spGLMexact(y_pois ~ x1 + x2, data = dat, family = "poisson", coords = coords, cor.fn = "matern", spParams = list(phi = 4, nu = 1.75), n.samples = 100, verbose = TRUE) post_beta <- mod1$samples$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # Example 2: spatial binomial count data mod2 <- spGLMexact(cbind(y_binom, n_trials) ~ x1 + x2, data = dat, family = "binomial", coords = coords, cor.fn = "matern", spParams = list(phi = 4, nu = 1.75), n.samples = 100, verbose = FALSE) # Example 3: spatial binary data mod3 <- spGLMexact(y_bin ~ x1 + x2, data = dat, family = "binary", coords = coords, cor.fn = "matern", spParams = list(phi = 4, nu = 1.75), n.samples = 100, verbose = FALSE)data(simSpatial) dat <- simSpatial[1:100, ] coords <- as.matrix(dat[, c("s1", "s2")]) # Example 1: spatial Poisson count data mod1 <- spGLMexact(y_pois ~ x1 + x2, data = dat, family = "poisson", coords = coords, cor.fn = "matern", spParams = list(phi = 4, nu = 1.75), n.samples = 100, verbose = TRUE) post_beta <- mod1$samples$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # Example 2: spatial binomial count data mod2 <- spGLMexact(cbind(y_binom, n_trials) ~ x1 + x2, data = dat, family = "binomial", coords = coords, cor.fn = "matern", spParams = list(phi = 4, nu = 1.75), n.samples = 100, verbose = FALSE) # Example 3: spatial binary data mod3 <- spGLMexact(y_bin ~ x1 + x2, data = dat, family = "binary", coords = coords, cor.fn = "matern", spParams = list(phi = 4, nu = 1.75), n.samples = 100, verbose = FALSE)
Fits Bayesian spatial generalized linear model on a collection of candidate models constructed based on some candidate values of some model parameters specified by the user and subsequently combines inference by stacking predictive densities. See Pan, Zhang, Bradley, and Banerjee (2025) for more details.
spGLMstack( formula, data = parent.frame(), family, coords, cor.fn, priors, candidate.models, n.samples, loopd.controls, parallel = FALSE, solver = NULL, verbose = TRUE, ... )spGLMstack( formula, data = parent.frame(), family, coords, cor.fn, priors, candidate.models, n.samples, loopd.controls, parallel = FALSE, solver = NULL, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. See example below. |
data |
an optional data frame containing the variables in the model.
If not found in |
family |
Specifies the distribution of the response as a member of the
exponential family. Supported options are |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
priors |
(optional) a list with each tag corresponding to a parameter
name and containing prior details. Valid tags include |
candidate.models |
an object of class |
n.samples |
number of posterior samples to be generated. |
loopd.controls |
a list with details on how leave-one-out predictive
densities (LOO-PD) are to be calculated. Valid tags include |
parallel |
logical. If |
solver |
(optional) Specifies the name of the solver that will be used
to obtain optimal stacking weights for each candidate model. Default order
is |
verbose |
logical. If |
... |
currently no additional argument. |
Instead of assigning a prior on the process parameters
and , the boundary adjustment parameter , we consider
a set of candidate models based on some candidate values of these parameters
supplied by the user. Suppose the set of candidate models is
. Then for each
, we sample from the posterior distribution
under the model and find
leave-one-out predictive densities . Then we
solve the optimization problem
to find the optimal stacking weights .
An object of class spGLMstack, which is a list including the
following tags -
familythe distribution of the responses as indicated in the function call
samplesa list of length equal to total number of candidate models
with each entry corresponding to a list of length 3, containing posterior
samples of fixed effects (beta), spatial effects (z) and
fine-scale variation term (xi) for that particular model.
loopda list of length equal to total number of candidate models with each entry containing leave-one-out predictive densities under that particular model.
loopd.methoda list containing details of the algorithm used for
calculation of leave-one-out predictive densities. For K-fold
cross-validation, its tag cv.update records the pre-processing method
('update' or 'direct') that was used.
n.modelsnumber of candidate models that are fit.
model.paramsa list with one element per candidate model, each a
named list of its parameters: phi, nu (NA for the
exponential correlation function) and boundary (boundary adjustment parameter).
stacking.summarya matrix with one row per candidate model, containing its parameters and its optimal stacking weight, for display.
stacking.weightsa numeric vector of length equal to the number of candidate models storing the optimal stacking weights.
run.timea proc_time object with runtime details.
diagnosticsa list of diagnostics. Element numerical is a
data frame with one row per candidate model and columns min.pivot
(the smallest relative Cholesky pivot of the
correlation matrix; values below 1e-8 indicate a nearly singular
correlation matrix), min.cor and max.cor (the correlations
of the two farthest-apart and of the two closest locations; values of
min.cor above 0.95 suggest an effective range far exceeding the
extent of the data, values of max.cor below 0.05 nearly
uncorrelated locations), obtained from quantities the fit computes
anyway. Element solver describes the optimization for the stacking
weights: the solver used (used) and its status (status),
the installed and requested solvers, the search order, the attempts with
their status, and whether the fallback loo::stacking_weights() was
used. If verbose = TRUE, a "Diagnostics" section is printed if
there is an issue: numerical flags of candidate models with stacking
weight above 0.05 (extreme candidates with negligible weight are expected
in a stacking grid and are only counted), and solver problems (a
requested solver not installed, an inaccurate solution, or the
fallback).
The return object might include additional data that is useful for subsequent prediction, model fit evaluation and other utilities.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Pan S, Zhang L, Bradley JR, Banerjee S (2025). "Bayesian Inference for Spatial-temporal Non-Gaussian Data Using Predictive Stacking." Bayesian Analysis, In Press. doi:10.1214/25-BA1582.
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
set.seed(1234) data(simSpatial) dat <- simSpatial[1:150, ] cand.mod <- candidateModels(list(phi = c(2, 4, 8), nu = c(1.5, 1.75), boundary = c(0.75)), "cartesian") mod1 <- spGLMstack(y_pois ~ x1 + x2, data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 500, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), parallel = FALSE, verbose = TRUE) post_samps <- stackedSampler(mod1) post_beta <- post_samps$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # compare the posterior medians of the spatial effects with the truth cor(apply(post_samps$z, 1, median), dat$z_true)set.seed(1234) data(simSpatial) dat <- simSpatial[1:150, ] cand.mod <- candidateModels(list(phi = c(2, 4, 8), nu = c(1.5, 1.75), boundary = c(0.75)), "cartesian") mod1 <- spGLMstack(y_pois ~ x1 + x2, data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 500, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), parallel = FALSE, verbose = TRUE) post_samps <- stackedSampler(mod1) post_beta <- post_samps$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # compare the posterior medians of the spatial effects with the truth cor(apply(post_samps$z, 1, median), dat$z_true)
Fits a Bayesian spatial linear model with spatial process parameters and the noise-to-spatial variance ratio fixed to a value supplied by the user. The output contains posterior samples of the fixed effects, variance parameter, spatial random effects and, if required, leave-one-out predictive densities.
spLMexact( formula, data = parent.frame(), coords, cor.fn, priors = "flat", spParams, noise_sp_ratio, n.samples, loopd = FALSE, loopd.method = "exact", verbose = TRUE, ... )spLMexact( formula, data = parent.frame(), coords, cor.fn, priors = "flat", spParams, noise_sp_ratio, n.samples, loopd = FALSE, loopd.method = "exact", verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. See example below. |
data |
an optional data frame containing the variables in the model.
If not found in |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
priors |
either |
spParams |
fixed value of spatial process parameters. |
noise_sp_ratio |
noise-to-spatial variance ratio. |
n.samples |
number of posterior samples to be generated. |
loopd |
logical. If |
loopd.method |
character. Ignored if |
verbose |
logical. If |
... |
currently no additional argument. |
Suppose denotes the
spatial locations the response is observed. With this function, we
fit a conjugate Bayesian hierarchical spatial model
where we fix the noise-to-spatial variance ratio
, the spatial process parameters
and , and the hyperparameters ,
, and . If priors = "flat",
we instead assign the prior . We utilize
a composition sampling strategy to sample the model parameters from their
joint posterior distribution which can be written as
We proceed by first sampling from its marginal posterior,
then given the samples of , we sample and
subsequently, we sample conditioned on the posterior samples of
and (Banerjee 2020). Posterior samples of the
spatial variance are obtained as .
An object of class spLMexact, which is a list with the
following tags -
a list of length 4, containing posterior samples of fixed
effects (beta), measurement error variance (sigmaSq),
spatial variance (sigmaSq.z), and spatial effects (z).
If loopd=TRUE, contains leave-one-out predictive
densities.
Values of the fixed parameters that includes
phi (spatial decay), nu (spatial smoothness; NA for
the exponential correlation function) and noise_sp_ratio
(noise-to-spatial variance ratio).
a list of fit diagnostics, obtained from quantities the
fit computes anyway. Element numerical is a data frame with one row
and columns min.pivot (the smallest relative Cholesky pivot of the
factorizations; values below 1e-8 indicate a
nearly singular covariance matrix), min.cor and max.cor (the
correlations of the two farthest-apart and of the two closest locations;
values of min.cor above 0.95 suggest an effective range far
exceeding the extent of the data, values of max.cor below 0.05
nearly uncorrelated locations). If loopd.method = 'PSIS', element
pareto is a list with the Pareto diagnostic values of the
leave-one-out predictive densities (k), the threshold above which
they are unreliable (threshold, Vehtari et al. 2024) and the
number of values above it (n.high). If verbose = TRUE, a
"Diagnostics" section is printed when any threshold is crossed.
The return object might include additional data used for subsequent prediction and/or model fit evaluation.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Banerjee S (2020). "Modeling massive spatial datasets using a conjugate Bayesian linear modeling framework." Spatial Statistics, 37, 100417. ISSN 2211-6753. doi:10.1016/j.spasta.2020.100417.
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
data(simSpatial) dat <- simSpatial[1:100, ] # setup prior list muBeta <- c(0, 0, 0) VBeta <- diag(100, 3) sigmaSqIGa <- 2 sigmaSqIGb <- 0.1 prior_list <- list(beta.norm = list(muBeta, VBeta), sigma.sq.ig = c(sigmaSqIGa, sigmaSqIGb)) mod1 <- spLMexact(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", priors = prior_list, spParams = list(phi = 4, nu = 1.75), noise_sp_ratio = 0.1, n.samples = 100, loopd = TRUE, loopd.method = "exact") post_beta <- mod1$samples$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # compare the posterior medians of the spatial effects with the truth cor(apply(mod1$samples$z, 1, median), dat$z_true)data(simSpatial) dat <- simSpatial[1:100, ] # setup prior list muBeta <- c(0, 0, 0) VBeta <- diag(100, 3) sigmaSqIGa <- 2 sigmaSqIGb <- 0.1 prior_list <- list(beta.norm = list(muBeta, VBeta), sigma.sq.ig = c(sigmaSqIGa, sigmaSqIGb)) mod1 <- spLMexact(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", priors = prior_list, spParams = list(phi = 4, nu = 1.75), noise_sp_ratio = 0.1, n.samples = 100, loopd = TRUE, loopd.method = "exact") post_beta <- mod1$samples$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # compare the posterior medians of the spatial effects with the truth cor(apply(mod1$samples$z, 1, median), dat$z_true)
Fits Bayesian spatial linear model on a collection of candidate models constructed based on some candidate values of some model parameters specified by the user and subsequently combines inference by stacking predictive densities. See Zhang, Tang and Banerjee (2025) for more details.
spLMstack( formula, data = parent.frame(), coords, cor.fn, priors = "flat", candidate.models, n.samples, loopd.method, parallel = FALSE, solver = NULL, verbose = TRUE, ... )spLMstack( formula, data = parent.frame(), coords, cor.fn, priors = "flat", candidate.models, n.samples, loopd.method, parallel = FALSE, solver = NULL, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. See example below. |
data |
an optional data frame containing the variables in the model.
If not found in |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
priors |
either |
candidate.models |
an object of class |
n.samples |
number of posterior samples to be generated. |
loopd.method |
character. Valid inputs are |
parallel |
logical. If |
solver |
(optional) Specifies the name of the solver that will be used
to obtain optimal stacking weights for each candidate model. Default order
is |
verbose |
logical. If |
... |
currently no additional argument. |
Instead of assigning a prior on the process parameters
and , noise-to-spatial variance ratio , we consider
a set of candidate models based on some candidate values of these parameters
supplied by the user. Suppose the set of candidate models is
. Then for each
, we sample from the posterior distribution
under the model and find
leave-one-out predictive densities . Then we
solve the optimization problem
to find the optimal stacking weights .
An object of class spLMstack, which is a list including the
following tags -
samplesa list of length equal to total number of candidate models
with each entry corresponding to a list of length 4, containing posterior
samples of fixed effects (beta), measurement error variance
(sigmaSq), spatial variance (sigmaSq.z), and spatial effects
(z) for that model.
loopda list of length equal to total number of candidate models with each entry containing leave-one-out predictive densities under that particular model.
n.modelsnumber of candidate models that are fit.
model.paramsa list with one element per candidate model, each a
named list of its parameters: phi, nu (NA for the
exponential correlation function) and noise_sp_ratio (noise-to-spatial variance ratio).
stacking.summarya matrix with one row per candidate model, containing its parameters and its optimal stacking weight, for display.
stacking.weightsa numeric vector of length equal to the number of candidate models storing the optimal stacking weights.
run.timea proc_time object with runtime details.
diagnosticsa list of diagnostics. Element numerical is a
data frame with one row per candidate model and columns min.pivot
(the smallest relative Cholesky pivot of the
factorizations; values below 1e-8 indicate a nearly singular covariance
matrix), min.cor and max.cor (the correlations of the two
farthest-apart and of the two closest locations; values of min.cor
above 0.95 suggest an effective range far exceeding the extent of the data,
values of max.cor below 0.05 nearly uncorrelated locations),
obtained from quantities the fits compute anyway. If
loopd.method = 'PSIS', element pareto is a list with the
Pareto diagnostic values of each candidate model (k), the
threshold above which they are unreliable (threshold) and the
number of values above it for each model (n.high). Element
solver describes the optimization for the stacking weights: the
solver used (used) and its status (status), the installed
and requested solvers, the search order, the attempts with their status,
and whether the fallback loo::stacking_weights() was used. If
verbose = TRUE, a "Diagnostics" section is printed if there is an
issue: numerical flags of candidate models with stacking weight above 0.05
(extreme candidates with negligible weight are expected in a stacking grid
and are only counted), Pareto values above the threshold for any
model, and solver problems (a requested solver not installed, an
inaccurate solution, or the fallback).
The return object might include additional data that is useful for subsequent prediction, model fit evaluation and other utilities.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
Zhang L, Tang W, Banerjee S (2025). "Bayesian Geostatistics Using Predictive Stacking." Journal of the American Statistical Association, In press. doi:10.1080/01621459.2025.2566449.
set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1, 0.25)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) post_samps <- stackedSampler(mod1) post_beta <- post_samps$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # compare the posterior medians of the spatial effects with the truth cor(apply(post_samps$z, 1, median), dat$z_true)set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1, 0.25)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) post_samps <- stackedSampler(mod1) post_beta <- post_samps$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975))))) # compare the posterior medians of the spatial effects with the truth cor(apply(post_samps$z, 1, median), dat$z_true)
A helper function to sample from the stacked posterior
distribution to obtain final posterior samples that can be used for
subsequent analysis. This function applies on outputs of functions
spLMstack(), spGLMstack(), svcLMstack(), svcGLMstack(),
stvcGLMstack() and stvcLMstack().
stackedSampler(mod_out, n.samples)stackedSampler(mod_out, n.samples)
mod_out |
an object that is an output of a model fit or a prediction
task, i.e., the class should be either |
n.samples |
(optional) If missing, inherits the number of posterior samples from the original output. Otherwise, it specifies number of posterior samples to draw from the stacked posterior. If it exceeds the number of posterior draws used in the original function, then a message is thrown and the samples are obtained by resampling. We recommended running the original model fit/prediction with enough samples. |
After obtaining the optimal stacking weights
, posterior inference of quantities of
interest subsequently proceed from the stacked posterior,
where is the collection of candidate
models.
An object of class stacked_posterior, which is a list that
includes the following tags -
samples of the fixed effect from the stacked joint posterior.
samples of the spatial random effects from the stacked joint posterior.
The list may also include other scale parameters corresponding to the model.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
spLMstack(), spGLMstack(), svcLMstack(), svcGLMstack(),
stvcGLMstack(), stvcLMstack()
set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) print(mod1$diagnostics$solver$used) print(mod1$diagnostics$solver$status) print(mod1$run.time) post_samps <- stackedSampler(mod1) post_beta <- post_samps$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975)))))set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] cand.mod <- candidateModels(list(phi = c(2, 4, 6), nu = c(1, 1.5, 1.75), noise_sp_ratio = c(0.1)), "cartesian") mod1 <- spLMstack(y_gauss ~ x1 + x2, data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", candidate.models = cand.mod, n.samples = 1000, loopd.method = "exact", parallel = FALSE, verbose = TRUE) print(mod1$diagnostics$solver$used) print(mod1$diagnostics$solver$status) print(mod1$run.time) post_samps <- stackedSampler(mod1) post_beta <- post_samps$beta print(t(apply(post_beta, 1, function(x) quantile(x, c(0.025, 0.5, 0.975)))))
Fits a Bayesian generalized linear model with spatially-temporally varying coefficients under fixed values of spatial-temporal process parameters and some auxiliary model parameters. The output contains posterior samples of the fixed effects, spatial-temporal random effects and, if required, finds leave-one-out predictive densities.
stvcGLMexact( formula, data = parent.frame(), family, sp_coords, time_coords, cor.fn, process.type, sptParams, priors, boundary = 0.5, n.samples, loopd = FALSE, loopd.method = "exact", CV.K = 10, loopd.nMC = 500, verbose = TRUE, ... )stvcGLMexact( formula, data = parent.frame(), family, sp_coords, time_coords, cor.fn, process.type, sptParams, priors, boundary = 0.5, n.samples, loopd = FALSE, loopd.method = "exact", CV.K = 10, loopd.nMC = 500, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially-temporally varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
family |
Specifies the distribution of the response as a member of the
exponential family. Supported options are |
sp_coords |
an |
time_coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial-temporal dependence structure among the observations.
Supported covariance model key words are: |
process.type |
a quoted keyword specifying the model for the
spatial-temporal process. Supported keywords are |
sptParams |
fixed values of spatial-temporal process parameters in
usually a list of length 2. If |
priors |
(optional) a list with each tag corresponding to a
hyperparameter name and containing hyperprior details. Valid tags include
|
boundary |
Specifies the boundary adjustment parameter. Must be a real number between 0 and 1. Default is 0.5. |
n.samples |
number of posterior samples to be generated. |
loopd |
logical. If |
loopd.method |
character. Ignored if |
CV.K |
An integer between 10 and 20. Considered only if
|
loopd.nMC |
Number of Monte Carlo samples to be used to evaluate
leave-one-out predictive densities when |
verbose |
logical. If |
... |
currently no additional argument. |
With this function, we fit a Bayesian hierarchical
spatially-temporally varying generalized linear model by sampling exactly
from the joint posterior distribution utilizing the generalized conjugate
multivariate distribution theory (Bradley and Clinch 2024). Suppose
denotes the spatial-temporal
co-ordinates in , the
response is observed. Let be the outcome at the
co-ordinate endowed with a probability law from the natural
exponential family, which we denote by
for some positive parameter and unit log partition function
. Here, denotes covariates with
spatially-temporally varying coefficients We consider the following response
models based on the input supplied to the argument family.
'poisson'It considers point-referenced Poisson responses
. Here, and
.
'binomial'It considers point-referenced binomial counts
where,
denotes the total number of trials and probability of success
at spatial-temporal co-ordinate . Here,
and .
'binary'It considers point-referenced binary data (0 or, 1) i.e.,
, where probability of
success at spatial-temporal co-ordinate .
Here, and .
The hierarchical model is given as
where denotes the discrepancy
parameter. We fix the spatial-temporal process parameters and
and the hyperparameters , ,
and . The term is known as the
fine-scale variation term which is given a conditional generalized conjugate
multivariate distribution as prior. For more details, see Pan et al. 2025.
Default values for , , ,
are diagonal with each diagonal element 100, 2.1, 2.1 and
0.1 respectively. If process.type = 'multivariate', the cross-covariance matrix of the processes has the prior
, with given by
IW.scale; its default gives
. The widths of the posterior credible intervals of the
processes grow with the prior scale.
An object of class stvcGLMexact, which is a list with the
following tags -
details of the priors used, containing the values of the
boundary adjustment parameter (boundary), the variance parameter of the
fine-scale variation term (simasq.xi) and others.
a list of length 3, containing posterior samples of fixed
effects (beta), spatial-temporal effects (z) and the
fine-scale variation term (xi). The element with tag z will
again be a list of length , each containing posterior samples of the
spatial-temporal random effects corresponding to each varying coefficient.
If loopd=TRUE, contains leave-one-out predictive
densities.
Values of the fixed parameters that includes phi_s
(spatial decay), phi_t (temporal smoothness).
a list of diagnostics. Element numerical is a
data frame with one row (one row per process, with columns model
and process, if process.type = 'independent') and columns
min.pivot (the smallest relative Cholesky pivot of the spatial-temporal correlation matrix; values below 1e-8
indicate a nearly singular correlation matrix), min.cor and
max.cor (the correlations of the two farthest-apart and of the two
closest space-time locations; values of min.cor above 0.95 suggest
an effective range far exceeding the extent of the data, values of
max.cor below 0.05 nearly uncorrelated space-time locations),
obtained from quantities the fit computes anyway. If verbose =
TRUE, a "Diagnostics" section is printed when any threshold is crossed.
The return object might include additional data that can be used for subsequent prediction and/or model fit evaluation.
Soumyakanti Pan [email protected]
Bradley JR, Clinch M (2024). "Generating Independent Replicates Directly from the Posterior Distribution for a Class of Spatial Hierarchical Models." Journal of Computational and Graphical Statistics, 0(0), 1-17. doi:10.1080/10618600.2024.2365728.
T. Gneiting and P. Guttorp (2010). "Continuous-parameter spatio-temporal processes." In A.E. Gelfand, P.J. Diggle, M. Fuentes, and P Guttorp, editors, Handbook of Spatial Statistics, Chapman & Hall CRC Handbooks of Modern Statistical Methods, p 427–436. Taylor and Francis.
Pan S, Zhang L, Bradley JR, Banerjee S (2025). "Bayesian Inference for Spatial-temporal Non-Gaussian Data Using Predictive Stacking." Bayesian Analysis, In Press. doi:10.1214/25-BA1582.
Vehtari A, Gelman A, Gabry J (2017). "Practical Bayesian Model Evaluation Using Leave-One-out Cross-Validation and WAIC." Statistics and Computing, 27(5), 1413-1432. ISSN 0960-3174. doi:10.1007/s11222-016-9696-4.
data(simSpaceTime) dat <- simSpaceTime[1:100, ] # Fit a spatial-temporal varying coefficient Poisson GLM mod1 <- stvcGLMexact(y_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent", sptParams = list(phi_s = c(3, 3), phi_t = c(4, 4)), verbose = FALSE, n.samples = 100) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[1:n], dat$z1_true)data(simSpaceTime) dat <- simSpaceTime[1:100, ] # Fit a spatial-temporal varying coefficient Poisson GLM mod1 <- stvcGLMexact(y_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent", sptParams = list(phi_s = c(3, 3), phi_t = c(4, 4)), verbose = FALSE, n.samples = 100) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[1:n], dat$z1_true)
Fits Bayesian spatial-temporal generalized linear model with spatially-temporally varying coefficients on a collection of candidate models constructed based on some candidate values of some model parameters specified by the user and subsequently combines inference by stacking predictive densities. See Pan, Zhang, Bradley, and Banerjee (2025) for more details.
stvcGLMstack( formula, data = parent.frame(), family, sp_coords, time_coords, cor.fn, process.type, priors, candidate.models, n.samples, loopd.controls, parallel = FALSE, solver = NULL, verbose = TRUE, ... )stvcGLMstack( formula, data = parent.frame(), family, sp_coords, time_coords, cor.fn, process.type, priors, candidate.models, n.samples, loopd.controls, parallel = FALSE, solver = NULL, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially-temporally varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
family |
Specifies the distribution of the response as a member of the
exponential family. Supported options are |
sp_coords |
an |
time_coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial-temporal dependence structure among the observations.
Supported covariance model key words are: |
process.type |
a quoted keyword specifying the model for the
spatial-temporal process. Supported keywords are |
priors |
(optional) a list with each tag corresponding to a
hyperparameter name and containing hyperprior details. Valid tags include
|
candidate.models |
an object of class |
n.samples |
number of samples to be drawn from the posterior distribution. |
loopd.controls |
a list with details on how leave-one-out predictive
densities (LOO-PD) are to be calculated. Valid tags include |
parallel |
logical. If |
solver |
(optional) Specifies the name of the solver that will be used
to obtain optimal stacking weights for each candidate model. Default order
is |
verbose |
logical. If |
... |
currently no additional argument. |
An object of class stvcGLMstack, which is a list including the
following tags -
samplesa list of length equal to total number of candidate models
with each entry corresponding to a list of length 3, containing posterior
samples of fixed effects (beta), spatial effects (z), and
fine scale variation xi for that model.
loopda list of length equal to total number of candidate models with each entry containing leave-one-out predictive densities under that particular model.
n.modelsnumber of candidate models that are fit.
model.paramsa list with one element per candidate model, each a
named list of its parameters: phi_s, phi_t (vectors of
length if process.type = 'independent') and boundary.
stacking.summarya matrix with one row per candidate model, containing its parameters and its optimal stacking weight, for display.
stacking.weightsa numeric vector of length equal to the number of candidate models storing the optimal stacking weights.
run.timea proc_time object with runtime details.
diagnosticsa list of diagnostics. Element numerical is a
data frame with one row per candidate model (per candidate model and
process, with columns model and process, if
process.type = 'independent') and columns min.pivot (the
smallest relative Cholesky pivot of the
spatial-temporal correlation matrix; values below 1e-8 indicate a nearly
singular correlation matrix), min.cor and max.cor (the
correlations of the two farthest-apart and of the two closest space-time
locations; values of min.cor above 0.95 suggest an effective range
far exceeding the extent of the data, values of max.cor below 0.05
nearly uncorrelated space-time locations), obtained from quantities the
fit computes anyway. Element solver describes the optimization for
the stacking weights: the solver used (used) and its status
(status), the installed and requested solvers, the search order,
the attempts with their status, and whether the fallback
loo::stacking_weights() was used. If verbose = TRUE, a
"Diagnostics" section is printed if there is an issue: numerical flags of
candidate models with stacking weight above 0.05 (extreme candidates with
negligible weight are expected in a stacking grid and are only counted),
and solver problems (a requested solver not installed, an inaccurate
solution, or the fallback).
This object can be further used to recover posterior samples of the scale
parameters in the model, and subsequrently, to make predictions at new
locations or times using the function posteriorPredict().
set.seed(1234) data(simSpaceTime) dat <- simSpaceTime[1:100, ] # create list of candidate models (multivariate) mod.list2 <- candidateModels(list(phi_s = list(2, 3, 4), phi_t = list(4, 8), boundary = c(0.75)), "cartesian") # fit a spatial-temporal varying coefficient model using predictive stacking mod1 <- stvcGLMstack(y_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "multivariate", candidate.models = mod.list2, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), n.samples = 500) post_samps <- stackedSampler(mod1)set.seed(1234) data(simSpaceTime) dat <- simSpaceTime[1:100, ] # create list of candidate models (multivariate) mod.list2 <- candidateModels(list(phi_s = list(2, 3, 4), phi_t = list(4, 8), boundary = c(0.75)), "cartesian") # fit a spatial-temporal varying coefficient model using predictive stacking mod1 <- stvcGLMstack(y_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "multivariate", candidate.models = mod.list2, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), n.samples = 500) post_samps <- stackedSampler(mod1)
Fits a Bayesian linear model with spatially-temporally varying coefficients for a Gaussian response, with the spatial-temporal process parameters and the noise-to-spatial variance ratios fixed to values supplied by the user. The output contains exact posterior samples of the fixed effects, the noise and process variances, the spatial-temporal random effects and, if required, leave-one-out predictive densities.
stvcLMexact( formula, data = parent.frame(), sp_coords, time_coords, cor.fn, process.type, sptParams, noise_sp_ratio, priors = "flat", n.samples, loopd = FALSE, loopd.method = "exact", verbose = TRUE, ... )stvcLMexact( formula, data = parent.frame(), sp_coords, time_coords, cor.fn, process.type, sptParams, noise_sp_ratio, priors = "flat", n.samples, loopd = FALSE, loopd.method = "exact", verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially-temporally varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
sp_coords |
an |
time_coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial-temporal dependence structure among the observations.
Supported covariance model key words are: |
process.type |
a quoted keyword specifying the model for the
spatial-temporal processes of the varying coefficients. Supported keywords
are |
sptParams |
fixed values of the spatial-temporal process parameters, a
list with tags |
noise_sp_ratio |
noise-to-spatial variance ratio(s) |
priors |
either |
n.samples |
number of posterior samples to be generated. |
loopd |
logical. If |
loopd.method |
character. Ignored if |
verbose |
logical. If |
... |
currently no additional argument. |
Suppose denotes the
spatial-temporal co-ordinates in at which the response is observed. With this function,
we fit the conjugate Bayesian hierarchical model
where denotes the covariates with
spatially-temporally varying coefficients, the processes are independent, and is the
spatial-temporal correlation matrix of the Gneiting (2002) family. We fix
the noise-to-spatial variance ratios , the process parameters and
, and the hyperparameters , ,
and . If process.type = 'independent',
each process has its own ; if
process.type = 'independent.shared', they share one. If
priors = "flat", we instead assign the prior .
The joint posterior distribution is available in closed form and is sampled exactly by composition,
where is inverse-gamma and the other two are Gaussian.
All of them depend on the data through the matrix
, with . The -dimensional vector is
drawn by a prior draw followed by a kriging correction (Matheron's rule;
Bhattacharya, Chakraborty and Mallick 2016), which needs only Cholesky factorizations. Posterior samples of the process
variances are obtained as . The
exact leave-one-out predictive densities are obtained in closed form from
the same factorizations.
An object of class stvcLMexact, which is a list with the
following tags -
a list of length 4, containing posterior samples of fixed
effects (beta, a n.samples matrix), the noise
variance (sigmaSq), the process variances (sigmaSq.z, an
n.samples matrix if process.type =
'independent', otherwise a vector), and the spatial-temporal effects
(z, an n.samples matrix whose rows
correspond to the -th varying
coefficient).
If loopd=TRUE, contains leave-one-out predictive
densities.
Values of the fixed parameters: phi_s,
phi_t and noise_sp_ratio.
a list of fit diagnostics, obtained from quantities the
fit computes anyway. Element numerical is a data frame with one row
(one row per process, if process.type = 'independent') and columns
min.pivot (the smallest relative Cholesky pivot of the
spatial-temporal correlation matrix and of ; values below 1e-8
indicate a nearly singular matrix), min.cor and max.cor (the
correlations of the two farthest-apart and of the two closest space-time
locations; values of min.cor above 0.95 suggest an effective range far
exceeding the extent of the data, values of max.cor below 0.05 nearly
uncorrelated space-time locations). If loopd.method = 'PSIS', element
pareto is a list with the Pareto diagnostic values
(k), the threshold above which they are unreliable
(threshold) and the number of values above it (n.high). If
verbose = TRUE, a "Diagnostics" section is printed when any threshold
is crossed.
The return object might include additional data used for subsequent prediction and/or model fit evaluation.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Bhattacharya A, Chakraborty A, Mallick BK (2016). "Fast sampling with Gaussian scale mixture priors in high-dimensional regression." Biometrika, 103(4), 985-991. doi:10.1093/biomet/asw042.
Gneiting T (2002). "Nonseparable, Stationary Covariance Functions for Space-Time Data." Journal of the American Statistical Association, 97(458), 590-600. doi:10.1198/016214502760047113.
T. Gneiting and P. Guttorp (2010). "Continuous-parameter spatio-temporal processes." In A.E. Gelfand, P.J. Diggle, M. Fuentes, and P Guttorp, editors, Handbook of Spatial Statistics, Chapman & Hall CRC Handbooks of Modern Statistical Methods, p 427-436. Taylor and Francis.
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
stvcLMstack(), stvcGLMexact(), spLMexact()
data(simSpaceTime) dat <- simSpaceTime[1:100, ] mod1 <- stvcLMexact(y_gauss ~ x1 + x2 + (x1), data = dat, sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent", sptParams = list(phi_s = c(2, 2), phi_t = c(4, 4)), noise_sp_ratio = c(0.1, 0.25), n.samples = 500, loopd = TRUE, verbose = FALSE) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[1:n], dat$z1_true)data(simSpaceTime) dat <- simSpaceTime[1:100, ] mod1 <- stvcLMexact(y_gauss ~ x1 + x2 + (x1), data = dat, sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent", sptParams = list(phi_s = c(2, 2), phi_t = c(4, 4)), noise_sp_ratio = c(0.1, 0.25), n.samples = 500, loopd = TRUE, verbose = FALSE) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[1:n], dat$z1_true)
Fits Bayesian linear models with spatially-temporally varying coefficients for a Gaussian response on a collection of candidate models, constructed from candidate values of the spatial-temporal process parameters and the noise-to-spatial variance ratios supplied by the user, and combines inference by stacking predictive densities.
stvcLMstack( formula, data = parent.frame(), sp_coords, time_coords, cor.fn, process.type, priors = "flat", candidate.models, n.samples, loopd.method = "exact", parallel = FALSE, solver = NULL, verbose = TRUE, ... )stvcLMstack( formula, data = parent.frame(), sp_coords, time_coords, cor.fn, process.type, priors = "flat", candidate.models, n.samples, loopd.method = "exact", parallel = FALSE, solver = NULL, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially-temporally varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
sp_coords |
an |
time_coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial-temporal dependence structure among the observations.
Supported covariance model key words are: |
process.type |
a quoted keyword specifying the model for the
spatial-temporal processes of the varying coefficients: |
priors |
either |
candidate.models |
an object of class |
n.samples |
number of posterior samples to be generated. |
loopd.method |
character. Valid inputs are |
parallel |
logical. If |
solver |
(optional) Specifies the name of the solver that will be used
to obtain optimal stacking weights for each candidate model. Default order
is |
verbose |
logical. If |
... |
currently no additional argument. |
Instead of assigning priors on the process parameters
, and the noise-to-spatial variance ratios
, we consider a set of candidate models
based on candidate values of these
parameters. For each , we sample exactly from the posterior
distribution (see stvcLMexact())
and find the leave-one-out predictive densities . The stacking weights solve
Candidate models that share the process parameters
are fitted together, building and factorizing the spatial-temporal
correlation matrices only once.
An object of class stvcLMstack, which is a list including the
following tags -
samplesa list of length equal to total number of candidate models
with each entry corresponding to a list of length 4, containing posterior
samples of fixed effects (beta), the noise variance
(sigmaSq), the process variances (sigmaSq.z) and the
spatial-temporal effects (z) for that model, as in
stvcLMexact().
loopda list of length equal to total number of candidate models with each entry containing leave-one-out predictive densities under that particular model.
n.modelsnumber of candidate models that are fit.
model.paramsa list with one element per candidate model, each a
named list of its parameters: phi_s, phi_t and
noise_sp_ratio (vectors of length if process.type =
'independent').
stacking.summarya matrix with one row per candidate model, containing its parameters and its optimal stacking weight, for display.
stacking.weightsa numeric vector of length equal to the number of candidate models storing the optimal stacking weights.
run.timea proc_time object with runtime details.
diagnosticsa list of diagnostics. Element numerical is a
data frame with one row per candidate model (per candidate model and
process, with columns model and process, if
process.type = 'independent') and columns min.pivot,
min.cor and max.cor, as in stvcLMexact(). If
loopd.method = 'PSIS', element pareto contains the Pareto
diagnostic values of each candidate model (k), the threshold
above which they are unreliable (threshold) and the number of values
above it for each model (n.high). Element solver describes the
optimization for the stacking weights: the solver used (used) and
its status (status), the installed and requested solvers, the search
order, the attempts with their status, and whether the fallback
loo::stacking_weights() was used. If verbose = TRUE, a
"Diagnostics" section is printed if there is an issue: numerical flags of
candidate models with stacking weight above 0.05 (extreme candidates with
negligible weight are expected in a stacking grid and are only counted),
Pareto values above the threshold for any model, and solver
problems.
This object can be used to make predictions at new locations or times with
posteriorPredict() and to sample from the stacked posterior with
stackedSampler().
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
Zhang L, Tang W, Banerjee S (2025). "Bayesian Geostatistics Using Predictive Stacking." Journal of the American Statistical Association, In press. doi:10.1080/01621459.2025.2566449.
stvcLMexact(), stvcGLMstack(), spLMstack()
set.seed(1234) data(simSpaceTime) dat <- simSpaceTime[1:100, ] # processes sharing (phi_s, phi_t, noise_sp_ratio): scalar candidates mod.list <- candidateModels(list(phi_s = c(1, 2, 3), phi_t = c(2, 4, 8), noise_sp_ratio = c(0.1, 0.25)), "cartesian") mod1 <- stvcLMstack(y_gauss ~ x1 + x2 + (x1), data = dat, sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent.shared", candidate.models = mod.list, n.samples = 500) post_samps <- stackedSampler(mod1) n <- nrow(dat) cor(apply(post_samps$z[1:n, ], 1, median), dat$z1_true) # independent processes (r = 2): vector-valued candidates via list() mod.list2 <- candidateModels(list(phi_s = list(c(2, 2), c(3, 3)), phi_t = list(c(4, 4), c(8, 8)), noise_sp_ratio = list(c(0.1, 0.25), c(0.25, 0.5))), "cartesian") mod2 <- stvcLMstack(y_gauss ~ x1 + x2 + (x1), data = dat, sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent", candidate.models = mod.list2, n.samples = 500, verbose = FALSE)set.seed(1234) data(simSpaceTime) dat <- simSpaceTime[1:100, ] # processes sharing (phi_s, phi_t, noise_sp_ratio): scalar candidates mod.list <- candidateModels(list(phi_s = c(1, 2, 3), phi_t = c(2, 4, 8), noise_sp_ratio = c(0.1, 0.25)), "cartesian") mod1 <- stvcLMstack(y_gauss ~ x1 + x2 + (x1), data = dat, sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent.shared", candidate.models = mod.list, n.samples = 500) post_samps <- stackedSampler(mod1) n <- nrow(dat) cor(apply(post_samps$z[1:n, ], 1, median), dat$z1_true) # independent processes (r = 2): vector-valued candidates via list() mod.list2 <- candidateModels(list(phi_s = list(c(2, 2), c(3, 3)), phi_t = list(c(4, 4), c(8, 8)), noise_sp_ratio = list(c(0.1, 0.25), c(0.25, 0.5))), "cartesian") mod2 <- stvcLMstack(y_gauss ~ x1 + x2 + (x1), data = dat, sp_coords = as.matrix(dat[, c("s1", "s2")]), time_coords = as.matrix(dat[, "t_coords"]), cor.fn = "gneiting-decay", process.type = "independent", candidate.models = mod.list2, n.samples = 500, verbose = FALSE)
Make a surface plot
surfaceplot( tab, coords_name, var_name, h = 8, col.pal, mark_points = FALSE, title = NULL )surfaceplot( tab, coords_name, var_name, h = 8, col.pal, mark_points = FALSE, title = NULL )
tab |
a data-frame containing spatial co-ordinates and the variable to plot |
coords_name |
name of the two columns that contains the co-ordinates of the points, also used as the axis labels |
var_name |
name of the column containing the variable to be plotted |
h |
integer; (optional) controls smoothness of the spatial interpolation
as appearing in the |
col.pal |
Optional; color palette, preferably divergent, use
|
mark_points |
Logical; if |
title |
(optional) a title for the plot. Default is no title. |
a ggplot object containing the surface plot
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
data(simSpatial) plot1 <- surfaceplot(simSpatial, coords_name = c("s1", "s2"), var_name = "z_true") plot1 # try your favourite color palette plot2 <- surfaceplot(simSpatial, coords_name = c("s1", "s2"), var_name = "z_true", col.pal = hcl.colors(100, "PuOr", rev = TRUE)) plot2data(simSpatial) plot1 <- surfaceplot(simSpatial, coords_name = c("s1", "s2"), var_name = "z_true") plot1 # try your favourite color palette plot2 <- surfaceplot(simSpatial, coords_name = c("s1", "s2"), var_name = "z_true", col.pal = hcl.colors(100, "PuOr", rev = TRUE)) plot2
Make two side-by-side surface plots, particularly useful towards a comparative study of two spatial surfaces.
surfaceplot2( tab, coords_name, var1_name, var2_name, h = 8, col.pal, mark_points = FALSE, titles = c(var1_name, var2_name) )surfaceplot2( tab, coords_name, var1_name, var2_name, h = 8, col.pal, mark_points = FALSE, titles = c(var1_name, var2_name) )
tab |
a data-frame containing spatial co-ordinates and the variables to plot |
coords_name |
name of the two columns that contains the co-ordinates of the points, also used as the axis labels |
var1_name |
name of the column containing the first variable to be plotted |
var2_name |
name of the column containing the second variable to be plotted |
h |
integer; (optional) controls smoothness of the spatial interpolation
as appearing in the |
col.pal |
Optional; color palette, preferably divergent, use
|
mark_points |
Logical; if |
titles |
a character vector of length 2, the titles of the two plots.
Default is the names of the two variables, |
a list containing two ggplot objects, which share the colour scale
(one legend serves both, e.g. with patchwork::wrap_plots(plots) + patchwork::plot_layout(guides = "collect"))
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
data(simSpatial) plots_2 <- surfaceplot2(simSpatial, coords_name = c("s1", "s2"), var1_name = "z_true", var2_name = "y_gauss", titles = c("True spatial effect", "Gaussian response")) plots_2data(simSpatial) plots_2 <- surfaceplot2(simSpatial, coords_name = c("s1", "s2"), var1_name = "z_true", var2_name = "y_gauss", titles = c("True spatial effect", "Gaussian response")) plots_2
Fits a Bayesian generalized linear model with spatially varying coefficients under fixed values of the spatial process parameters and some auxiliary model parameters. The output contains posterior samples of the fixed effects, the spatially varying coefficients and, if required, finds leave-one-out predictive densities.
svcGLMexact( formula, data = parent.frame(), family, coords, cor.fn, process.type, spParams, priors, boundary = 0.5, n.samples, loopd = FALSE, loopd.method = "exact", CV.K = 10, loopd.nMC = 500, verbose = TRUE, ... )svcGLMexact( formula, data = parent.frame(), family, coords, cor.fn, process.type, spParams, priors, boundary = 0.5, n.samples, loopd = FALSE, loopd.method = "exact", CV.K = 10, loopd.nMC = 500, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
family |
Specifies the distribution of the response as a member of the
exponential family. Supported options are |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
process.type |
a quoted keyword specifying the model for the spatial
processes: |
spParams |
fixed values of the spatial process parameters, a list with
tags |
priors |
(optional) a list with each tag corresponding to a
hyperparameter name and containing hyperprior details. Valid tags include
|
boundary |
Specifies the boundary adjustment parameter. Must be a real number between 0 and 1. Default is 0.5. |
n.samples |
number of posterior samples to be generated. |
loopd |
logical. If |
loopd.method |
character. Ignored if |
CV.K |
An integer between 10 and 20. Considered only if
|
loopd.nMC |
Number of Monte Carlo samples to be used to evaluate
leave-one-out predictive densities when |
verbose |
logical. If |
... |
currently no additional argument. |
With this function, we fit a Bayesian hierarchical spatially
varying coefficients generalized linear model by sampling exactly from the
joint posterior distribution utilizing the generalized conjugate
multivariate distribution theory (Bradley and Clinch 2024). Suppose
denotes the spatial locations in
at which the response is
observed, with endowed with a probability law from the natural
exponential family
for some positive parameter and unit log partition function
. Here, denotes the covariates with
spatially varying coefficients. The supported families ('poisson',
'binomial' and 'binary') and the hierarchical model are those of
stvcGLMexact(), with
where is the exponential or Matern spatial
correlation matrix with decay and smoothness . If
process.type = 'independent', each process has its own ; if process.type = 'independent.shared', they share one. If
process.type = 'multivariate', is a
multivariate Gaussian process with correlation matrix and an cross-covariance matrix with an
inverse-Wishart prior. We fix the process parameters and the
hyperparameters , , and
; their defaults are as in stvcGLMexact().
An object of class svcGLMexact, which is a list with the
following tags -
details of the priors used, containing the values of the
boundary adjustment parameter (boundary), the variance parameter of the
fine-scale variation term (sigmaSq.xi) and others.
a list of length 3, containing posterior samples of fixed
effects (beta), the spatially varying coefficients (z, an
n.samples matrix whose rows correspond to the -th varying coefficient) and the fine-scale
variation term (xi).
If loopd=TRUE, contains leave-one-out predictive
densities.
Values of the fixed parameters: phi and
nu (NA for the exponential correlation function).
a list of diagnostics. Element numerical is a
data frame with one row (one row per process, if process.type =
'independent') and columns min.pivot (the smallest relative
Cholesky pivot of the spatial correlation matrix;
values below 1e-8 indicate a nearly singular correlation matrix),
min.cor and max.cor (the correlations of the two
farthest-apart and of the two closest locations; values of min.cor
above 0.95 suggest an effective range far exceeding the extent of the data,
values of max.cor below 0.05 nearly uncorrelated locations). If
verbose = TRUE, a "Diagnostics" section is printed when any threshold
is crossed.
The return object might include additional data that can be used for subsequent prediction and/or model fit evaluation.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Bradley JR, Clinch M (2024). "Generating Independent Replicates Directly from the Posterior Distribution for a Class of Spatial Hierarchical Models." Journal of Computational and Graphical Statistics, 0(0), 1-17. doi:10.1080/10618600.2024.2365728.
Pan S, Zhang L, Bradley JR, Banerjee S (2025). "Bayesian Inference for Spatial-temporal Non-Gaussian Data Using Predictive Stacking." Bayesian Analysis, In Press. doi:10.1214/25-BA1582.
Vehtari A, Gelman A, Gabry J (2017). "Practical Bayesian Model Evaluation Using Leave-One-out Cross-Validation and WAIC." Statistics and Computing, 27(5), 1413-1432. ISSN 0960-3174. doi:10.1007/s11222-016-9696-4.
svcGLMstack(), svcLMexact(), spGLMexact(), stvcGLMexact()
data(simSpatial) dat <- simSpatial[1:150, ] mod1 <- svcGLMexact(y_svc_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent", spParams = list(phi = c(8, 4), nu = c(1.5, 1.5)), n.samples = 100, verbose = FALSE) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[n + 1:n], dat$z_true)data(simSpatial) dat <- simSpatial[1:150, ] mod1 <- svcGLMexact(y_svc_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent", spParams = list(phi = c(8, 4), nu = c(1.5, 1.5)), n.samples = 100, verbose = FALSE) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[n + 1:n], dat$z_true)
Fits Bayesian generalized linear models with spatially varying coefficients on a collection of candidate models constructed from candidate values of the spatial process parameters and the boundary adjustment parameter supplied by the user, and combines inference by stacking predictive densities. See Pan, Zhang, Bradley, and Banerjee (2025) for more details.
svcGLMstack( formula, data = parent.frame(), family, coords, cor.fn, process.type, priors, candidate.models, n.samples, loopd.controls, parallel = FALSE, solver = NULL, verbose = TRUE, ... )svcGLMstack( formula, data = parent.frame(), family, coords, cor.fn, process.type, priors, candidate.models, n.samples, loopd.controls, parallel = FALSE, solver = NULL, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
family |
Specifies the distribution of the response as a member of the
exponential family. Supported options are |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
process.type |
a quoted keyword specifying the model for the spatial
processes: |
priors |
(optional) a list with each tag corresponding to a
hyperparameter name and containing hyperprior details. Valid tags include
|
candidate.models |
an object of class |
n.samples |
number of samples to be drawn from the posterior distribution. |
loopd.controls |
a list with details on how leave-one-out predictive
densities (LOO-PD) are to be calculated, with tags |
parallel |
logical. If |
solver |
(optional) Specifies the name of the solver that will be used
to obtain optimal stacking weights for each candidate model. Default order
is |
verbose |
logical. If |
... |
currently no additional argument. |
Candidate models that share the process parameters are fitted together: the spatial correlation matrices and all the
pre-processing for the leave-one-out predictive densities are computed once
and shared across their boundary values, and the groups of such candidates
are the units of parallel work.
An object of class svcGLMstack, which is a list including the
following tags -
samplesa list of length equal to total number of candidate models
with each entry corresponding to a list of length 3, containing posterior
samples of fixed effects (beta), the spatially varying coefficients
(z), and fine scale variation xi for that model.
loopda list of length equal to total number of candidate models with each entry containing leave-one-out predictive densities under that particular model.
n.modelsnumber of candidate models that are fit.
model.paramsa list with one element per candidate model, each a
named list of its parameters: phi, nu (NA for the
exponential correlation function) and boundary.
stacking.summarya matrix with one row per candidate model, containing its parameters and its optimal stacking weight, for display.
stacking.weightsa numeric vector of length equal to the number of candidate models storing the optimal stacking weights.
run.timea proc_time object with runtime details.
diagnosticsa list of diagnostics, as in stvcGLMstack(): element
numerical (columns min.pivot, min.cor and
max.cor, see svcGLMexact()) and element solver. If
verbose = TRUE, a "Diagnostics" section is printed if there is an
issue.
This object can be further used to recover posterior samples of the scale
parameters in the model with recoverGLMscale(), to make predictions at new
locations with posteriorPredict(), and to sample from the stacked
posterior with stackedSampler().
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Pan S, Zhang L, Bradley JR, Banerjee S (2025). "Bayesian Inference for Spatial-temporal Non-Gaussian Data Using Predictive Stacking." Bayesian Analysis, In Press. doi:10.1214/25-BA1582.
svcGLMexact(), svcLMstack(), spGLMstack(), stvcGLMstack()
set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] # processes sharing (phi, nu): scalar candidates mod.list <- candidateModels(list(phi = c(4, 8), nu = c(1.5), boundary = c(0.5, 0.75)), "cartesian") mod1 <- svcGLMstack(y_svc_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent.shared", candidate.models = mod.list, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), n.samples = 500) post_samps <- stackedSampler(mod1)set.seed(1234) data(simSpatial) dat <- simSpatial[1:100, ] # processes sharing (phi, nu): scalar candidates mod.list <- candidateModels(list(phi = c(4, 8), nu = c(1.5), boundary = c(0.5, 0.75)), "cartesian") mod1 <- svcGLMstack(y_svc_pois ~ x1 + x2 + (x1), data = dat, family = "poisson", coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent.shared", candidate.models = mod.list, loopd.controls = list(method = "CV", CV.K = 10, nMC = 500), n.samples = 500) post_samps <- stackedSampler(mod1)
Fits a Bayesian linear model with spatially varying coefficients for a Gaussian response, with the spatial process parameters and the noise-to-spatial variance ratios fixed to values supplied by the user. The output contains exact posterior samples of the fixed effects, the noise and process variances, the spatially varying coefficients and, if required, leave-one-out predictive densities.
svcLMexact( formula, data = parent.frame(), coords, cor.fn, process.type, spParams, noise_sp_ratio, priors = "flat", n.samples, loopd = FALSE, loopd.method = "exact", verbose = TRUE, ... )svcLMexact( formula, data = parent.frame(), coords, cor.fn, process.type, spParams, noise_sp_ratio, priors = "flat", n.samples, loopd = FALSE, loopd.method = "exact", verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
process.type |
a quoted keyword specifying the model for the spatial
processes of the varying coefficients. Supported keywords are
|
spParams |
fixed values of the spatial process parameters, a list with
tags |
noise_sp_ratio |
noise-to-spatial variance ratio(s) |
priors |
either |
n.samples |
number of posterior samples to be generated. |
loopd |
logical. If |
loopd.method |
character. Ignored if |
verbose |
logical. If |
... |
currently no additional argument. |
Suppose denotes the
spatial locations in at which the
response is observed. With this function, we fit the conjugate
Bayesian hierarchical model
where denotes the covariates with spatially
varying coefficients, the processes are independent,
and is the exponential or Matern spatial
correlation matrix with decay and smoothness . We fix the
noise-to-spatial variance ratios , the process parameters and , and the
hyperparameters , , and
. If process.type = 'independent', each process has its
own ; if process.type =
'independent.shared', they share one. If priors = "flat", we instead
assign the prior .
The joint posterior distribution is available in closed form and is sampled exactly by composition,
where is inverse-gamma and the other two are Gaussian.
All of them depend on the data through the matrix
, with . The -dimensional vector is
drawn by a prior draw followed by a kriging correction (Matheron's rule;
Bhattacharya, Chakraborty and Mallick 2016), which needs only Cholesky factorizations. The exact leave-one-out predictive
densities are obtained in closed form from the same factorizations. The
computations are those of stvcLMexact(), with a spatial correlation
function in place of the spatial-temporal one.
An object of class svcLMexact, which is a list with the
following tags -
a list of length 4, containing posterior samples of fixed
effects (beta, a n.samples matrix), the noise
variance (sigmaSq), the process variances (sigmaSq.z, an
n.samples matrix if process.type =
'independent', otherwise a vector), and the spatially varying coefficients
(z, an n.samples matrix whose rows
correspond to the -th varying
coefficient).
If loopd=TRUE, contains leave-one-out predictive
densities.
Values of the fixed parameters: phi, nu
(NA for the exponential correlation function) and
noise_sp_ratio.
a list of fit diagnostics, obtained from quantities the
fit computes anyway. Element numerical is a data frame with one row
(one row per process, if process.type = 'independent') and columns
min.pivot (the smallest relative Cholesky pivot of the spatial
correlation matrix and of ; values below 1e-8 indicate a nearly
singular matrix), min.cor and max.cor (the correlations of the
two farthest-apart and of the two closest locations; values of
min.cor above 0.95 suggest an effective range far exceeding the
extent of the data, values of max.cor below 0.05 nearly uncorrelated
locations). If loopd.method = 'PSIS', element pareto is a list
with the Pareto diagnostic values (k), the threshold above
which they are unreliable (threshold) and the number of values above
it (n.high). If verbose = TRUE, a "Diagnostics" section is
printed when any threshold is crossed.
The return object might include additional data used for subsequent prediction and/or model fit evaluation.
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Bhattacharya A, Chakraborty A, Mallick BK (2016). "Fast sampling with Gaussian scale mixture priors in high-dimensional regression." Biometrika, 103(4), 985-991. doi:10.1093/biomet/asw042.
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
svcLMstack(), svcGLMexact(), spLMexact(), stvcLMexact()
data(simSpatial) dat <- simSpatial[1:200, ] # varying intercept and varying slope of x1, each with its own parameters mod1 <- svcLMexact(y_svc ~ x1 + x2 + (x1), data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent", spParams = list(phi = c(8, 4), nu = c(1.5, 1.5)), noise_sp_ratio = c(0.25, 0.25), n.samples = 500, loopd = TRUE, verbose = FALSE) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[1:n], dat$z2_true) cor(z_hat[n + 1:n], dat$z_true)data(simSpatial) dat <- simSpatial[1:200, ] # varying intercept and varying slope of x1, each with its own parameters mod1 <- svcLMexact(y_svc ~ x1 + x2 + (x1), data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent", spParams = list(phi = c(8, 4), nu = c(1.5, 1.5)), noise_sp_ratio = c(0.25, 0.25), n.samples = 500, loopd = TRUE, verbose = FALSE) # rows 1, ..., n of z hold the varying intercept, rows n+1, ..., 2n the # varying slope of x1 n <- nrow(dat) z_hat <- apply(mod1$samples$z, 1, median) cor(z_hat[1:n], dat$z2_true) cor(z_hat[n + 1:n], dat$z_true)
Fits Bayesian linear models with spatially varying coefficients for a Gaussian response on a collection of candidate models, constructed from candidate values of the spatial process parameters and the noise-to-spatial variance ratios supplied by the user, and combines inference by stacking predictive densities.
svcLMstack( formula, data = parent.frame(), coords, cor.fn, process.type, priors = "flat", candidate.models, n.samples, loopd.method = "exact", parallel = FALSE, solver = NULL, verbose = TRUE, ... )svcLMstack( formula, data = parent.frame(), coords, cor.fn, process.type, priors = "flat", candidate.models, n.samples, loopd.method = "exact", parallel = FALSE, solver = NULL, verbose = TRUE, ... )
formula |
a symbolic description of the regression model to be fit. Variables in parenthesis are assigned spatially varying coefficients. See examples. |
data |
an optional data frame containing the variables in the model.
If not found in |
coords |
an |
cor.fn |
a quoted keyword that specifies the correlation function used
to model the spatial dependence structure among the observations. Supported
covariance model key words are: |
process.type |
a quoted keyword specifying the model for the spatial
processes of the varying coefficients: |
priors |
either |
candidate.models |
an object of class |
n.samples |
number of posterior samples to be generated. |
loopd.method |
character. Valid inputs are |
parallel |
logical. If |
solver |
(optional) Specifies the name of the solver that will be used
to obtain optimal stacking weights for each candidate model. Default order
is |
verbose |
logical. If |
... |
currently no additional argument. |
Instead of assigning priors on the process parameters ,
and the noise-to-spatial variance ratios , we
consider a set of candidate models
based on candidate values of these parameters. For each , we sample
exactly from the posterior distribution (see svcLMexact()) and find the leave-one-out predictive densities
. The stacking weights solve
Candidate models that share the process parameters are
fitted together, building and factorizing the spatial correlation matrices
only once, and the groups of such candidates are the units of parallel
work.
An object of class svcLMstack, which is a list including the
following tags -
samplesa list of length equal to total number of candidate models
with each entry corresponding to a list of length 4, containing posterior
samples of fixed effects (beta), the noise variance
(sigmaSq), the process variances (sigmaSq.z) and the
spatially varying coefficients (z) for that model, as in
svcLMexact().
loopda list of length equal to total number of candidate models with each entry containing leave-one-out predictive densities under that particular model.
n.modelsnumber of candidate models that are fit.
model.paramsa list with one element per candidate model, each a
named list of its parameters: phi, nu (NA for the
exponential correlation function) and noise_sp_ratio (vectors of
length if process.type = 'independent').
stacking.summarya matrix with one row per candidate model, containing its parameters and its optimal stacking weight, for display.
stacking.weightsa numeric vector of length equal to the number of candidate models storing the optimal stacking weights.
run.timea proc_time object with runtime details.
diagnosticsa list of diagnostics. Element numerical is a
data frame with one row per candidate model (per candidate model and
process, with columns model and process, if
process.type = 'independent') and columns min.pivot,
min.cor and max.cor, as in svcLMexact(). If
loopd.method = 'PSIS', element pareto contains the Pareto
diagnostic values of each candidate model (k), the threshold
above which they are unreliable (threshold) and the number of values
above it for each model (n.high). Element solver describes the
optimization for the stacking weights: the solver used (used) and
its status (status), the installed and requested solvers, the search
order, the attempts with their status, and whether the fallback
loo::stacking_weights() was used. If verbose = TRUE, a
"Diagnostics" section is printed if there is an issue: numerical flags of
candidate models with stacking weight above 0.05 (extreme candidates with
negligible weight are expected in a stacking grid and are only counted),
Pareto values above the threshold for any model, and solver
problems.
This object can be used to make predictions at new locations with
posteriorPredict() and to sample from the stacked posterior with
stackedSampler().
Soumyakanti Pan [email protected],
Sudipto Banerjee [email protected]
Vehtari A, Simpson D, Gelman A, Yao Y, Gabry J (2024). "Pareto Smoothed Importance Sampling." Journal of Machine Learning Research, 25(72), 1-58. URL https://jmlr.org/papers/v25/19-556.html.
Zhang L, Tang W, Banerjee S (2025). "Bayesian Geostatistics Using Predictive Stacking." Journal of the American Statistical Association, In press. doi:10.1080/01621459.2025.2566449.
svcLMexact(), svcGLMstack(), spLMstack(), stvcLMstack()
set.seed(1234) data(simSpatial) dat <- simSpatial[1:200, ] # independent processes (r = 2): vector-valued candidates via list() mod.list <- candidateModels(list(phi = list(c(4, 4), c(8, 4), c(8, 8)), nu = list(c(1.5, 1.5)), noise_sp_ratio = list(c(0.1, 0.1), c(0.25, 0.25))), "cartesian") mod1 <- svcLMstack(y_svc ~ x1 + x2 + (x1), data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent", candidate.models = mod.list, n.samples = 500) post_samps <- stackedSampler(mod1) n <- nrow(dat) cor(apply(post_samps$z[n + 1:n, ], 1, median), dat$z_true)set.seed(1234) data(simSpatial) dat <- simSpatial[1:200, ] # independent processes (r = 2): vector-valued candidates via list() mod.list <- candidateModels(list(phi = list(c(4, 4), c(8, 4), c(8, 8)), nu = list(c(1.5, 1.5)), noise_sp_ratio = list(c(0.1, 0.1), c(0.25, 0.25))), "cartesian") mod1 <- svcLMstack(y_svc ~ x1 + x2 + (x1), data = dat, coords = as.matrix(dat[, c("s1", "s2")]), cor.fn = "matern", process.type = "independent", candidate.models = mod.list, n.samples = 500) post_samps <- stackedSampler(mod1) n <- nrow(dat) cor(apply(post_samps$z[n + 1:n, ], 1, median), dat$z_true)