cs2_sarscov2.Rmd
This document describes the steps and components of the provided R code for creating and running serological models using simulated data. The code defines observational models, antibody kinetics models, and runs inference using MCMC methods.
This data has been generated using serosim
.
wave_full <- readRDS(file = "wave2_export.RDS")
#wave_full <- readRDS(file = "./vignettes/wave2_export.RDS")
sero_data_w2 <- wave_full$sero_data
known_inf_w2 <- wave_full$known_inf
inf_prior_w2 <- wave_full$inf_prior
# Check the entries are sensible
check_sero_no_single_entries(sero_data_w2)
## No single entries in data_sero!,
check_sero_timings(sero_data_w2)
## No individuals with less than 15 days in the study!
wave_full <- readRDS(file = "wave3_export.RDS")
#wave_full <- readRDS(file = "./vignettes/wave3_export.RDS")
sero_data_w3 <- wave_full$sero_data
known_inf_w3 <- wave_full$known_inf
inf_prior_w3 <- wave_full$inf_prior
# Check the entries are sensible
check_sero_no_single_entries(sero_data_w3)
## No single entries in data_sero!,
check_sero_timings(sero_data_w3)
## No individuals with less than 15 days in the study!
#known_inf_w2 <- known_inf_w2_check %>% filter(key_exposure == "inferrable")
obsLogLikelihood <- function(titre_val, titre_est, pars) {
ll <- dnorm(titre_val, titre_est, pars[1], log = TRUE)
}
noInfSerumKinetics <- function(titre_est, timeSince, pars) {
titre_est_log <- titre_est - (pars[1] * titre_est) * (timeSince)
titre_est_log <- max(0, titre_est_log)
titre_est_log
}
infTuenisPower2016 <- function(titre_est, timeSince, pars) {
y1 <- pars[1]
t1 <- pars[2]
r <- pars[3]
alpha <- pars[4]
v <- 0.001
mu <- 1 / t1 * y1
if (timeSince < t1) {
titre_est_boost <- exp(mu * timeSince)
} else {
titre_est_boost <- exp(y1) * (1 + (r - 1) * exp(y1)^{r - 1} * v * (timeSince - t1)) ^ {-1 / (r - 1)}
}
titre_est_log <- titre_est + log(titre_est_boost) * max(0, 1 - titre_est * alpha)
titre_est_log
}
# Define the biomarkers and exposure types in the model
biomarkers <- c("spike", "NCP")
exposureTypes <- c("none", "delta", "vax", "predelta")
exposureFitted <- "delta"
# Define the observational model
observationalModel <- list(
names = c("spike", "NCP"),
model = makeModel(
addObservationalModel("spike", c("sigma"), obsLogLikelihood),
addObservationalModel("NCP", c("sigma_a"), obsLogLikelihood)),
prior = bind_rows(
addPrior("sigma", 0.0001, 2, "exp", 1, NA),
addPrior("sigma_a", 0.0001, 2, "exp", 1, NA)
) # observational model,
)
# Define the antibody kinetics model
abkineticsModel <- list(
model = makeModel(
addAbkineticsModel("none_s", "spike", "none", c("wane"), noInfSerumKinetics),
addAbkineticsModel("delta_s", "spike", "delta", c("y1_d", "t1_d", "r_d", "s"), infTuenisPower2016),
addAbkineticsModel("vax_s", "spike", "vax", c("y1_vax", "t1_vax", "r_vax", "s"), infTuenisPower2016),
addAbkineticsModel("predelta_s", "spike", "predelta", c("y1_pd", "t1_pd", "r_pd", "s"), infTuenisPower2016),
addAbkineticsModel("none_ncp", "NCP", "none", c("wane_a"), noInfSerumKinetics),
addAbkineticsModel("delta_ncp", "NCP", "delta", c("y1_d_a", "t1_d_a", "r_d_a", "s_a"), infTuenisPower2016),
addAbkineticsModel("vax_ncp", "NCP", "vax", c("y1_vax_a", "t1_vax_a", "r_vax_a", "s_a"), infTuenisPower2016),
addAbkineticsModel("predelta_ncp", "NCP", "predelta", c("y1_pd_a", "t1_pd_a", "r_pd_a", "s_a"), infTuenisPower2016)
),
prior = bind_rows(
addPrior("y1_d", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_d", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_d", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("y1_vax", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_vax", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_vax", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("y1_pd", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_pd", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_pd", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("s", 0, 1, "unif", 0, 1), # ab kinetics
addPrior("wane", 0.0, 0.01, "unif", 0.0, 0.01), # observational model
addPrior("y1_d_a", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_d_a", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_d_a", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("y1_vax_a", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_vax_a", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_vax_a", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("y1_pd_a", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_pd_a", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_pd_a", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("s_a", 0, 1, "unif", 0, 1), # ab kinetics
addPrior("wane_a", 0.0, 0.01, "unif", 0.0, 0.01) # observational model
)
)
model_w2 <- createSeroJumpModel(
data_sero = sero_data_w2,
data_known = known_inf_w2,
biomarkers = biomarkers,
exposureTypes = exposureTypes,
exposureFitted = exposureFitted,
observationalModel = observationalModel,
abkineticsModel = abkineticsModel,
exposurePriorTime = inf_prior_w2,
exposurePriorTimeType = "empirical"
)
## OUTLINE OF INPUTTED MODEL
## There are 2 measured biomarkers: spike, NCP
## There are 4 exposure types in the study period: none, delta, vax, predelta
## The fitted exposure type is delta
## PRIOR DISTRIBUTIONS
## Prior parameters of observationalModel are: sigma, sigma_a
## Prior parameters of abkineticsModel are: y1_d, t1_d, r_d, y1_vax, t1_vax, r_vax, y1_pd, t1_pd, r_pd, s, wane, y1_d_a, t1_d_a, r_d_a, y1_vax_a, t1_vax_a, r_vax_a, y1_pd_a, t1_pd_a, r_pd_a, s_a, wane_a
## No single entries in data_sero!,
## No individuals with less than 15 days in the study!
## Warning in addExposurePrior_checkempirical(exp_prior, T_max): Warning: The number of rows in the exposure prior dataframe does not match the number of time points in the study
## Warning in addExposurePrior_checkempirical(exp_prior, T_max): Warning: The number of rows in the exposure prior dataframe does not match the number of time points in the study
## There are individuals which have exposure before their first bleed or before their last bleed, ids: 19, 23, 45, 92, 95, 147, 162, 205, 218, 6, 18, 24, 30, 63, 98, 142, 181, 192, 199, 208, 210, 214, 215, 245, 246, 254, 265 . It is hard to perform inference on these people, so we recommend you remove the exposures from the known inf, but, if included, the model ignores these exposures.
Before running the whole model it is good to check the data and the
priors. This can be done using a suit of functions
plotPriors
function.
p1 <- plotSero(model_w2)
p2 <- plotPriorPredictive(model_w2)
p3 <- plotPriorInfection(model_w2)
p1 / p2
p3
# Define the biomarkers and exposure types in the model
biomarkers <- c("spike", "NCP")
exposureTypes <- c("none", "omicron", "vax")
exposureFitted <- "omicron"
# Define the observational model
observationalModel <- list(
names = c("spike", "NCP"),
model = makeModel(
addObservationalModel("spike", c("sigma"), obsLogLikelihood),
addObservationalModel("NCP", c("sigma_a"), obsLogLikelihood)),
prior = bind_rows(
addPrior("sigma", 0.0001, 2, "exp", 1, NA),
addPrior("sigma_a", 0.0001, 2, "exp", 1, NA)
) # observational model,
)
# Define the antibody kinetics model
abkineticsModel <- list(
model = makeModel(
addAbkineticsModel("none_s", "spike", "none", c("wane"), noInfSerumKinetics),
addAbkineticsModel("omicron_s", "spike", "omicron", c("y1_o", "t1_o", "r_o", "s"), infTuenisPower2016),
addAbkineticsModel("vax_s", "spike", "vax", c("y1_vax", "t1_vax", "r_vax", "s"), infTuenisPower2016),
addAbkineticsModel("none_ncp", "NCP", "none", c("wane_a"), noInfSerumKinetics),
addAbkineticsModel("omicron_ncp", "NCP", "omicron", c("y1_o_a", "t1_o_a", "r_o_a", "s_a"), infTuenisPower2016),
addAbkineticsModel("vax_ncp", "NCP", "vax", c("y1_vax_a", "t1_vax_a", "r_vax_a", "s_a"), infTuenisPower2016)
),
prior = bind_rows(
addPrior("y1_o", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_o", 7, 21,"unif", 7, 21), # ab kinetics
addPrior("r_o", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("y1_vax", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_vax", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_vax", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("s", 0, 1, "unif", 0, 1), # ab kinetics
addPrior("wane", 0.0, 0.01, "unif", 0.0, 0.01), # observational model
addPrior("y1_o_a", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_o_a", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_o_a", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("y1_vax_a", 0, 6, "unif", 0, 6), # ab kinetics
addPrior("t1_vax_a", 7, 21, "unif", 7, 21), # ab kinetics
addPrior("r_vax_a", 1, 5, "unif", 1, 5), # ab kinetics
addPrior("s_a", 0, 1, "unif", 0, 1), # ab kinetics
addPrior("wane_a", 0.0, 0.01, "unif", 0.0, 0.01) # observational model
)
)
model_w3 <- createSeroJumpModel(
data_sero = sero_data_w3,
data_known = known_inf_w3,
biomarkers = biomarkers,
exposureTypes = exposureTypes,
exposureFitted = exposureFitted,
observationalModel = observationalModel,
abkineticsModel = abkineticsModel,
exposurePriorTime = inf_prior_w3,
exposurePriorTimeType = "empirical"
)
## OUTLINE OF INPUTTED MODEL
## There are 2 measured biomarkers: spike, NCP
## There are 3 exposure types in the study period: none, omicron, vax
## The fitted exposure type is omicron
## PRIOR DISTRIBUTIONS
## Prior parameters of observationalModel are: sigma, sigma_a
## Prior parameters of abkineticsModel are: y1_o, t1_o, r_o, y1_vax, t1_vax, r_vax, s, wane, y1_o_a, t1_o_a, r_o_a, y1_vax_a, t1_vax_a, r_vax_a, s_a, wane_a
## No single entries in data_sero!,
## No individuals with less than 15 days in the study!
## Warning in addExposurePrior_checkempirical(exp_prior, T_max): Warning: The number of rows in the exposure prior dataframe does not match the number of time points in the study
## Warning in addExposurePrior_checkempirical(exp_prior, T_max): Warning: The number of rows in the exposure prior dataframe does not match the number of time points in the study
## There are individuals which have exposure before their first bleed or before their last bleed, ids: 111, 57, 227, 228, 248 . It is hard to perform inference on these people, so we recommend you remove the exposures from the known inf, but, if included, the model ignores these exposures.
Before running the whole model it is good to check the data and the
priors. This can be done using a suit of functions
plotPriors
function.
p1 <- plotSero(model_w3)
p2 <- plotPriorPredictive(model_w3)
p3 <- plotPriorInfection(model_w3)
p1 / p2
p3
rj_settings <- list(
numberChainRuns = 4,
iterations = 200000,
burninPosterior = 100000,
thin = 100
# onDebug = TRUE,
# runParallel = FALSE
)
save_info_w2 <- list(
file_name = "transvir_data",
model_name = "wave_2_non"
)
save_info_w3 <- list(
file_name = "transvir_data",
model_name = "wave_3_non"
)
# Run these but take a while
#model_summary_w2 <- runSeroJump(model_w2, rj_settings, save_info = save_info_w2)
#model_summary_w3 <- runSeroJump(model_w3, rj_settings, save_info = save_info_w3)
model_summary_w2 <- readRDS("model_summary_w2.RDS")
model_summary_w3 <- readRDS("model_summary_w3.RDS")
plotMCMCDiagnosis(model_summary_w2, save_info = save_info_w2)
# takes ages to run these so comment out!
#plotPostFigs(model_summary_w2, save_info = save_info_w2)
plotMCMCDiagnosis(model_summary_w3, save_info = save_info_w3)
# takes ages to run these so comment out!
#plotPostFigs(model_summary_w3, save_info = save_info_w3)