From fb8b3d3bac45a6dfd866b60bcc62f92411c90a4d Mon Sep 17 00:00:00 2001 From: "alex.hill@gmail.com" Date: Wed, 2 Oct 2024 10:51:35 +0100 Subject: [PATCH] rename scova to biokinetics --- .gitignore | 1 + NAMESPACE | 4 +- R/{scova.R => biokinetics.R} | 30 ++++---- R/priors.R | 14 ++-- R/simulate.R | 4 +- man/{scova.Rd => biokinetics.Rd} | 74 +++++++++---------- ...{scova_priors.Rd => biokinetics_priors.Rd} | 16 ++-- tests/testthat/test-data.R | 12 +-- tests/testthat/test-extract-parameters.R | 14 ++-- tests/testthat/test-input-validation.R | 20 ++--- .../test-population-stationary-points.R | 4 +- tests/testthat/test-priors.R | 4 +- tests/testthat/test-run-model.R | 4 +- .../test-simulate-individual-trajectories.R | 16 ++-- .../test-simulate-population-trajectories.R | 12 +-- vignettes/{scova.Rmd => biokinetics.Rmd} | 13 +++- vignettes/data.Rmd | 6 +- 17 files changed, 127 insertions(+), 121 deletions(-) rename R/{scova.R => biokinetics.R} (96%) rename man/{scova.Rd => biokinetics.Rd} (67%) rename man/{scova_priors.Rd => biokinetics_priors.Rd} (61%) rename vignettes/{scova.Rmd => biokinetics.Rmd} (90%) diff --git a/.gitignore b/.gitignore index 098c0ef..feb74ee 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ src/stan/**/*.exe src/stan/**/*.EXE inst/doc .idea +*.png diff --git a/NAMESPACE b/NAMESPACE index bc71e05..349881e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,8 +1,8 @@ # Generated by roxygen2: do not edit by hand +export(biokinetics) +export(biokinetics_priors) export(convert_log_scale_inverse) -export(scova) -export(scova_priors) importFrom(R6,R6Class) importFrom(data.table,":=") importFrom(data.table,.BY) diff --git a/R/scova.R b/R/biokinetics.R similarity index 96% rename from R/scova.R rename to R/biokinetics.R index 3abc277..f3234c2 100644 --- a/R/scova.R +++ b/R/biokinetics.R @@ -1,11 +1,11 @@ -##' @title SARS-CoV-2 Antibody Kinetics Model +##' @title Biomarker Kinetics Model ##' -##' @description Create an instance of the SARS-CoV-2 antibody model and -##' fit it to a dataset using Gaussian priors and a given hierarchical model structure. +##' @description Create an instance of the biomarker kinetics model and +##' fit it to a dataset. ##' @export ##' @importFrom R6 R6Class -scova <- R6::R6Class( - "scova", +biokinetics <- R6::R6Class( + "biokinetics", cloneable = FALSE, private = list( priors = NULL, @@ -152,7 +152,7 @@ scova <- R6::R6Class( dt_out <- merge( dt_samples_wide, dt_times, by = "t_id", allow.cartesian = TRUE) - dt_out[, mu := scova_simulate_trajectory( + dt_out[, mu := biokinetics_simulate_trajectory( t, t0_pop, tp_pop, ts_pop, m1_pop, m2_pop, m3_pop), by = c("t", "p", "k", ".draw")] @@ -223,22 +223,22 @@ scova <- R6::R6Class( ), public = list( #' @description Initialise the kinetics model. - #' @return An epikinetics::scova object. + #' @return An epikinetics::biokinetics object. #' @param data Optional data table of model inputs. One of data or file must be provided. See the data vignette #' for required columns: \code{vignette("data", package = "epikinetics")}. #' @param file_path Optional file path to model inputs in CSV format. One of data or file must be provided. - #' @param priors Object of type \link[epikinetics]{scova_priors}. Default scova_priors(). + #' @param priors Object of type \link[epikinetics]{biokinetics_priors}. Default biokinetics_priors(). #' @param covariate_formula Formula specifying hierarchical structure of model. Default ~0. #' @param preds_sd Standard deviation of predictor coefficients. Default 0.25. #' @param time_type One of 'relative' or 'absolute'. Default 'relative'. - initialize = function(priors = scova_priors(), + initialize = function(priors = biokinetics_priors(), data = NULL, file_path = NULL, covariate_formula = ~0, preds_sd = 0.25, time_type = "relative") { - if (!inherits(priors, "scova_priors")) { - stop("'priors' must be of type 'scova_priors'") + if (!inherits(priors, "biokinetics_priors")) { + stop("'priors' must be of type 'biokinetics_priors'") } private$priors <- priors validate_numeric(preds_sd) @@ -409,11 +409,11 @@ scova <- R6::R6Class( logger::log_info("Calculating peak and switch titre values") dt_peak_switch[, `:=`( - mu_0 = scova_simulate_trajectory( + mu_0 = biokinetics_simulate_trajectory( 0, t0_pop, tp_pop, ts_pop, m1_pop, m2_pop, m3_pop), - mu_p = scova_simulate_trajectory( + mu_p = biokinetics_simulate_trajectory( tp_pop, t0_pop, tp_pop, ts_pop, m1_pop, m2_pop, m3_pop), - mu_s = scova_simulate_trajectory( + mu_s = biokinetics_simulate_trajectory( ts_pop, t0_pop, tp_pop, ts_pop, m1_pop, m2_pop, m3_pop)), by = c("p", "k", "draw")] @@ -479,7 +479,7 @@ scova <- R6::R6Class( # Running the C++ code to simulate trajectories for each parameter sample # for each individual logger::log_info("Simulating individual trajectories") - dt_params_ind_traj <- scova_simulate_trajectories(dt_params_ind_trim) + dt_params_ind_traj <- biokinetics_simulate_trajectories(dt_params_ind_trim) dt_params_ind_traj <- data.table::setDT(convert_log_scale_inverse_cpp( dt_params_ind_traj, vars_to_transform = "mu")) diff --git a/R/priors.R b/R/priors.R index 8753bfa..9f3e570 100644 --- a/R/priors.R +++ b/R/priors.R @@ -11,22 +11,22 @@ gaussian_priors <- function(names, mu_values, sigma_values) { ret } -#' @title Construct priors for the SARS-CoV-2 antibody model. +#' @title Construct priors for the biomarker model. #' @export -#' @description The scova model has 6 parameters: t0, tp, ts, m1, m2, m3 corresponding to critical time points and +#' @description The biokinetics model has 6 parameters: t0, tp, ts, m1, m2, m3 corresponding to critical time points and #' gradients. See the model vignette for details: \code{vignette("model", package = "epikinetics")}. Each of these #' parameters has a Gaussian prior, and these can be specified by the user. This function takes means and standard -#' deviations for each prior and constructs an object of type 'scova_priors' to be passed to the model. -#' @return A named list of type 'scova_priors'. +#' deviations for each prior and constructs an object of type 'biokinetics_priors' to be passed to the model. +#' @return A named list of type 'biokinetics_priors'. #' @param mu_values Mean of Gaussian prior for each of t0, tp, ts, m1, m2, m3, in order. #' @param sigma_values Standard deviation of Gaussian prior for each of t0, tp, ts, m1, m2, m3, in order. #' @examples -#' priors <- scova_priors(mu_values = c(4.0, 10, 60, 0.25, -0.02, 0), +#' priors <- biokinetics_priors(mu_values = c(4.0, 10, 60, 0.25, -0.02, 0), #' sigma_values = c(2.0, 2.0, 3.0, 0.01, 0.01, 0.01)) -scova_priors <- function(mu_values = c(4.0, 10, 60, 0.25, -0.02, 0), +biokinetics_priors <- function(mu_values = c(4.0, 10, 60, 0.25, -0.02, 0), sigma_values = c(2.0, 2.0, 3.0, 0.01, 0.01, 0.01)) { names <- c("t0", "tp", "ts", "m1", "m2", "m3") ret <- gaussian_priors(names, mu_values, sigma_values) - class(ret) <- append("scova_priors", class(ret)) + class(ret) <- append("biokinetics_priors", class(ret)) ret } diff --git a/R/simulate.R b/R/simulate.R index 65e3987..a0c411e 100644 --- a/R/simulate.R +++ b/R/simulate.R @@ -1,4 +1,4 @@ -scova_simulate_trajectory <- function(t, t0, tp, ts, m1, m2, m3) { +biokinetics_simulate_trajectory <- function(t, t0, tp, ts, m1, m2, m3) { mu <- t0 if (t < tp) { mu <- mu + m1 * t @@ -10,6 +10,6 @@ scova_simulate_trajectory <- function(t, t0, tp, ts, m1, m2, m3) { max(mu, 0) } -scova_simulate_trajectories <- function(dat) { +biokinetics_simulate_trajectories <- function(dat) { data.table::setDT(simulate_trajectories_cpp(dat)) } diff --git a/man/scova.Rd b/man/biokinetics.Rd similarity index 67% rename from man/scova.Rd rename to man/biokinetics.Rd index 24adf49..f89bd87 100644 --- a/man/scova.Rd +++ b/man/biokinetics.Rd @@ -1,32 +1,32 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/scova.R -\name{scova} -\alias{scova} -\title{SARS-CoV-2 Antibody Kinetics Model} +% Please edit documentation in R/biokinetics.R +\name{biokinetics} +\alias{biokinetics} +\title{Biomarker Kinetics Model} \description{ -Create an instance of the SARS-CoV-2 antibody model and -fit it to a dataset using Gaussian priors and a given hierarchical model structure. +Create an instance of the biomarker kinetics model and +fit it to a dataset. } \section{Methods}{ \subsection{Public methods}{ \itemize{ -\item \href{#method-scova-new}{\code{scova$new()}} -\item \href{#method-scova-fit}{\code{scova$fit()}} -\item \href{#method-scova-extract_population_parameters}{\code{scova$extract_population_parameters()}} -\item \href{#method-scova-extract_individual_parameters}{\code{scova$extract_individual_parameters()}} -\item \href{#method-scova-simulate_population_trajectories}{\code{scova$simulate_population_trajectories()}} -\item \href{#method-scova-population_stationary_points}{\code{scova$population_stationary_points()}} -\item \href{#method-scova-simulate_individual_trajectories}{\code{scova$simulate_individual_trajectories()}} +\item \href{#method-biokinetics-new}{\code{biokinetics$new()}} +\item \href{#method-biokinetics-fit}{\code{biokinetics$fit()}} +\item \href{#method-biokinetics-extract_population_parameters}{\code{biokinetics$extract_population_parameters()}} +\item \href{#method-biokinetics-extract_individual_parameters}{\code{biokinetics$extract_individual_parameters()}} +\item \href{#method-biokinetics-simulate_population_trajectories}{\code{biokinetics$simulate_population_trajectories()}} +\item \href{#method-biokinetics-population_stationary_points}{\code{biokinetics$population_stationary_points()}} +\item \href{#method-biokinetics-simulate_individual_trajectories}{\code{biokinetics$simulate_individual_trajectories()}} } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-new}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-new}{}}} \subsection{Method \code{new()}}{ Initialise the kinetics model. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$new( - priors = scova_priors(), +\if{html}{\out{
}}\preformatted{biokinetics$new( + priors = biokinetics_priors(), data = NULL, file_path = NULL, covariate_formula = ~0, @@ -38,7 +38,7 @@ Initialise the kinetics model. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{priors}}{Object of type \link[epikinetics]{scova_priors}. Default scova_priors().} +\item{\code{priors}}{Object of type \link[epikinetics]{biokinetics_priors}. Default biokinetics_priors().} \item{\code{data}}{Optional data table of model inputs. One of data or file must be provided. See the data vignette for required columns: \code{vignette("data", package = "epikinetics")}.} @@ -54,16 +54,16 @@ for required columns: \code{vignette("data", package = "epikinetics")}.} \if{html}{\out{
}} } \subsection{Returns}{ -An epikinetics::scova object. +An epikinetics::biokinetics object. } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-fit}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-fit}{}}} \subsection{Method \code{fit()}}{ Fit the model and return CmdStanMCMC fitted model object. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$fit(...)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{biokinetics$fit(...)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -79,12 +79,12 @@ A CmdStanMCMC fitted model object: \url{https://mc-stan.org/cmdstanr/reference/C } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-extract_population_parameters}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-extract_population_parameters}{}}} \subsection{Method \code{extract_population_parameters()}}{ Extract fitted population parameters \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$extract_population_parameters( +\if{html}{\out{
}}\preformatted{biokinetics$extract_population_parameters( n_draws = 2500, human_readable_covariates = TRUE )}\if{html}{\out{
}} @@ -104,12 +104,12 @@ A data.table } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-extract_individual_parameters}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-extract_individual_parameters}{}}} \subsection{Method \code{extract_individual_parameters()}}{ Extract fitted individual parameters \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$extract_individual_parameters( +\if{html}{\out{
}}\preformatted{biokinetics$extract_individual_parameters( n_draws = 2500, include_variation_params = TRUE, human_readable_covariates = TRUE @@ -132,12 +132,12 @@ A data.table } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-simulate_population_trajectories}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-simulate_population_trajectories}{}}} \subsection{Method \code{simulate_population_trajectories()}}{ Process the model results into a data table of titre values over time. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$simulate_population_trajectories( +\if{html}{\out{
}}\preformatted{biokinetics$simulate_population_trajectories( time_type = "relative", t_max = 150, summarise = TRUE, @@ -169,12 +169,12 @@ titre_type and a column for each covariate in the hierarchical model. See the da } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-population_stationary_points}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-population_stationary_points}{}}} \subsection{Method \code{population_stationary_points()}}{ Process the stan model results into a data.table. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$population_stationary_points(n_draws = 2500)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{biokinetics$population_stationary_points(n_draws = 2500)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -191,13 +191,13 @@ mu_s_me, and a column for each covariate. See the data vignette for details: } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-scova-simulate_individual_trajectories}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-biokinetics-simulate_individual_trajectories}{}}} \subsection{Method \code{simulate_individual_trajectories()}}{ Simulate individual trajectories from the model. This is computationally expensive and may take a while to run if n_draws is large. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{scova$simulate_individual_trajectories( +\if{html}{\out{
}}\preformatted{biokinetics$simulate_individual_trajectories( summarise = TRUE, n_draws = 2500, time_shift = 0 diff --git a/man/scova_priors.Rd b/man/biokinetics_priors.Rd similarity index 61% rename from man/scova_priors.Rd rename to man/biokinetics_priors.Rd index 0b9525c..306c3f0 100644 --- a/man/scova_priors.Rd +++ b/man/biokinetics_priors.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/priors.R -\name{scova_priors} -\alias{scova_priors} -\title{Construct priors for the SARS-CoV-2 antibody model.} +\name{biokinetics_priors} +\alias{biokinetics_priors} +\title{Construct priors for the biomarker model.} \usage{ -scova_priors( +biokinetics_priors( mu_values = c(4, 10, 60, 0.25, -0.02, 0), sigma_values = c(2, 2, 3, 0.01, 0.01, 0.01) ) @@ -15,15 +15,15 @@ scova_priors( \item{sigma_values}{Standard deviation of Gaussian prior for each of t0, tp, ts, m1, m2, m3, in order.} } \value{ -A named list of type 'scova_priors'. +A named list of type 'biokinetics_priors'. } \description{ -The scova model has 6 parameters: t0, tp, ts, m1, m2, m3 corresponding to critical time points and +The biokinetics model has 6 parameters: t0, tp, ts, m1, m2, m3 corresponding to critical time points and gradients. See the model vignette for details: \code{vignette("model", package = "epikinetics")}. Each of these parameters has a Gaussian prior, and these can be specified by the user. This function takes means and standard -deviations for each prior and constructs an object of type 'scova_priors' to be passed to the model. +deviations for each prior and constructs an object of type 'biokinetics_priors' to be passed to the model. } \examples{ -priors <- scova_priors(mu_values = c(4.0, 10, 60, 0.25, -0.02, 0), +priors <- biokinetics_priors(mu_values = c(4.0, 10, 60, 0.25, -0.02, 0), sigma_values = c(2.0, 2.0, 3.0, 0.01, 0.01, 0.01)) } diff --git a/tests/testthat/test-data.R b/tests/testthat/test-data.R index 513e6fa..3ef31cf 100644 --- a/tests/testthat/test-data.R +++ b/tests/testthat/test-data.R @@ -8,8 +8,8 @@ local_mocked_bindings( test_that("Can construct stan data", { dt <- data.table::fread(system.file("delta_full.rds", package = "epikinetics")) - mod <- scova$new(data = dt, - priors = scova_priors(), + mod <- biokinetics$new(data = dt, + priors = biokinetics_priors(), covariate_formula = ~0 + infection_history, preds_sd = 0.25, time_type = "relative") @@ -20,12 +20,12 @@ test_that("Can construct stan data", { }) test_that("Can initialise file path data", { - expect_true(inherits(scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), - priors = scova_priors()), "scova")) + expect_true(inherits(biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + priors = biokinetics_priors()), "biokinetics")) }) test_that("Can provide data directly", { dat <- data.table::fread(system.file("delta_full.rds", package = "epikinetics")) - expect_true(inherits(scova$new(data = dat, - priors = scova_priors()), "scova")) + expect_true(inherits(biokinetics$new(data = dat, + priors = biokinetics_priors()), "biokinetics")) }) diff --git a/tests/testthat/test-extract-parameters.R b/tests/testthat/test-extract-parameters.R index 1690e5b..de0e955 100644 --- a/tests/testthat/test-extract-parameters.R +++ b/tests/testthat/test-extract-parameters.R @@ -7,17 +7,17 @@ local_mocked_bindings( ) test_that("Cannot retrieve population params until model is fitted", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics")) + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics")) expect_error(mod$extract_population_parameters(), "Model has not been fitted yet. Call 'fit' before calling this function.") }) test_that("Cannot retrieve individual params until model is fitted", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics")) + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics")) expect_error(mod$extract_individual_parameters(), "Model has not been fitted yet. Call 'fit' before calling this function.") }) test_that("Can extract population parameters without human readable covariates", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() params <- mod$extract_population_parameters(n_draws = 10, human_readable_covariates = FALSE) @@ -26,7 +26,7 @@ test_that("Can extract population parameters without human readable covariates", }) test_that("Can extract population parameters with human readable covariates", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() params <- mod$extract_population_parameters(n_draws = 10, human_readable_covariates = TRUE) @@ -36,7 +36,7 @@ test_that("Can extract population parameters with human readable covariates", { }) test_that("Can extract individual parameters without human readable covariates", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() params <- mod$extract_individual_parameters(n_draws = 10, @@ -47,7 +47,7 @@ test_that("Can extract individual parameters without human readable covariates", }) test_that("Can extract individual parameters with human readable covariates", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() params <- mod$extract_individual_parameters(n_draws = 10, @@ -58,7 +58,7 @@ test_that("Can extract individual parameters with human readable covariates", { }) test_that("Can extract individual parameters with variation params", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() params <- mod$extract_individual_parameters(n_draws = 10, diff --git a/tests/testthat/test-input-validation.R b/tests/testthat/test-input-validation.R index 4242d0c..d67aa79 100644 --- a/tests/testthat/test-input-validation.R +++ b/tests/testthat/test-input-validation.R @@ -1,41 +1,41 @@ test_that("One of data or file required", { - expect_error(scova$new(), "One of 'data' or 'file_path' must be provided") + expect_error(biokinetics$new(), "One of 'data' or 'file_path' must be provided") }) test_that("Only one of data or file can be provided", { - expect_error(scova$new(data = data.table::data.table(), file_path = "some/where"), + expect_error(biokinetics$new(data = data.table::data.table(), file_path = "some/where"), "Only one of 'data' or 'file_path' should be provided") }) -test_that("Priors must be of type 'scova_priors'", { - expect_error(scova$new(priors = list(t0 = 1, t2 = 3)), - "'priors' must be of type 'scova_priors'") +test_that("Priors must be of type 'biokinetics_priors'", { + expect_error(biokinetics$new(priors = list(t0 = 1, t2 = 3)), + "'priors' must be of type 'biokinetics_priors'") }) test_that("preds_sd must be numeric", { - expect_error(scova$new(preds_sd = "bad"), + expect_error(biokinetics$new(preds_sd = "bad"), "'preds_sd' must be numeric") }) test_that("Time type must be 'absolute' or 'relative'", { - expect_error(scova$new(time_type = "bad"), + expect_error(biokinetics$new(time_type = "bad"), "'time_type' must be one of 'relative' or 'absolute'") }) test_that("Covariate formula must be a formula", { dat <- data.table(test = 1) - expect_error(scova$new(data = dat, covariate_formula = "bad"), + expect_error(biokinetics$new(data = dat, covariate_formula = "bad"), "'covariate_formula' must be a formula") }) test_that("Covariates must be present in data", { dat <- data.table(test = 1) - expect_error(scova$new(data = dat, covariate_formula = 0~ bad), + expect_error(biokinetics$new(data = dat, covariate_formula = 0~ bad), "All variables in 'covariate_formula' must correspond to data columns. Found unknown variables: bad") }) test_that("Data must be a data.table", { dat <- data.frame(test = 1) - expect_error(scova$new(data = dat), + expect_error(biokinetics$new(data = dat), "'data' must be a data.table") }) diff --git a/tests/testthat/test-population-stationary-points.R b/tests/testthat/test-population-stationary-points.R index 2e343c1..668dc3b 100644 --- a/tests/testthat/test-population-stationary-points.R +++ b/tests/testthat/test-population-stationary-points.R @@ -7,12 +7,12 @@ local_mocked_bindings( ) test_that("Cannot retrieve data until model is fitted", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics")) + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics")) expect_error(mod$population_stationary_points(), "Model has not been fitted yet. Call 'fit' before calling this function.") }) test_that("Can get population stationary poins", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() result <- mod$population_stationary_points() diff --git a/tests/testthat/test-priors.R b/tests/testthat/test-priors.R index 095c621..881d809 100644 --- a/tests/testthat/test-priors.R +++ b/tests/testthat/test-priors.R @@ -6,9 +6,9 @@ test_that("Can construct named list of Gaussian prior parameters", { }) test_that("Can construct cab prior parameters", { - priors <- scova_priors(mu_values = c(1, 2, 3, 4, 5, 6), sigma_values = c(7, 8, 9, 10, 11, 12)) + priors <- biokinetics_priors(mu_values = c(1, 2, 3, 4, 5, 6), sigma_values = c(7, 8, 9, 10, 11, 12)) expect_s3_class(priors, "gaussian_priors") - expect_s3_class(priors, "scova_priors") + expect_s3_class(priors, "biokinetics_priors") expect_true(is.list(priors)) expect_equal(unclass(priors), list("mu_t0" = 1, "mu_tp" = 2, "mu_ts" = 3, "mu_m1" = 4, "mu_m2" = 5, "mu_m3" = 6, diff --git a/tests/testthat/test-run-model.R b/tests/testthat/test-run-model.R index 0c45b73..545a746 100644 --- a/tests/testthat/test-run-model.R +++ b/tests/testthat/test-run-model.R @@ -7,8 +7,8 @@ local_mocked_bindings( ) test_that("Can fit model with arguments", { - res <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), - priors = scova_priors())$fit(chains = 4, + res <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + priors = biokinetics_priors())$fit(chains = 4, parallel_chains = 4, iter_warmup = 100, iter_sampling = 400, diff --git a/tests/testthat/test-simulate-individual-trajectories.R b/tests/testthat/test-simulate-individual-trajectories.R index 208e54d..9fbaf89 100644 --- a/tests/testthat/test-simulate-individual-trajectories.R +++ b/tests/testthat/test-simulate-individual-trajectories.R @@ -8,7 +8,7 @@ test_that("Cpp and R function produce same values", { m2 = 1, m3 = 1.5 ) - res_pop <- dat_pop[, mu := scova_simulate_trajectory(t, t0, tp, ts, m1, m2, m3), by = "t"] + res_pop <- dat_pop[, mu := biokinetics_simulate_trajectory(t, t0, tp, ts, m1, m2, m3), by = "t"] dat_ind <- data.table(stan_id = 1L, t_max = t_max, k = 3L, @@ -21,7 +21,7 @@ test_that("Cpp and R function produce same values", { m3_ind = 1.5 ) - res_ind <- scova_simulate_trajectories(dat_ind) + res_ind <- biokinetics_simulate_trajectories(dat_ind) expect_equal(res_pop$mu, res_ind$mu) }) @@ -34,12 +34,12 @@ local_mocked_bindings( ) test_that("Cannot retrieve trajectories until model is fitted", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics")) + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics")) expect_error(mod$simulate_individual_trajectories(), "Model has not been fitted yet. Call 'fit' before calling this function.") }) test_that("Validates inputs", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() expect_error(mod$simulate_individual_trajectories(summarise = "bad"), "'summarise' must be logical") @@ -48,7 +48,7 @@ test_that("Validates inputs", { }) test_that("Can retrieve summarised trajectories", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_individual_trajectories(summarise = TRUE, n_draws = 10) @@ -56,7 +56,7 @@ test_that("Can retrieve summarised trajectories", { }) test_that("Can retrieve un-summarised trajectories", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_individual_trajectories(summarise = FALSE, n_draws = 10) @@ -65,7 +65,7 @@ test_that("Can retrieve un-summarised trajectories", { }) test_that("Only n_draws draws are returned", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_individual_trajectories(summarise = FALSE, n_draws = 10) @@ -73,7 +73,7 @@ test_that("Only n_draws draws are returned", { }) test_that("Exposure dates are brought forward by time_shift days", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_individual_trajectories(summarise = FALSE, n_draws = 10) diff --git a/tests/testthat/test-simulate-population-trajectories.R b/tests/testthat/test-simulate-population-trajectories.R index cf69004..cc0addb 100644 --- a/tests/testthat/test-simulate-population-trajectories.R +++ b/tests/testthat/test-simulate-population-trajectories.R @@ -7,12 +7,12 @@ local_mocked_bindings( ) test_that("Cannot retrieve trajectories until model is fitted", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics")) + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics")) expect_error(mod$simulate_population_trajectories(), "Model has not been fitted yet. Call 'fit' before calling this function.") }) test_that("Validates inputs", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() expect_error(mod$simulate_population_trajectories(summarise = "bad"), "'summarise' must be logical") @@ -22,7 +22,7 @@ test_that("Validates inputs", { }) test_that("Can retrieve summarised trajectories", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_population_trajectories(summarise = TRUE) @@ -30,7 +30,7 @@ test_that("Can retrieve summarised trajectories", { }) test_that("Can retrieve un-summarised trajectories", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_population_trajectories(summarise = FALSE) @@ -40,7 +40,7 @@ test_that("Can retrieve un-summarised trajectories", { }) test_that("Absolute dates are returned if time_type is 'absolute'", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_population_trajectories(summarise = TRUE, time_type = "absolute") @@ -49,7 +49,7 @@ test_that("Absolute dates are returned if time_type is 'absolute'", { }) test_that("Only times up to t_max are returned", { - mod <- scova$new(file_path = system.file("delta_full.rds", package = "epikinetics"), + mod <- biokinetics$new(file_path = system.file("delta_full.rds", package = "epikinetics"), covariate_formula = ~0 + infection_history) mod$fit() trajectories <- mod$simulate_population_trajectories(summarise = TRUE, t_max = 10) diff --git a/vignettes/scova.Rmd b/vignettes/biokinetics.Rmd similarity index 90% rename from vignettes/scova.Rmd rename to vignettes/biokinetics.Rmd index 026c159..88e7d42 100644 --- a/vignettes/scova.Rmd +++ b/vignettes/biokinetics.Rmd @@ -1,8 +1,8 @@ --- -title: "SARS-CoV-2 antibody model: replicating paper figures" +title: "biokinetics case study" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{SARS-CoV-2 antibody model: replicating paper figures} + %\VignetteIndexEntry{biokinetics case study} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -14,15 +14,20 @@ knitr::opts_chunk$set( ) ``` +The underlying `biokinetics` model was developed in the following paper: +[Russell TW et al. Real-time estimation of immunological responses against emerging SARS-CoV-2 variants in the UK: a mathematical modelling study. Lancet Infect Dis. 2024 Sep 11:S1473-3099(24)00484-5](https://doi.org/10.1016/s1473-3099(24)00484-5) + +This vignette demonstrates how to use the `epikinetics` package to replicate some of the key paper figures. + # Fitting the model -To initialise a model object, the only required argument is a path to the data in CSV format, or a [data.table]("https://cran.r-project.org/web/packages/data.table/index.html"). See [scova](../reference/scova.html) for all available arguments. In this vignette we use a dataset representing the Delta wave which is installed with this package, specifying a hierarchical model that just looks at the effect of infection history. +To initialise a model object, the only required argument is a path to the data in CSV format, or a [data.table]("https://cran.r-project.org/web/packages/data.table/index.html"). See [biokinetics](../reference/biokinetics.html) for all available arguments. In this vignette we use a dataset representing the Delta wave which is installed with this package, specifying a hierarchical model that just looks at the effect of infection history. The `fit` method then has the same function signature as the underlying [cmdstanr::sample](https://mc-stan.org/cmdstanr/reference/model-method-sample.html) method. Here we specify a relatively small number of iterations of the algorithm to limit the time it takes to compile this vignette. ```{r, warning=FALSE, message=FALSE, results="hide"} dat <- data.table::fread(system.file("delta_full.rds", package = "epikinetics")) -mod <- epikinetics::scova$new(data = dat, covariate_formula = ~0 + infection_history) +mod <- epikinetics::biokinetics$new(data = dat, covariate_formula = ~0 + infection_history) delta <- mod$fit(parallel_chains = 4, iter_warmup = 50, iter_sampling = 200, diff --git a/vignettes/data.Rmd b/vignettes/data.Rmd index 6006154..af88f7f 100644 --- a/vignettes/data.Rmd +++ b/vignettes/data.Rmd @@ -39,17 +39,17 @@ After fitting a model, a [CmdStanMCMC](https://mc-stan.org/cmdstanr/reference/Cm that users who are already familiar with `cmdstanr` are free to do what they want with the fitted model. **Important!** -**The data provided to `scova$new` is converted to a base2 log scale before inference is performed. This means that if working +**The data provided to `biokinetics$new` is converted to a base2 log scale before inference is performed. This means that if working directly with the fitted `CmdStanMCMC` all values will be on this scale. The package provides a helper function for converting back to the original scale: [convert_log_scale_inverse](../reference/convert_log_scale_inverse.html).** Three further functions provide model outputs that we think are particularly useful in [data.table](https://cran.r-project.org/web/packages/data.table/) format. -[Scova](../reference/scova.html) contains documentation on each of these functions so please read that first; this Vignette provides +[biokinetics](../reference/biokinetics.html) contains documentation on each of these functions so please read that first; this Vignette provides guidance on the correct interpretation of each column in the returned tables. (In these functions data is returned on the original scale). ## simulate_population_trajectories -See the documentation for this function [here](../reference/scova.html#method-simulate-population-trajectories). +See the documentation for this function [here](../reference/biokinetics.html#method-simulate-population-trajectories). There are 2 different output formats depending on whether the provided `summarise` argument is `TRUE` or `FALSE`. * `summarise = TRUE`