library(sf)
library(tidyverse)
library(spdep)
library(INLA)
library(ggthemes)
library(knitr)Spatial and Temporal Analysis of TB in Nam Dinh Using INLA
Introduction
This document outlines the process of analyzing spatial and temporal data using Integrated Nested Laplace Approximations (INLA) in R. We aim to explore the effects of several predictors on observed outcomes across different spatial and temporal scales.
Setup
Load Required Libraries
Reading layer `merged_df1' from data source `E:\inla\merged_df1.geojson' using driver `GeoJSON'
Simple feature collection with 2260 features and 24 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 105.9219 ymin: 19.95672 xmax: 106.5805 ymax: 20.50066
Geodetic CRS: WGS 84
Calculate TB notifications by time
notif_data <- gdf %>%
group_by(year) %>%
summarise(
Total_Observed = sum(adjusted_observed),
Total_Population = sum(pop)
) %>%
mutate(notif = (Total_Observed / Total_Population) * 1e5)
notif_dataSimple feature collection with 10 features and 4 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 105.9219 ymin: 19.95672 xmax: 106.5805 ymax: 20.50066
Geodetic CRS: WGS 84
# A tibble: 10 × 5
year Total_Observed Total_Population geometry notif
* <int> <dbl> <int> <POLYGON [°]> <dbl>
1 2013 1488 1846126 ((106.1746 19.99359, 106.1749 19… 80.6
2 2014 1457 1851759 ((106.1746 19.99359, 106.1749 19… 78.7
3 2015 1535 1796891 ((106.1746 19.99359, 106.1749 19… 85.4
4 2016 1556 1792452 ((106.1746 19.99359, 106.1749 19… 86.8
5 2017 1753 1788225 ((106.1746 19.99359, 106.1749 19… 98.0
6 2018 1654 1784206 ((106.1746 19.99359, 106.1749 19… 92.7
7 2019 1688 1780865 ((106.1746 19.99359, 106.1749 19… 94.8
8 2020 1369 1780333 ((106.1746 19.99359, 106.1749 19… 76.9
9 2021 1111 1836268 ((106.1746 19.99359, 106.1749 19… 60.5
10 2022 1276 1830794 ((106.1746 19.99359, 106.1749 19… 69.7
ggplot(notif_data, aes(x = year, y = notif)) +
geom_line() +
geom_point() +
theme_Publication() +
labs(
title = "",
x = "Year",
y = "TB case notifications per 100,000"
)Moran’s I Calculation
weights <- poly2nb(subset_gdf, queen = TRUE)
weights <- nb2listw(weights, style = "W", zero.policy = TRUE)
gdf$adjusted_observed[gdf$adjusted_observed==0] <- NA
gdf$SMR <- gdf$adjusted_observed / gdf$Eunique_years <- unique(gdf$year)
# Initialize an empty list to store results
moran_results <- list()
# Loop through each year and calculate Moran's I
for (current_year in unique_years) {
# Subset data for the specific year
year_data <- dplyr::filter(gdf, year == current_year)
# Check if year_data is empty after subsetting
if (nrow(year_data) == 0) {
cat(sprintf("Moran's I for year %d: No data for this year\n", current_year))
moran_results[[as.character(current_year)]] <- list(year = current_year, moran = NA, p_value = NA, warning = "No data for this year")
next
}
# Convert 'SMR' to numeric
year_data$SMR <- as.numeric(as.character(year_data$SMR))
# Replace NA values in SMR with 0
year_data$SMR[is.na(year_data$SMR)] <- 0
# Ensure the order of SMR values matches the spatial units in the weights matrix
if (length(year_data$SMR) != length(weights$neighbours)) {
cat(sprintf("Moran's I for year %d: Mismatch in data length and weights matrix\n", current_year))
moran_results[[as.character(current_year)]] <- list(year = current_year, moran = NA, p_value = NA, warning = "Mismatch in data length and weights matrix")
next
}
# Perform Moran's I test
moran_test <- moran.test(year_data$SMR, weights, zero.policy = TRUE)
cat(sprintf("Moran's I for year %d is %f with a normal p-value of %f\n", current_year, moran_test$estimate, moran_test$p.value))
# Store results in the list
moran_results[[as.character(current_year)]] <- list(year = current_year, moran = moran_test$estimate, p_value = moran_test$p.value)
}Moran's I for year 2013 is 0.094222 with a normal p-value of 0.007713
Moran's I for year 2013 is -0.004444 with a normal p-value of 0.007713
Moran's I for year 2013 is 0.001659 with a normal p-value of 0.007713
Moran's I for year 2014 is 0.117018 with a normal p-value of 0.001499
Moran's I for year 2014 is -0.004444 with a normal p-value of 0.001499
Moran's I for year 2014 is 0.001675 with a normal p-value of 0.001499
Moran's I for year 2015 is 0.081503 with a normal p-value of 0.017892
Moran's I for year 2015 is -0.004444 with a normal p-value of 0.017892
Moran's I for year 2015 is 0.001676 with a normal p-value of 0.017892
Moran's I for year 2016 is 0.090854 with a normal p-value of 0.010018
Moran's I for year 2016 is -0.004444 with a normal p-value of 0.010018
Moran's I for year 2016 is 0.001679 with a normal p-value of 0.010018
Moran's I for year 2017 is 0.070746 with a normal p-value of 0.033001
Moran's I for year 2017 is -0.004444 with a normal p-value of 0.033001
Moran's I for year 2017 is 0.001673 with a normal p-value of 0.033001
Moran's I for year 2018 is 0.059970 with a normal p-value of 0.057819
Moran's I for year 2018 is -0.004444 with a normal p-value of 0.057819
Moran's I for year 2018 is 0.001676 with a normal p-value of 0.057819
Moran's I for year 2019 is 0.129636 with a normal p-value of 0.000533
Moran's I for year 2019 is -0.004444 with a normal p-value of 0.000533
Moran's I for year 2019 is 0.001678 with a normal p-value of 0.000533
Moran's I for year 2020 is 0.069116 with a normal p-value of 0.035978
Moran's I for year 2020 is -0.004444 with a normal p-value of 0.035978
Moran's I for year 2020 is 0.001671 with a normal p-value of 0.035978
Moran's I for year 2021 is 0.043341 with a normal p-value of 0.122065
Moran's I for year 2021 is -0.004444 with a normal p-value of 0.122065
Moran's I for year 2021 is 0.001683 with a normal p-value of 0.122065
Moran's I for year 2022 is 0.051127 with a normal p-value of 0.086796
Moran's I for year 2022 is -0.004444 with a normal p-value of 0.086796
Moran's I for year 2022 is 0.001668 with a normal p-value of 0.086796
# Assuming moran_results is a list of lists with each year's result
# Convert the list to a data frame
results_df <- do.call(rbind, lapply(names(moran_results), function(year) {
moran <- moran_results[[year]]$moran
data.frame(
Year = as.integer(year),
Moran_I = moran[1], # Moran I statistic
Expectation = moran[2], # Expected value
Variance = moran[3], # Variance of Moran's I
P_Value = moran_results[[year]]$p_value
)
}))
### 2. Presenting the Data
# Use kable from knitr to create a nice table
knitr::kable(results_df, format = "html", table.attr = "style='width:100%;'",
col.names = c("Year", "Moran I", "Expectation", "Variance", "P-Value"))| Year | Moran I | Expectation | Variance | P-Value | |
|---|---|---|---|---|---|
| Moran I statistic | 2013 | 0.0942219 | -0.0044444 | 0.0016593 | 0.0077132 |
| Moran I statistic1 | 2014 | 0.1170183 | -0.0044444 | 0.0016749 | 0.0014993 |
| Moran I statistic2 | 2015 | 0.0815028 | -0.0044444 | 0.0016760 | 0.0178917 |
| Moran I statistic3 | 2016 | 0.0908540 | -0.0044444 | 0.0016791 | 0.0100176 |
| Moran I statistic4 | 2017 | 0.0707463 | -0.0044444 | 0.0016728 | 0.0330005 |
| Moran I statistic5 | 2018 | 0.0599697 | -0.0044444 | 0.0016761 | 0.0578186 |
| Moran I statistic6 | 2019 | 0.1296363 | -0.0044444 | 0.0016785 | 0.0005326 |
| Moran I statistic7 | 2020 | 0.0691162 | -0.0044444 | 0.0016712 | 0.0359782 |
| Moran I statistic8 | 2021 | 0.0433409 | -0.0044444 | 0.0016832 | 0.1220651 |
| Moran I statistic9 | 2022 | 0.0511273 | -0.0044444 | 0.0016678 | 0.0867960 |
gdf$year <- as.integer(gdf$year)
data1 <- gdf %>%
mutate(SMR = ifelse(is.na(SMR), 0, SMR)) %>% # Replace NA values with 0
group_by(year) %>%
do({
.data <- .
local_moran_results <- localmoran(.data$SMR, weights)
# Transform results into a dataframe to rejoin with original data
data.frame(.data,
local_I = local_moran_results[, "Ii"],
p_value = 2 * pnorm(-abs(local_moran_results[, "Z.Ii"]), lower.tail = TRUE), # two-sided p-value
hotspot_type = attr(local_moran_results, "quadr")[["pysal"]] # assuming 'pysal' gives the most consistent results
)
}) %>%
ungroup()# Visualization using ggplot2 with facets for each year
merged_data <- gdf %>%
# Step 1: Remove the 'observed' column from gdf before merging
select(-observed, -hotspot_type) %>%
# Step 2: Merge with selected columns from data1
left_join(data1 %>%
select(OBJECTID, year, observed, SMR, hotspot_type),
by = c("OBJECTID", "year"))merged_data$hotspot_type <- factor(merged_data$hotspot_type,
levels = c("High-High", "High-Low", "Low-High", "Low-Low", "Not significant"))
lisa_plot <- ggplot(data = merged_data) +
geom_sf(aes(fill = hotspot_type), color = "black") + # Fill regions based on hotspot type and set borders to black
scale_fill_manual(values = c("High-High" = "red", "Low-Low" = "blue",
"High-Low" = "pink", "Low-High" = "green",
"Not significant" = "grey")) + # Define manual color for each hotspot type
facet_wrap(~ year, ncol = 2) + # Facet by 'year', with two columns
labs(title = "",
fill = "Hotspot Type") +
theme_Publication() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), axis.line = element_blank(),
strip.background = element_blank(), # Remove facet label backgrounds
strip.text = element_text(color = "black", size = 12), # Style facet labels
axis.text.x = element_blank(), # Remove x-axis labels
axis.text.y = element_blank(), # Remove y-axis labels
axis.ticks = element_blank(), # Remove axis ticks
legend.title = element_blank(),
legend.position = "right", # Set legend position to top right
legend.justification = "top",
legend.text = element_text(size = 8), # Smaller legend text
legend.key.size = unit(0.5, "cm"),
plot.margin = grid::unit(c(0,0,0,0), "mm")) # Justify the
lisa_plotmerged_data <- merged_data %>%
mutate(
observed_category = cut(observed,
breaks = c(0, 5, 10, Inf),
labels = c("1-5", "6-10", "11+"),
right = TRUE) # intervals are closed on the right
)
# Create a spatial plot with faceting by year, arranged in two columns
oplot <- ggplot(data = merged_data) +
geom_sf(aes(fill = observed_category), color = "black") + # Fill regions based on observed category
scale_fill_manual(values = c("1-5" = "blue", "6-10" = "orange", "11+" = "red"), # Custom colors
name = "Observed Cases", # Rename legend title
guide = guide_legend(title.position = "top")) +
facet_wrap(~ year, ncol = 2) + # Facet by 'year', with two columns
labs(title = "") +
theme_Publication() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), axis.line = element_blank(),
strip.background = element_blank(), # Remove facet label backgrounds
strip.text = element_text(color = "black", size = 12), # Style facet labels
axis.text.x = element_blank(), # Remove x-axis labels
axis.text.y = element_blank(), # Remove y-axis labels
axis.ticks = element_blank(), # Remove axis ticks
legend.title = element_blank(),
legend.position = "right", # Set legend position to top right
legend.justification = "top",
legend.text = element_text(size = 8), # Smaller legend text
legend.key.size = unit(0.5, "cm"),
plot.margin = grid::unit(c(0,0,0,0), "mm"))
oplotModel fitting
Spatial convolution model (1a)
formula1a<-adjusted_observed~1+f(idarea1, model="bym",graph=g)
result1a<-inla(formula1a,family="poisson",data=gdf,
E=E,control.predictor = list(compute = TRUE),
control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE))
summary(result1a)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.452, Running = 1.3, Post = 0.0919, Total = 1.84
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.003 0.014 -0.03 -0.003 0.025 -0.003 0
Random effects:
Name Model
idarea1 BYM model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea1 (iid component) 37.85 13.24 18.05 35.81
Precision for idarea1 (spatial component) 17.73 9.76 5.79 15.50
0.975quant mode
Precision for idarea1 (iid component) 69.50 32.05
Precision for idarea1 (spatial component) 42.90 11.91
Deviance Information Criterion (DIC) ...............: 10672.31
Deviance Information Criterion (DIC, saturated) ....: 2639.15
Effective number of parameters .....................: 165.26
Watanabe-Akaike information criterion (WAIC) ...: 10696.48
Effective number of parameters .................: 176.82
Marginal log-Likelihood: -5379.66
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Spatial convolution model with covariates (model 1b)
formula1b<-adjusted_observed~1+f(idarea1,model="bym",graph=g) + poor + POP_DENS
result1b<-inla(formula1b,family="poisson",data=gdf,
E=E,control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE))
summary(result1b)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.307, Running = 1.3, Post = 0.0878, Total = 1.7
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.021 0.022 -0.064 -0.021 0.022 -0.021 0
poor 0.005 0.003 -0.001 0.005 0.012 0.005 0
POP_DENS 0.000 0.005 -0.010 0.000 0.009 0.000 0
Random effects:
Name Model
idarea1 BYM model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea1 (iid component) 37.99 13.92 17.12 35.85
Precision for idarea1 (spatial component) 18.20 10.90 5.63 15.54
0.975quant mode
Precision for idarea1 (iid component) 71.14 31.91
Precision for idarea1 (spatial component) 46.73 11.52
Deviance Information Criterion (DIC) ...............: 10672.61
Deviance Information Criterion (DIC, saturated) ....: 2639.46
Effective number of parameters .....................: 166.19
Watanabe-Akaike information criterion (WAIC) ...: 10697.56
Effective number of parameters .................: 178.29
Marginal log-Likelihood: -5396.29
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Spatial convolution + temporal random walk 1 (2a)
formula2a<-adjusted_observed~1+f(idarea1, model="bym",graph=g) + f(idtime,model="rw2")
result2a<-inla(formula2a,family="poisson",data=gdf,
E=E,control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE))
summary(result2a)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.308, Running = 0.851, Post = 0.0866, Total = 1.25
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.003 0.014 -0.031 -0.003 0.025 -0.003 0
Random effects:
Name Model
idarea1 BYM model
idtime RW2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea1 (iid component) 37.58 13.22 17.80 35.54
Precision for idarea1 (spatial component) 18.14 10.39 5.70 15.69
Precision for idtime 30648.58 27433.81 4017.31 22816.45
0.975quant mode
Precision for idarea1 (iid component) 69.15 31.79
Precision for idarea1 (spatial component) 45.08 11.84
Precision for idtime 103275.52 11098.80
Deviance Information Criterion (DIC) ...............: 10675.33
Deviance Information Criterion (DIC, saturated) ....: 2642.17
Effective number of parameters .....................: 167.18
Watanabe-Akaike information criterion (WAIC) ...: 10700.48
Effective number of parameters .................: 179.37
Marginal log-Likelihood: -5386.39
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Spatial convolution + temporal random walk 2 + covariates (2b)
formula2b<-adjusted_observed~1+f(idarea1, model="bym",graph=g) + f(idtime,model="rw2") + poor + POP_DENS
result2b<-inla(formula2b,family="poisson",data=gdf,
E=E,control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE))
summary(result2b)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.32, Running = 0.868, Post = 0.0947, Total = 1.28
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.050 0.028 -0.105 -0.050 0.006 -0.050 0
poor 0.013 0.006 0.002 0.013 0.024 0.013 0
POP_DENS 0.001 0.005 -0.009 0.001 0.010 0.001 0
Random effects:
Name Model
idarea1 BYM model
idtime RW2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea1 (iid component) 36.48 12.84 17.00 34.58
Precision for idarea1 (spatial component) 20.40 13.11 5.82 17.08
Precision for idtime 28667.74 25772.68 3592.63 21279.92
0.975quant mode
Precision for idarea1 (iid component) 66.87 31.08
Precision for idarea1 (spatial component) 54.94 12.23
Precision for idtime 96902.41 10033.33
Deviance Information Criterion (DIC) ...............: 10674.67
Deviance Information Criterion (DIC, saturated) ....: 2641.51
Effective number of parameters .....................: 167.96
Watanabe-Akaike information criterion (WAIC) ...: 10700.19
Effective number of parameters .................: 180.35
Marginal log-Likelihood: -5401.27
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Space-time interaction additive model
formula3a<-adjusted_observed~1+f(idarea1,model="bym",graph=g)+ f(idtime,model="rw2")+f(id2,model="iid")
result3a<-inla(formula3a,family="poisson",data=gdf,
E=E,control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE))
summary(result3a)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.33, Running = 1.74, Post = 0.191, Total = 2.26
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.01 0.014 -0.038 -0.01 0.017 -0.01 0
Random effects:
Name Model
idarea1 BYM model
idtime RW2 model
id2 IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea1 (iid component) 42.64 17.15 18.21 39.63
Precision for idarea1 (spatial component) 17.37 9.97 5.37 15.04
Precision for idtime 29919.68 26569.62 3674.70 22319.68
Precision for id2 60.17 17.50 34.70 57.27
0.975quant mode
Precision for idarea1 (iid component) 84.53 34.21
Precision for idarea1 (spatial component) 43.16 11.33
Precision for idtime 100200.56 10364.56
Precision for id2 102.80 51.33
Deviance Information Criterion (DIC) ...............: 10646.53
Deviance Information Criterion (DIC, saturated) ....: 2613.38
Effective number of parameters .....................: 382.31
Watanabe-Akaike information criterion (WAIC) ...: 10660.50
Effective number of parameters .................: 345.15
Marginal log-Likelihood: -5383.00
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Space-time interaction additive model + covariates
formula3b<-adjusted_observed~1+f(idarea1,model="bym",graph=g)+ f(idtime,model="rw2")+f(id2,model="iid") + poor + POP_DENS
result3b<-inla(formula3b,family="poisson",data=gdf,
E=E,control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE))
summary(result3b)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.327, Running = 1.89, Post = 0.172, Total = 2.39
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.059 0.029 -0.116 -0.059 -0.002 -0.059 0
poor 0.013 0.006 0.001 0.013 0.025 0.013 0
POP_DENS 0.001 0.005 -0.009 0.001 0.010 0.001 0
Random effects:
Name Model
idarea1 BYM model
idtime RW2 model
id2 IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea1 (iid component) 40.53 15.69 17.70 37.91
Precision for idarea1 (spatial component) 19.64 12.34 5.59 16.59
Precision for idtime 28466.17 25427.95 3705.47 21208.31
Precision for id2 62.05 18.76 35.29 58.80
0.975quant mode
Precision for idarea1 (iid component) 78.48 33.14
Precision for idarea1 (spatial component) 51.96 11.98
Precision for idtime 95776.48 10267.55
Precision for id2 108.16 52.16
Deviance Information Criterion (DIC) ...............: 10644.68
Deviance Information Criterion (DIC, saturated) ....: 2611.52
Effective number of parameters .....................: 380.02
Watanabe-Akaike information criterion (WAIC) ...: 10660.90
Effective number of parameters .................: 345.11
Marginal log-Likelihood: -5398.08
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Space time interaction type II
formula4a<- adjusted_observed ~ f(idarea,model="bym",graph=g) +
f(idtime,model="rw2") +
f(idtime1,model="iid") +
f(idarea.int,model="iid", group=idyear.int,
control.group=list(model="rw2"))
result4a <- inla(formula4a,family="poisson",data=gdf,E=E,
control.predictor=list(compute=TRUE),
control.compute=list(dic=TRUE,cpo=TRUE, waic=TRUE))
summary(result4a)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.354, Running = 99.3, Post = 0.222, Total = 99.9
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.01 97080.73 -190402.5 -0.01 190402.5 -0.01 0
Random effects:
Name Model
idarea BYM model
idtime RW2 model
idtime1 IID model
idarea.int IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea (iid component) 1982.05 10.97 1964.00 1982.72
Precision for idarea (spatial component) 2223.54 13.74 2202.24 2224.30
Precision for idtime 20624.21 79.43 20449.88 20623.47
Precision for idtime1 24164.70 347.46 23406.60 24181.37
Precision for idarea.int 296.20 4.42 289.78 295.68
0.975quant mode
Precision for idarea (iid component) 2007.17 1977.19
Precision for idarea (spatial component) 2256.01 2215.36
Precision for idtime 20785.33 20628.90
Precision for idtime1 24766.36 24312.26
Precision for idarea.int 306.60 292.66
Deviance Information Criterion (DIC) ...............: 10803.28
Deviance Information Criterion (DIC, saturated) ....: 2770.12
Effective number of parameters .....................: 511.07
Watanabe-Akaike information criterion (WAIC) ...: 10808.15
Effective number of parameters .................: 432.63
Marginal log-Likelihood: -6206.28
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Space time interaction type II + covariates
formula4b<- adjusted_observed ~ f(idarea,model="bym",graph=g) +
f(idtime,model="rw2") +
f(idtime1,model="iid") +
f(idarea.int,model="iid", group=idyear.int,
control.group=list(model="rw2")) + + poor + POP_DENS
result4b <- inla(formula4b,family="poisson",data=gdf,E=E,
control.predictor=list(compute=TRUE),
control.compute=list(dic=TRUE,cpo=TRUE, waic=TRUE))
summary(result4b)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.361, Running = 41, Post = 0.178, Total = 41.5
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) 0.039 142215.063 -283704.424 0.040 283704.505 0.041 0
poor 0.009 0.013 -0.016 0.009 0.035 0.009 0
POP_DENS -0.050 0.031 -0.110 -0.050 0.010 -0.050 0
Random effects:
Name Model
idarea BYM model
idtime RW2 model
idtime1 IID model
idarea.int IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea (iid component) 48.16 0.589 47.34 48.10
Precision for idarea (spatial component) 59.07 0.408 58.27 59.07
Precision for idtime 58.70 0.753 57.27 58.68
Precision for idtime1 61.87 1.740 57.91 62.07
Precision for idarea.int 86.50 1.268 83.78 86.58
0.975quant mode
Precision for idarea (iid component) 49.57 47.64
Precision for idarea (spatial component) 59.92 59.03
Precision for idtime 60.27 58.59
Precision for idtime1 64.54 63.23
Precision for idarea.int 88.72 86.99
Deviance Information Criterion (DIC) ...............: 10837.07
Deviance Information Criterion (DIC, saturated) ....: 2803.91
Effective number of parameters .....................: 601.75
Watanabe-Akaike information criterion (WAIC) ...: 10820.21
Effective number of parameters .................: 481.54
Marginal log-Likelihood: -6254.34
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Space time interaction type III
formula5a<- adjusted_observed ~ f(idarea,model="bym",graph=g) +
f(idtime,model="rw2") +
f(idtime1,model="iid") +
f(idyear.int,model="iid", group=idarea.int,
control.group=list(model="besag",
graph=g))
result5a <- inla(formula5a,family="poisson",data=gdf,E=E,
control.predictor=list(compute=TRUE),
control.compute=list(dic=TRUE,cpo=TRUE, waic=TRUE))
summary(result5a)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.44, Running = 47.2, Post = 0.168, Total = 47.8
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.004 207977.1 -419355.9 -0.01 419355.9 -0.01 0
Random effects:
Name Model
idarea BYM model
idtime RW2 model
idtime1 IID model
idyear.int IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea (iid component) 34.32 0.718 32.65 34.41
Precision for idarea (spatial component) 14.73 0.109 14.52 14.73
Precision for idtime 168.67 1.604 165.08 168.70
Precision for idtime1 207.49 2.781 201.02 207.77
Precision for idyear.int 75.62 0.588 74.39 75.63
0.975quant mode
Precision for idarea (iid component) 35.34 34.91
Precision for idarea (spatial component) 14.96 14.71
Precision for idtime 171.37 169.45
Precision for idtime1 211.57 209.74
Precision for idyear.int 76.74 75.73
Deviance Information Criterion (DIC) ...............: 10644.39
Deviance Information Criterion (DIC, saturated) ....: 2611.23
Effective number of parameters .....................: 290.04
Watanabe-Akaike information criterion (WAIC) ...: 10667.24
Effective number of parameters .................: 279.37
Marginal log-Likelihood: -6307.86
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Space time interaction type III + covariates
formula5b<- adjusted_observed ~ f(idarea,model="bym",graph=g) +
f(idtime,model="rw2") +
f(idtime1,model="iid") +
f(idyear.int,model="iid", group=idarea.int,
control.group=list(model="besag",
graph=g)) + poor + POP_DENS
result5b <- inla(formula5b,family="poisson",data=gdf,E=E,
control.predictor=list(compute=TRUE),
control.compute=list(dic=TRUE,cpo=TRUE, waic=TRUE))
summary(result5b)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.402, Running = 152, Post = 0.195, Total = 152
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.048 183366.403 -359582.005 -0.048 359581.908 -0.048 0
poor 0.016 0.008 0.001 0.016 0.030 0.016 0
POP_DENS 0.002 0.005 -0.007 0.002 0.011 0.002 0
Random effects:
Name Model
idarea BYM model
idtime RW2 model
idtime1 IID model
idyear.int IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant
Precision for idarea (iid component) 31.32 0.813 29.51 31.37
Precision for idarea (spatial component) 20.98 0.984 19.52 20.85
Precision for idtime 515.28 11.566 488.32 516.85
Precision for idtime1 614.27 6.412 602.76 614.27
Precision for idyear.int 85.15 1.106 83.53 85.11
0.975quant mode
Precision for idarea (iid component) 32.66 31.78
Precision for idarea (spatial component) 23.30 20.25
Precision for idtime 531.57 524.95
Precision for idtime1 628.44 612.15
Precision for idyear.int 87.78 84.32
Deviance Information Criterion (DIC) ...............: 10649.11
Deviance Information Criterion (DIC, saturated) ....: 2615.95
Effective number of parameters .....................: 273.49
Watanabe-Akaike information criterion (WAIC) ...: 10673.56
Effective number of parameters .................: 267.47
Marginal log-Likelihood: -6319.62
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Comparing model performance
# Apply inla.group.cv to each result
apply_inla_group_cv <- function(result) {
result$loocv <- inla.group.cv(result, num.level.sets = -1)
result$logcv.m3 <- inla.group.cv(result, num.level.sets = 3)
result$logcv.m5 <- inla.group.cv(result, num.level.sets = 5)
result$logcv.m10 <- inla.group.cv(result, num.level.sets = 10)
return(result)
}
# Apply the function to each result in the list
results <- list(result1a, result1b, result2a, result2b, result3a, result3b, result4a, result4b, result5a, result5b)
results <- lapply(results, apply_inla_group_cv)
names(results) <- c("Model 1a", "Model 1b", "Model 2a", "Model 2b", "Model 3a", "Model 3b", "Model 4a", "Model 4b", "Model 5a", "Model 5b")
# Define functions for extracting metrics
DIC <- function(x) {
data.frame(mean.deviance = x$dic$mean.deviance,
p.eff.DIC = x$dic$p.eff,
DIC = x$dic$dic,
WAIC = x$waic$waic,
p.WAIC = x$waic$p.eff)
}
compute_loocv <- function(x) {
cv_values <- x$loocv$cv
cv_values <- cv_values[!is.na(cv_values)] # Remove NA values
if (length(cv_values) > 0) {
-mean(log(cv_values))
} else {
NA
}
}
logcv <- function(cv_values) {
cv_values <- cv_values[!is.na(cv_values)] # Remove NA values
if (length(cv_values) > 0) {
-mean(log(cv_values))
} else {
NA # Handle cases where all values are NA
}
}
compute_logcv <- function(x) {
# Extract logcv values for each num.level.sets
logcv_m3 <- logcv(x$logcv.m3$cv)
logcv_m5 <- logcv(x$logcv.m5$cv)
logcv_m10 <- logcv(x$logcv.m10$cv)
#rounding
logcv_m3_rounded <- if (!is.na(logcv_m3)) round(logcv_m3, 3) else NA
logcv_m5_rounded <- if (!is.na(logcv_m5)) round(logcv_m5, 3) else NA
logcv_m10_rounded <- if (!is.na(logcv_m10)) round(logcv_m10, 3) else NA
list(
logcv_m3 = logcv_m3_rounded,
logcv_m5 = logcv_m5_rounded,
logcv_m10 = logcv_m10_rounded
)
}
extract_group_indices <- function(x, num.level.sets) {
lapply(x[[paste0("logcv.m", num.level.sets)]]$groups, function(group) group$idx)
}
tables <- list()
for (name in names(results)) {
result <- results[[name]]
# Extract DIC and WAIC
dic_waic <- DIC(result)
# print(paste("DIC for", name, ":", dic_waic))
# Compute LOOCV
loocv <- round(compute_loocv(result), 3)
# print(paste("LOOCV for", name, ":", loocv))
# Compute logcv
logcv_results <- compute_logcv(result)
# print(paste("logcv_m3 for", name, ":", logcv_results$logcv_m3))
# print(paste("logcv_m5 for", name, ":", logcv_results$logcv_m5))
# print(paste("logcv_m10 for", name, ":", logcv_results$logcv_m10))
# Extract group indices
# groups_m3 <- extract_group_indices(result, 3)
# groups_m5 <- extract_group_indices(result, 5)
# groups_m10 <- extract_group_indices(result, 10)
# print(paste("Groups_m3 for", name, ":", paste(unlist(groups_m3), collapse = ", ")))
# print(paste("Groups_m5 for", name, ":", paste(unlist(groups_m5), collapse = ", ")))
# print(paste("Groups_m10 for", name, ":", paste(unlist(groups_m10), collapse = ", ")))
# Combine all data into a single table
table <- data.frame(
mean.deviance = dic_waic$mean.deviance,
DIC = dic_waic$DIC,
p.DIC = dic_waic$p.eff,
WAIC = dic_waic$WAIC,
p.WAIC = dic_waic$p.WAIC,
LOOCV = loocv,
logcv_m3 = I(list(logcv_results$logcv_m3)),
logcv_m5 = I(list(logcv_results$logcv_m5)),
logcv_m10 = I(list(logcv_results$logcv_m10))
)
tables[[name]] <- table
}
# Combine all tables into a single data frame
final_table <- do.call(rbind, tables)
# Print the final table
kable(final_table, format = "html", caption = "Model Evaluation Results")| mean.deviance | DIC | p.DIC | WAIC | p.WAIC | LOOCV | logcv_m3 | logcv_m5 | logcv_m10 | |
|---|---|---|---|---|---|---|---|---|---|
| Model 1a | 10507.05 | 10672.31 | 165.2574 | 10696.48 | 176.8209 | 2.395 | 2.463 | 2.463 | 2.463 |
| Model 1b | 10506.42 | 10672.61 | 166.1913 | 10697.56 | 178.2874 | 2.395 | 2.414 | 2.432 | 2.467 |
| Model 2a | 10508.15 | 10675.33 | 167.1821 | 10700.48 | 179.3718 | 2.396 | 2.418 | 2.436 | 2.467 |
| Model 2b | 10506.71 | 10674.67 | 167.9594 | 10700.19 | 180.3550 | 2.396 | 2.419 | 2.443 | 2.467 |
| Model 3a | 10264.22 | 10646.53 | 382.3128 | 10660.50 | 345.1542 | 2.391 | 2.437 | 2.454 | 2.449 |
| Model 3b | 10264.66 | 10644.68 | 380.0167 | 10660.90 | 345.1061 | 2.391 | 2.437 | 2.456 | 2.448 |
| Model 4a | 10292.21 | 10803.28 | 511.0710 | 10808.15 | 432.6329 | 2.431 | 2.561 | 2.844 | 4.299 |
| Model 4b | 10235.32 | 10837.07 | 601.7524 | 10820.21 | 481.5438 | 2.440 | 2.576 | 2.82 | 3.646 |
| Model 5a | 10354.35 | 10644.38 | 290.0367 | 10667.24 | 279.3690 | 2.391 | 2.428 | 2.454 | 2.465 |
| Model 5b | 10375.62 | 10649.11 | 273.4914 | 10673.56 | 267.4711 | 2.392 | 2.431 | 2.458 | 2.466 |
Analyzing M3b - best fitted
result3b$summary.fixed mean sd 0.025quant 0.5quant 0.975quant
(Intercept) -0.058655807 0.029227316 -0.116162673 -0.058593674 -0.001501919
poor 0.013000225 0.006105871 0.001044241 0.012993145 0.024996666
POP_DENS 0.001099171 0.004811779 -0.008503182 0.001153227 0.010395601
mode kld
(Intercept) -0.058593169 1.205954e-09
poor 0.012993152 3.784022e-10
POP_DENS 0.001153583 3.234859e-08
result3b$summary.hyperpar mean sd 0.025quant
Precision for idarea1 (iid component) 40.52628 15.69245 17.700308
Precision for idarea1 (spatial component) 19.64479 12.33589 5.592538
Precision for idtime 28466.16957 25427.94895 3705.471339
Precision for id2 62.04805 18.75721 35.287208
0.5quant 0.975quant mode
Precision for idarea1 (iid component) 37.91362 78.48133 33.13852
Precision for idarea1 (spatial component) 16.58510 51.96276 11.97744
Precision for idtime 21208.31244 95776.47907 10267.55074
Precision for id2 58.79856 108.15967 52.15702
summary(result3b$cpo$cpo - result3a$cpo$cpo) Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
-0.016072 -0.001453 0.000044 -0.000027 0.001605 0.011227 27
plot(result3b$cpo$cpo, result3a$cpo$cpo, xlab = "Model 3 CPO", ylab = "Model 2 CPO", main = "CPO Comparison")
abline(a = 0, b = 1, col = "red")Sensitivity analysis
formula3b_s2 <- adjusted_observed ~ 1 +
f(idarea1, model = "bym", graph = g, hyper = list(
prec.unstruct = list(prior = "loggamma", param = c(0.01, 0.01)),
prec.spatial = list(prior = "loggamma", param = c(0.01, 0.01))
)) +
f(idtime, model = "rw2", hyper = list(
prec = list(prior = "pc.prec", param = c(0.01, 0.01))
)) +
f(id2, model = "iid", hyper = list(
prec = list(prior = "loggamma", param = c(0.01, 0.01))
)) +
poor + POP_DENS
result3b_s2 <- inla(formula3b_s2, family = "poisson", data = gdf, E = E, control.predictor = list(compute = TRUE), control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE, return.marginals.predictor=TRUE) )
summary(result3b_s2)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.33, Running = 1.83, Post = 0.23, Total = 2.39
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.056 0.029 -0.112 -0.056 0.000 -0.056 0
poor 0.012 0.006 0.001 0.012 0.024 0.012 0
POP_DENS 0.001 0.005 -0.009 0.001 0.010 0.001 0
Random effects:
Name Model
idarea1 BYM model
idtime RW2 model
id2 IID model
Model hyperparameters:
mean sd 0.025quant
Precision for idarea1 (iid component) 4.04e+01 1.38e+01 19.62
Precision for idarea1 (spatial component) 1.64e+01 8.10e+00 6.03
Precision for idtime 4.90e+06 4.54e+07 18667.78
Precision for id2 5.38e+01 1.36e+01 32.89
0.5quant 0.975quant mode
Precision for idarea1 (iid component) 38.36 7.31e+01 34.57
Precision for idarea1 (spatial component) 14.71 3.71e+01 11.83
Precision for idtime 433005.09 3.19e+07 35820.57
Precision for id2 51.90 8.61e+01 47.88
Deviance Information Criterion (DIC) ...............: 10643.59
Deviance Information Criterion (DIC, saturated) ....: 2610.44
Effective number of parameters .....................: 399.04
Watanabe-Akaike information criterion (WAIC) ...: 10655.67
Effective number of parameters .................: 356.01
Marginal log-Likelihood: -5398.13
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
formula3b_s3 <- adjusted_observed ~ 1 +
f(idarea1, model = "bym", graph = g, hyper = list(
prec.unstruct = list(prior = "loggamma", param = c(2, 0.5)),
prec.spatial = list(prior = "loggamma", param = c(2, 0.5))
)) +
f(idtime, model = "rw2", hyper = list(
prec = list(prior = "pc.prec", param = c(2, 0.5))
)) +
f(id2, model = "iid", hyper = list(
prec = list(prior = "loggamma", param = c(2, 0.5))
)) +
poor + POP_DENS
result3b_s3 <- inla(formula3b_s3, family = "poisson", data = gdf, E = E, control.predictor = list(compute = TRUE), control.compute=list(dic=TRUE,cpo=TRUE,waic=TRUE, return.marginals.predictor=TRUE) )
summary(result3b_s3)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts,
", " data = data, quantiles = quantiles, E = E, offset = offset, ", "
scale = scale, weights = weights, Ntrials = Ntrials, strata = strata,
", " lp.scale = lp.scale, link.covariates = link.covariates, verbose =
verbose, ", " lincomb = lincomb, selection = selection, control.compute
= control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla,
control.fixed = control.fixed, ", " control.mode = control.mode,
control.expert = control.expert, ", " control.hazard = control.hazard,
control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", "
control.pardiso = control.pardiso, only.hyperparam = only.hyperparam,
", " inla.call = inla.call, inla.arg = inla.arg, num.threads =
num.threads, ", " keep = keep, working.directory = working.directory,
silent = silent, ", " inla.mode = inla.mode, safe = FALSE, debug =
debug, .parent.frame = .parent.frame)" )
Time used:
Pre = 0.375, Running = 1.8, Post = 0.316, Total = 2.49
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) -0.064 0.032 -0.126 -0.063 -0.001 -0.063 0
poor 0.013 0.007 0.000 0.013 0.025 0.013 0
POP_DENS 0.001 0.005 -0.010 0.001 0.011 0.001 0
Random effects:
Name Model
idarea1 BYM model
idtime RW2 model
id2 IID model
Model hyperparameters:
mean sd 0.025quant
Precision for idarea1 (iid component) 26.57 4.33e+00 19.01
Precision for idarea1 (spatial component) 14.13 3.57e+00 8.33
Precision for idtime 177535.48 1.85e+06 445.10
Precision for id2 32.10 4.22e+00 24.58
0.5quant 0.975quant mode
Precision for idarea1 (iid component) 26.25 3.60e+01 25.63
Precision for idarea1 (spatial component) 13.72 2.23e+01 12.95
Precision for idtime 13475.67 1.13e+06 760.35
Precision for id2 31.84 4.12e+01 31.32
Deviance Information Criterion (DIC) ...............: 10658.78
Deviance Information Criterion (DIC, saturated) ....: 2625.62
Effective number of parameters .....................: 522.14
Watanabe-Akaike information criterion (WAIC) ...: 10638.51
Effective number of parameters .................: 421.35
Marginal log-Likelihood: -5416.42
CPO, PIT is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
Marginal posterior distribution
plot_combined_marginal_effects_with_quantiles <- function(result_list, effect_name, model_names) {
# Create an empty data frame to store combined data
combined_data <- data.frame(x = numeric(), y = numeric(), Model = factor(), lquant = numeric(), uquant = numeric())
# Loop through the list of model results
for (i in seq_along(result_list)) {
# Extract the marginal effects for the specified variable
effect <- result_list[[i]]$marginals.fixed[[effect_name]]
# Calculate the quantiles for the shading
lquant <- inla.qmarginal(0.025, effect)
uquant <- inla.qmarginal(0.975, effect)
# Create a data frame from the smoothed marginal
df_effect <- data.frame(inla.smarginal(effect))
df_effect$Model <- model_names[i]
df_effect$lquant <- lquant
df_effect$uquant <- uquant
# Combine with the main data frame
combined_data <- rbind(combined_data, df_effect)
}
# Ensure the 'Model' factor is ordered as desired for the legend
combined_data$Model <- factor(combined_data$Model, levels = model_names)
# Define line types and widths for better differentiation
line_types <- c("solid", "dashed", "dotdash", "longdash")
# Generate the plot
p <- ggplot(combined_data, aes(x, y, color = Model)) +
geom_line(aes(linetype = Model), size = 1.0) +
geom_vline(xintercept = 0, linetype = "dashed") +
scale_colour_manual(values = c("#386cb0", "#fdb462", "#7fc97f")) +
scale_linetype_manual(values = line_types) +
theme_Publication(base_size = 12) +
theme(legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size = 8)) +
labs(title = "",
x = NULL, y = "Probability density")
return(p)
}
# Usage
result_list <- list(result3b, result3b_s2, result3b_s3)
model_names <- c("Default priors, log-gamma (1, 0.0005)", "Best-fitted, log-gamma (0.01, 0.01)", "log-gamma (2, 0.5)")
plot <- plot_combined_marginal_effects_with_quantiles(result_list, "poor", model_names)Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
print(plot)Space time interaction type IV