From c4fb00eacdd2cc19ec70a1a9292501809caa80bd Mon Sep 17 00:00:00 2001 From: Naeem Model Date: Wed, 10 Jan 2024 15:08:43 +0000 Subject: Refactor ID and IDEA methods --- NAMESPACE | 4 ++-- R/id.R | 48 +++++++++++++++++++++++------------------------ R/idea.R | 62 ++++++++++++++++++++++++++++++------------------------------- R/server.R | 4 ++-- man/id.Rd | 42 +++++++++++++++++++++++------------------ man/idea.Rd | 44 ++++++++++++++++++++++++------------------- 6 files changed, 108 insertions(+), 96 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 0508cde..dc19a2c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,9 +1,9 @@ # Generated by roxygen2: do not edit by hand -export(ID) -export(IDEA) export(WP) export(app) +export(id) +export(idea) export(seqB) importFrom(methods,is) importFrom(stats,pexp) diff --git a/R/id.R b/R/id.R index 7e8a04d..eef66d6 100644 --- a/R/id.R +++ b/R/id.R @@ -1,11 +1,11 @@ -#' ID method +#' Incidence Decay (ID) #' #' This function implements a least squares estimation method of R0 due to #' Fisman et al. (PloS One, 2013). See details for implementation notes. #' #' The method is based on a straightforward incidence decay model. The estimate #' of R0 is the value which minimizes the sum of squares between observed case -#' counts and cases counts 'expected' under the model. +#' counts and cases counts expected under the model. #' #' This method is based on an approximation of the SIR model, which is most #' valid at the beginning of an epidemic. The method assumes that the mean of @@ -14,33 +14,33 @@ #' is strongly recommended. Users should be careful about units of time (e.g., #' are counts observed daily or weekly?) when implementing. #' -#' @param NT Vector of case counts. -#' @param mu Mean of the serial distribution. This needs to match case counts -#' in time units. For example, if case counts are weekly and the -#' serial distribution has a mean of seven days, then \code{mu} should -#' be set to one. If case counts are daily and the serial distribution -#' has a mean of seven days, then \code{mu} should be set to seven. +#' @param cases Vector of case counts. The vector must be non-empty and only +#' contain positive integers. +#' @param mu Mean of the serial distribution. This must be a positive number. +#' The value should match the case counts in time units. For example, if case +#' counts are weekly and the serial distribution has a mean of seven days, +#' then `mu` should be set to `1`. If case counts are daily and the serial +#' distribution has a mean of seven days, then `mu` should be set to `7`. #' -#' @return \code{ID} returns a single value, the estimate of R0. +#' @return An estimate of the basic reproduction number (R0). +#' +#' @references +#' [Fisman et al. (PloS One, 2013)]( +#' https://doi.org/10.1371/journal.pone.0083622) +#' +#' @seealso [idea()] for a similar method. +#' +#' @export #' #' @examples -#' # Weekly data: -#' NT <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) +#' # Weekly data. +#' cases <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) #' #' # Obtain R0 when the serial distribution has a mean of five days. -#' ID(NT, mu = 5 / 7) +#' id(cases, mu = 5 / 7) #' #' # Obtain R0 when the serial distribution has a mean of three days. -#' ID(NT, mu = 3 / 7) -#' -#' @export -ID <- function(NT, mu) { - NT <- as.numeric(NT) - TT <- length(NT) - s <- (1:TT) / mu - y <- log(NT) / s - - R0_ID <- exp(sum(y) / TT) - - return(R0_ID) +#' id(cases, mu = 3 / 7) +id <- function(cases, mu) { + exp(sum((log(cases) * mu) / seq_along(cases)) / length(cases)) } diff --git a/R/idea.R b/R/idea.R index 53fa653..0549527 100644 --- a/R/idea.R +++ b/R/idea.R @@ -1,11 +1,11 @@ -#' IDEA method +#' Incidence Decay and Exponential Adjustment (IDEA) #' #' This function implements a least squares estimation method of R0 due to #' Fisman et al. (PloS One, 2013). See details for implementation notes. #' -#' This method is closely related to that implemented in \code{ID}. The method -#' is based on an incidence decay model. The estimate of R0 is the value which -#' minimizes the sum of squares between observed case counts and cases counts +#' This method is closely related to that implemented in [id()]. The method is +#' based on an incidence decay model. The estimate of R0 is the value which +#' minimizes the sum of squares between observed case counts and case counts #' expected under the model. #' #' This method is based on an approximation of the SIR model, which is most @@ -15,42 +15,42 @@ #' is strongly recommended. Users should be careful about units of time (e.g., #' are counts observed daily or weekly?) when implementing. #' -#' @param NT Vector of case counts. -#' @param mu Mean of the serial distribution. This needs to match case counts in -#' time units. For example, if case counts are weekly and the serial -#' distribution has a mean of seven days, then \code{mu} should be set -#' to one. If case counts are daily and the serial distribution has a -#' mean of seven days, then \code{mu} should be set to seven. +#' @param cases Vector of case counts. The vector must be of length at least two +#' and only contain positive integers. +#' @param mu Mean of the serial distribution. This must be a positive number. +#' The value should match the case counts in time units. For example, if case +#' counts are weekly and the serial distribution has a mean of seven days, +#' then `mu` should be set to `1`. If case counts are daily and the serial +#' distribution has a mean of seven days, then `mu` should be set to `7`. #' -#' @return \code{IDEA} returns a single value, the estimate of R0. +#' @return An estimate of the basic reproduction number (R0). +#' +#' @references +#' [Fisman et al. (PloS One, 2013)]( +#' https://doi.org/10.1371/journal.pone.0083622) +#' +#' @seealso [id()] for a similar method. +#' +#' @export #' #' @examples #' # Weekly data. -#' NT <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) +#' cases <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) #' #' # Obtain R0 when the serial distribution has a mean of five days. -#' IDEA(NT, mu = 5 / 7) +#' idea(cases, mu = 5 / 7) #' #' # Obtain R0 when the serial distribution has a mean of three days. -#' IDEA(NT, mu = 3 / 7) -#' -#' @export -IDEA <- function(NT, mu) { - if (length(NT) < 2) - print("Warning: length of NT should be at least two.") - else { - NT <- as.numeric(NT) - TT <- length(NT) - s <- (1:TT) / mu +#' idea(cases, mu = 3 / 7) +idea <- function(cases, mu) { + s <- seq_along(cases) / mu - y1 <- log(NT) / s - y2 <- s^2 - y3 <- log(NT) + x1 <- sum(s) + x2 <- sum(s^2) + x3 <- log(cases) - IDEA1 <- sum(y2) * sum(y1) - sum(s) * sum(y3) - IDEA2 <- TT * sum(y2) - sum(s)^2 - IDEA <- exp(IDEA1 / IDEA2) + y1 <- x2 * sum(x3 / s) - x1 * sum(x3) + y2 <- x2 * length(cases) - x1^2 - return(IDEA) - } + exp(y1 / y2) } diff --git a/R/server.R b/R/server.R index a2ba674..4cf87db 100644 --- a/R/server.R +++ b/R/server.R @@ -303,10 +303,10 @@ eval_estimator <- function(input, output, estimator, dataset) { kappa = estimator$kappa)$Rhat, 2) # Incidence Decay else if (estimator$method == "ID") - estimate <- round(ID(unlist(dataset[3]), mu = serial), 2) + estimate <- round(id(unlist(dataset[3]), mu = serial), 2) # Incidence Decay with Exponential Adjustement else if (estimator$method == "IDEA") - estimate <- round(IDEA(unlist(dataset[3]), mu = serial), 2) + estimate <- round(idea(unlist(dataset[3]), mu = serial), 2) return(estimate) } diff --git a/man/id.Rd b/man/id.Rd index 1d32c50..27f49d0 100644 --- a/man/id.Rd +++ b/man/id.Rd @@ -1,22 +1,23 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/ID.R -\name{ID} -\alias{ID} -\title{ID method} +% Please edit documentation in R/id.R +\name{id} +\alias{id} +\title{Incidence Decay (ID)} \usage{ -ID(NT, mu) +id(cases, mu) } \arguments{ -\item{NT}{Vector of case counts.} +\item{cases}{Vector of case counts. The vector must be non-empty and only +contain positive integers.} -\item{mu}{Mean of the serial distribution. This needs to match case counts -in time units. For example, if case counts are weekly and the -serial distribution has a mean of seven days, then \code{mu} should -be set to one. If case counts are daily and the serial distribution -has a mean of seven days, then \code{mu} should be set to seven.} +\item{mu}{Mean of the serial distribution. This must be a positive number. +The value should match the case counts in time units. For example, if case +counts are weekly and the serial distribution has a mean of seven days, +then \code{mu} should be set to \code{1}. If case counts are daily and the serial +distribution has a mean of seven days, then \code{mu} should be set to \code{7}.} } \value{ -\code{ID} returns a single value, the estimate of R0. +An estimate of the basic reproduction number (R0). } \description{ This function implements a least squares estimation method of R0 due to @@ -25,7 +26,7 @@ Fisman et al. (PloS One, 2013). See details for implementation notes. \details{ The method is based on a straightforward incidence decay model. The estimate of R0 is the value which minimizes the sum of squares between observed case -counts and cases counts 'expected' under the model. +counts and cases counts expected under the model. This method is based on an approximation of the SIR model, which is most valid at the beginning of an epidemic. The method assumes that the mean of @@ -35,13 +36,18 @@ is strongly recommended. Users should be careful about units of time (e.g., are counts observed daily or weekly?) when implementing. } \examples{ -# Weekly data: -NT <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) +# Weekly data. +cases <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) # Obtain R0 when the serial distribution has a mean of five days. -ID(NT, mu = 5 / 7) +id(cases, mu = 5 / 7) # Obtain R0 when the serial distribution has a mean of three days. -ID(NT, mu = 3 / 7) - +id(cases, mu = 3 / 7) +} +\references{ +\href{https://doi.org/10.1371/journal.pone.0083622}{Fisman et al. (PloS One, 2013)} +} +\seealso{ +\code{\link[=idea]{idea()}} for a similar method. } diff --git a/man/idea.Rd b/man/idea.Rd index f4c7d14..91c360b 100644 --- a/man/idea.Rd +++ b/man/idea.Rd @@ -1,31 +1,32 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/IDEA.R -\name{IDEA} -\alias{IDEA} -\title{IDEA method} +% Please edit documentation in R/idea.R +\name{idea} +\alias{idea} +\title{Incidence Decay and Exponential Adjustment (IDEA)} \usage{ -IDEA(NT, mu) +idea(cases, mu) } \arguments{ -\item{NT}{Vector of case counts.} +\item{cases}{Vector of case counts. The vector must be of length at least two +and only contain positive integers.} -\item{mu}{Mean of the serial distribution. This needs to match case counts in -time units. For example, if case counts are weekly and the serial -distribution has a mean of seven days, then \code{mu} should be set -to one. If case counts are daily and the serial distribution has a -mean of seven days, then \code{mu} should be set to seven.} +\item{mu}{Mean of the serial distribution. This must be a positive number. +The value should match the case counts in time units. For example, if case +counts are weekly and the serial distribution has a mean of seven days, +then \code{mu} should be set to \code{1}. If case counts are daily and the serial +distribution has a mean of seven days, then \code{mu} should be set to \code{7}.} } \value{ -\code{IDEA} returns a single value, the estimate of R0. +An estimate of the basic reproduction number (R0). } \description{ This function implements a least squares estimation method of R0 due to Fisman et al. (PloS One, 2013). See details for implementation notes. } \details{ -This method is closely related to that implemented in \code{ID}. The method -is based on an incidence decay model. The estimate of R0 is the value which -minimizes the sum of squares between observed case counts and cases counts +This method is closely related to that implemented in \code{\link[=id]{id()}}. The method is +based on an incidence decay model. The estimate of R0 is the value which +minimizes the sum of squares between observed case counts and case counts expected under the model. This method is based on an approximation of the SIR model, which is most @@ -37,12 +38,17 @@ are counts observed daily or weekly?) when implementing. } \examples{ # Weekly data. -NT <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) +cases <- c(1, 4, 10, 5, 3, 4, 19, 3, 3, 14, 4) # Obtain R0 when the serial distribution has a mean of five days. -IDEA(NT, mu = 5 / 7) +idea(cases, mu = 5 / 7) # Obtain R0 when the serial distribution has a mean of three days. -IDEA(NT, mu = 3 / 7) - +idea(cases, mu = 3 / 7) +} +\references{ +\href{https://doi.org/10.1371/journal.pone.0083622}{Fisman et al. (PloS One, 2013)} +} +\seealso{ +\code{\link[=id]{id()}} for a similar method. } -- cgit v1.2.3