library(magrittr) library(ggthemes) library(ggplot2) library(dplyr) library(rstan) library(EpiEstim) devtools::load_all()
We start with defining a very simple model with only one location. The model is given by [ I(t) \sim Poisson(R_t \sum_{s = 0}^{t}{I_{t} ws_{t - s}}). ]
The model is tested with simulated data.
Load in the data and prepare to feed into Stan.
mean_SI <- 14.2 CV_SI <- 9.6 / 14.2 SItrunc <- 40 SI_Distr <- sapply(0:SItrunc, function(e) DiscrSI(e, mean_SI, mean_SI * CV_SI)) SI_Distr <- SI_Distr / sum(SI_Distr)
I0 <- 110 incid <- as.matrix(I0, 1, 1) R <- c(rep(1.5, times = 8), rep(1.1, times = 7), rep(0.3, times = 7)) R <- as.matrix(R, ncol = 1) pij <- 1 # probability of staying at i n.days <- 21 SI <- SI_Distr[1:(n.days + 1)] I1 <- project2(incid, R, SI, pij, n.days) I1 <- c(I0, I1)
And now fitting.
sim_data <- list(T = length(I1), I = I1, SI = SI_Distr[1:length(I1)], num_windows = 3, windows_end = c(8, 15, length(I1))) fit1 <- stan( file = "R/gravitymodel.stan", # Stan program data = sim_data, # named list of data chains = 1, # number of Markov chains warmup = 1000, # number of warmup iterations per chain iter = 5000, # total number of iterations per chain cores = 2, # number of cores (using 2 just for the vignette) refresh = 500 # show progress every 'refresh' iterations ) print(fit1, pars=c("R"), probs=c(.1,.5,.9))
Looks like it is working as expected!
I0 <- c(110, 150, 200, 300) incid <- as.matrix(I0, length(I0), 1) R <- c(rep(1.5, times = length(I0)), rep(1.5, times = 7), rep(1.1, times = 7), rep(0.3, times = 7)) R <- as.matrix(R, ncol = 1) pij <- 1 # probability of staying at i n.days <- 21 SI <- SI_Distr[1:(n.days + 1)] I1 <- project2(incid, R, SI, pij, n.days) I1 <- c(I0, I1)
And now fitting.
sim_data <- list(T = length(I1), I = I1, SI = SI_Distr[1:length(I1)], num_windows = 3, windows_end = c(12, 19, length(I1))) fit1 <- stan( file = "R/gravitymodel.stan", # Stan program data = sim_data, # named list of data chains = 1, # number of Markov chains warmup = 1000, # number of warmup iterations per chain iter = 5000, # total number of iterations per chain cores = 2, # number of cores (using 2 just for the vignette) refresh = 500 # show progress every 'refresh' iterations ) print(fit1, pars=c("R"), probs=c(.1,.5,.9))
Looks like it is working as expected!
infile <- "WHO_bycountry.csv" infile <- here::here("data/CaseCounts/processed/", infile) incid_wide <- readr::read_csv(infile) guinea_incid <- filter(incid_wide, Country == "Guinea") %>% pull(incid) lbr_incid <- filter(incid_wide, Country == "Liberia") %>% pull(incid) sl_incid <- filter(incid_wide, Country == "Sierra Leone") %>% pull(incid)
Use the entire dataset.
time_window <- 49 windows_end <- seq(time_window, length(guinea_incid), by = time_window) num_windows <- length(windows_end) T <- windows_end[num_windows] I <- guinea_incid[seq(T)] SI_len <- length(SI_Distr) SI <- if(T < SI_len) SI_Distr[1:T] else c(SI_Distr, rep(0, T - SI_len)) sim_data <- list(T = T, I = I, SI = SI, num_windows = num_windows, windows_end = windows_end)
And get the ball rolling
fit1 <- stan( file = "R/gravitymodel.stan", # Stan program data = sim_data, # named list of data chains = 5, # number of Markov chains warmup = 1000, # number of warmup iterations per chain iter = 5000, # total number of iterations per chain cores = 2, # number of cores (using 2 just for the vignette) refresh = 500 # show progress every 'refresh' iterations ) print(fit1, pars=c("R"), probs=c(.1,.5,.9)) traceplot(fit1, pars = c("R"), inc_warmup = TRUE, nrow = 5) from_stan <- summary(fit1) from_stan <- from_stan$summary from_stan <- from_stan[-13, c("mean", "sd", "2.5%", "25%", "50%", "75%", "97.5%")]
windows_start <- seq(1, by = time_window, length.out = length(windows_end)) r.estim <- EpiEstim::EstimateR(I, T.Start = windows_start , T.End = windows_end, method = "NonParametricSI", SI.Distr = SI_Distr, plot = FALSE , CV.Posterior = 1 , Mean.Prior = 1 , Std.Prior = 0.5) from_epiestim <- r.estim$R[, c("Mean(R)", "Std(R)", "Quantile.0.025(R)", "Quantile.0.25(R)", "Median(R)", "Quantile.0.75(R)", "Quantile.0.975(R)")] rownames(from_epiestim) <- rownames(from_stan) colnames(from_epiestim) <- colnames(from_stan) from_stan <- tibble::rownames_to_column(data.frame(from_stan)) from_epiestim <- tibble::rownames_to_column(data.frame(from_epiestim))
And now compare them visually.
compare <- list(stan = from_stan, epiestim = from_epiestim) compare <- bind_rows(compare, .id = "Source") compare <- tidyr::gather(compare, key = "variable", value = "value", -c(Source, rowname)) compare$rowname %<>% factor(levels = c("R[1]", "R[2]", "R[3]", "R[4]", "R[5]", "R[6]", "R[7]", "R[8]", "R[9]", "R[10]", "R[11]", "R[12]")) ggplot(compare, aes(rowname, value, color = Source)) + geom_point(position = "jitter") + facet_wrap(~variable) + theme_minimal()
Use the entire dataset.
lbr_incid %<>% `[`(1:329) ## only non-NAs time_window <- 49 windows_end <- seq(time_window, length(lbr_incid), by = time_window) num_windows <- length(windows_end) T <- windows_end[num_windows] I <- lbr_incid[seq(T)] SI_len <- length(SI_Distr) SI <- if(T < SI_len) SI_Distr[1:T] else c(SI_Distr, rep(0, T - SI_len)) sim_data <- list(T = T, I = I, SI = SI, num_windows = num_windows, windows_end = windows_end)
And get the ball rolling
fit1 <- stan( file = "R/gravitymodel.stan", # Stan program data = sim_data, # named list of data chains = 5, # number of Markov chains warmup = 1000, # number of warmup iterations per chain iter = 5000, # total number of iterations per chain cores = 2, # number of cores (using 2 just for the vignette) refresh = 500 # show progress every 'refresh' iterations ) print(fit1, pars=c("R"), probs=c(.1,.5,.9)) traceplot(fit1, pars = c("R"), inc_warmup = TRUE, nrow = 5) lbr_stan <- summary(fit1) lbr_stan <- lbr_stan$summary lbr_stan <- lbr_stan[-7, c("mean", "sd", "2.5%", "25%", "50%", "75%", "97.5%")]
windows_start <- seq(1, by = time_window, length.out = length(windows_end)) r.estim <- EpiEstim::EstimateR(I, T.Start = windows_start , T.End = windows_end, method = "NonParametricSI", SI.Distr = SI_Distr, plot = FALSE , CV.Posterior = 1 , Mean.Prior = 1 , Std.Prior = 0.5) lbr_epiestim <- r.estim$R[, c("Mean(R)", "Std(R)", "Quantile.0.025(R)", "Quantile.0.25(R)", "Median(R)", "Quantile.0.75(R)", "Quantile.0.975(R)")] rownames(lbr_epiestim) <- rownames(lbr_stan) colnames(lbr_epiestim) <- colnames(lbr_stan) lbr_stan <- tibble::rownames_to_column(data.frame(lbr_stan)) lbr_epiestim <- tibble::rownames_to_column(data.frame(lbr_epiestim))
And now compare them visually.
compare <- list(stan = lbr_stan, epiestim = lbr_epiestim) compare <- bind_rows(compare, .id = "Source") compare <- tidyr::gather(compare, key = "variable", value = "value", -c(Source, rowname)) compare$rowname %<>% factor(levels = c("R[1]", "R[2]", "R[3]", "R[4]", "R[5]", "R[6]", "R[7]", "R[8]", "R[9]", "R[10]", "R[11]", "R[12]")) ggplot(compare, aes(rowname, value, color = Source)) + geom_point(position = "jitter") + facet_wrap(~variable) + theme_minimal()
Use the entire dataset.
time_window <- 49 windows_end <- seq(time_window, length(sl_incid), by = time_window) num_windows <- length(windows_end) T <- windows_end[num_windows] I <- sl_incid[seq(T)] SI_len <- length(SI_Distr) SI <- if(T < SI_len) SI_Distr[1:T] else c(SI_Distr, rep(0, T - SI_len)) sim_data <- list(T = T, I = I, SI = SI, num_windows = num_windows, windows_end = windows_end)
And get the ball rolling
fit1 <- stan( file = "R/gravitymodel.stan", # Stan program data = sim_data, # named list of data chains = 5, # number of Markov chains warmup = 1000, # number of warmup iterations per chain iter = 5000, # total number of iterations per chain cores = 2, # number of cores (using 2 just for the vignette) refresh = 500 # show progress every 'refresh' iterations ) print(fit1, pars=c("R"), probs=c(.1,.5,.9)) traceplot(fit1, pars = c("R"), inc_warmup = TRUE, nrow = 5) sl_stan <- summary(fit1) sl_stan <- sl_stan$summary sl_stan <- sl_stan[-13, c("mean", "sd", "2.5%", "25%", "50%", "75%", "97.5%")]
windows_start <- seq(1, by = time_window, length.out = length(windows_end)) r.estim <- EpiEstim::EstimateR(I, T.Start = windows_start , T.End = windows_end, method = "NonParametricSI", SI.Distr = SI_Distr, plot = FALSE , CV.Posterior = 1 , Mean.Prior = 1 , Std.Prior = 0.5) sl_epiestim <- r.estim$R[, c("Mean(R)", "Std(R)", "Quantile.0.025(R)", "Quantile.0.25(R)", "Median(R)", "Quantile.0.75(R)", "Quantile.0.975(R)")] rownames(sl_epiestim) <- rownames(sl_stan) colnames(sl_epiestim) <- colnames(sl_stan) sl_stan <- tibble::rownames_to_column(data.frame(sl_stan)) sl_epiestim <- tibble::rownames_to_column(data.frame(sl_epiestim))
And now compare them visually.
compare <- list(stan = sl_stan, epiestim = sl_epiestim) compare <- bind_rows(compare, .id = "Source") compare <- tidyr::gather(compare, key = "variable", value = "value", -c(Source, rowname)) compare$rowname %<>% factor(levels = c("R[1]", "R[2]", "R[3]", "R[4]", "R[5]", "R[6]", "R[7]", "R[8]", "R[9]", "R[10]", "R[11]", "R[12]")) ggplot(compare, aes(rowname, value, color = Source)) + geom_point(position = "jitter") + facet_wrap(~variable) + theme_minimal()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.