## ----setup, include=FALSE----------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4.5 ) set.seed(20260729) ## ----design------------------------------------------------------------------- library(Matrix) library(mvtnorm) library(ZINB.GP) make_design <- function(n_space, n_time, mean_replicates) { cell_n <- matrix( rpois(n_space * n_time, mean_replicates), nrow = n_space ) cells <- expand.grid( spatial = seq_len(n_space), temporal = seq_len(n_time) ) spatial_id <- rep(cells$spatial, times = as.vector(cell_n)) temporal_id <- rep(cells$temporal, times = as.vector(cell_n)) n <- length(spatial_id) Vs_full <- as.matrix(sparseMatrix( i = seq_len(n), j = spatial_id, x = 1, dims = c(n, n_space) )) Vt_full <- as.matrix(sparseMatrix( i = seq_len(n), j = temporal_id, x = 1, dims = c(n, n_time) )) list(Vs_full = Vs_full, Vt_full = Vt_full, cell_n = cell_n) } n_space <- 12 n_time <- 8 design <- make_design(n_space, n_time, mean_replicates = 3) N <- nrow(design$Vs_full) N ## ----distances---------------------------------------------------------------- coords <- cbind(runif(n_space), runif(n_space)) * 1000 time_coord <- matrix(0:(n_time - 1) * 50, ncol = 1) Ds <- as.matrix(dist(coords)) Dt <- as.matrix(dist(time_coord)) Vs <- design$Vs_full[, -1, drop = FALSE] Vt <- design$Vt_full[, -1, drop = FALSE] stopifnot( ncol(Vs) + 1 == nrow(Ds), ncol(Vt) + 1 == nrow(Dt), nrow(Vs) == nrow(Vt) ) ## ----simulate----------------------------------------------------------------- noisy_covariance <- function(distance, length_scale, sigma, kappa) { correlation <- exp(-(distance^2) / length_scale^2) sigma^2 * (kappa * correlation + (1 - kappa) * diag(nrow(distance))) } spatial_distance <- Ds[-1, -1, drop = FALSE] temporal_distance <- Dt[-1, -1, drop = FALSE] a <- drop(rmvnorm(1, sigma = noisy_covariance( spatial_distance, length_scale = 350, sigma = 1, kappa = 0.5 ))) c <- drop(rmvnorm(1, sigma = noisy_covariance( spatial_distance, length_scale = 250, sigma = 1, kappa = 0.5 ))) b <- drop(rmvnorm(1, sigma = noisy_covariance( temporal_distance, length_scale = 100, sigma = 0.5, kappa = 0.2 ))) d <- drop(rmvnorm(1, sigma = noisy_covariance( temporal_distance, length_scale = 150, sigma = 0.5, kappa = 0.2 ))) x <- rnorm(N) X <- cbind("(Intercept)" = 1, x = x) alpha <- c(-0.25, 0.25) beta <- c(0.50, -0.25) r <- 1 eta_at_risk <- drop(X %*% alpha + Vs %*% a + Vt %*% b) p_at_risk <- plogis(eta_at_risk) at_risk <- rbinom(N, size = 1, prob = p_at_risk) eta_count <- drop(X %*% beta + Vs %*% c + Vt %*% d) mu_count <- r * exp(eta_count) y <- integer(N) y[at_risk == 1] <- rnbinom( sum(at_risk == 1), size = r, mu = mu_count[at_risk == 1] ) c(observations = N, zeros = sum(y == 0), positive = sum(y > 0)) ## ----simulated-heatmap-------------------------------------------------------- cell_id <- max.col(design$Vs_full) + n_space * (max.col(design$Vt_full) - 1) cell_sum <- tapply(y, cell_id, sum) cell_total <- numeric(n_space * n_time) cell_total[as.integer(names(cell_sum))] <- cell_sum cell_total <- matrix(cell_total, nrow = n_space) image( x = seq_len(n_time), y = seq_len(n_space), z = t(log1p(cell_total)), xlab = "Time", ylab = "Spatial location", main = "Simulated cell totals: log(1 + count)", col = hcl.colors(20, "YlOrRd", rev = TRUE) ) ## ----fit, eval=FALSE---------------------------------------------------------- # fit <- ZINB_GP( # X = X, # y = y, # coords = coords, # Vs = Vs, # Vt = Vt, # Ds = Ds, # Dt = Dt, # nsim = 20000, # burn = 5000, # thin = 5, # save_ypred = TRUE, # print_progress = TRUE, # use_count_gp = TRUE, # use_inflation_gp = TRUE # ) ## ----count-only, eval=FALSE--------------------------------------------------- # fit_count_gp <- ZINB_GP( # X = X, y = y, coords = coords, # Vs = Vs, Vt = Vt, Ds = Ds, Dt = Dt, # nsim = 20000, burn = 5000, thin = 5, # use_count_gp = TRUE, # use_inflation_gp = FALSE # ) ## ----prediction-inputs, eval=FALSE-------------------------------------------- # coords_future <- rbind( # c(250, 250), # c(500, 500), # c(750, 750) # ) # times_future <- matrix(c(400, 450), ncol = 1) # prediction_grid <- expand.grid( # spatial = seq_len(nrow(coords_future)), # temporal = seq_len(nrow(times_future)) # ) # # coords_new <- coords_future[prediction_grid$spatial, , drop = FALSE] # time_coords_new <- times_future[ # prediction_grid$temporal, , # drop = FALSE # ] # X_new <- cbind( # "(Intercept)" = 1, # x = rep(0, nrow(prediction_grid)) # ) # # prediction_inputs <- make_prediction_inputs( # coords = coords, # time_coords = time_coord, # coords_new = coords_new, # time_coords_new = time_coords_new # ) ## ----predict-new, eval=FALSE-------------------------------------------------- # predicted <- do.call( # predict, # c( # list(object = fit, X = X_new), # prediction_inputs # ) # ) # # apply(predicted$Y_pred, 2, quantile, probs = c(0.025, 0.5, 0.975)) ## ----intervals, eval=FALSE---------------------------------------------------- # apply(fit$Alpha, 2, quantile, probs = c(0.025, 0.5, 0.975)) # apply(fit$Beta, 2, quantile, probs = c(0.025, 0.5, 0.975))