From 573a2fed09571f5dc9d7e0cc36303ecd89052c67 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 9 Jun 2023 18:04:53 +0100 Subject: [PATCH] add an internal function --- R/dist.R | 62 +++++++++++++++++++-------------- man/dist_spec_plus.Rd | 30 ++++++++++++++++ man/plus-.dist_spec.Rd | 12 ++----- tests/testthat/test-dist_spec.R | 2 +- 4 files changed, 68 insertions(+), 38 deletions(-) create mode 100644 man/dist_spec_plus.Rd diff --git a/R/dist.R b/R/dist.R index 1662fda41..044a4afeb 100644 --- a/R/dist.R +++ b/R/dist.R @@ -1058,39 +1058,14 @@ dist_spec <- function(mean, sd = 0, mean_sd = 0, sd_sd = 0, #' combine. #' @param e2 The second delay distribution (from a call to [dist_spec()]) to #' combine. -#' @param tolerance A numeric value that sets the cumulative probability -#' to retain when truncating the cumulative distribution function of the -#' combined nonparametric delays. The default value is 0.001 with this retaining -#' 0.999 of the cumulative probability. Note that using a larger tolerance may -#' result in a smaller number of points in the combined nonparametric delay but -#' may also impact the accuracy of the combined delay (i.e., change the mean -#' and standard deviation). #' #' @return A delay distribution representing the sum of the two delays #' (with class [dist_spec()]) #' #' @author Sebastian Funk -#' @method + dist_spec +#' @author Sam Abbott #' @importFrom stats convolve -#' @export -#' -#' @examples -#' # A fixed lognormal distribution with mean 5 and sd 1. -#' lognormal <- dist_spec( -#' mean = 1.6, sd = 1, max = 20, distribution = "lognormal" -#' ) -#' lognormal + lognormal -#' -#' # An uncertain gamma distribution with mean 3 and sd 2 -#' gamma <- dist_spec( -#' mean = 3, sd = 2, mean_sd = 0.5, sd_sd = 0.5, max = 20, -#' distribution = "gamma" -#' ) -#' lognormal + gamma -#' -#' # Using tolerance parameter -#' EpiNow2:::`+.dist_spec`(lognormal, lognormal, tolerance = 0.5) -`+.dist_spec` <- function(e1, e2, tolerance = 0.001) { +dist_spec_plus <- function(e1, e2, tolerance = 0.001) { ## process delay distributions delays <- c(e1, e2) ## combine any nonparametric delays that can be combined @@ -1119,6 +1094,39 @@ dist_spec <- function(mean, sd = 0, mean_sd = 0, sd_sd = 0, return(delays) } +#' Creates a delay distribution as the sum of two other delay distributions +#' +#' This is done via convolution with `stats::convolve()`. Nonparametric delays +#' that can be combined are processed together, and their cumulative +#' distribution function is truncated at a specified tolerance level, ensuring +#' numeric stability. +#' +#' @return A delay distribution representing the sum of the two delays +#' (with class [dist_spec()]) +#' @inheritParams dist_spec_plus +#' @author Sebastian Funk +#' @method + dist_spec +#' @export +#' @examples +#' # A fixed lognormal distribution with mean 5 and sd 1. +#' lognormal <- dist_spec( +#' mean = 1.6, sd = 1, max = 20, distribution = "lognormal" +#' ) +#' lognormal + lognormal +#' +#' # An uncertain gamma distribution with mean 3 and sd 2 +#' gamma <- dist_spec( +#' mean = 3, sd = 2, mean_sd = 0.5, sd_sd = 0.5, max = 20, +#' distribution = "gamma" +#' ) +#' lognormal + gamma +#' +#' # Using tolerance parameter +#' EpiNow2:::dist_spec_plus(lognormal, lognormal, tolerance = 0.5) +`+.dist_spec` <- function(e1, e2) { + dist_spec_plus(e1, e2, tolerance = 0.001) +} + #' Combines multiple delay distributions for further processing #' #' This combines the parameters so that they can be fed as multiple delay diff --git a/man/dist_spec_plus.Rd b/man/dist_spec_plus.Rd new file mode 100644 index 000000000..112b23afa --- /dev/null +++ b/man/dist_spec_plus.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dist.R +\name{dist_spec_plus} +\alias{dist_spec_plus} +\title{Creates a delay distribution as the sum of two other delay distributions} +\usage{ +dist_spec_plus(e1, e2, tolerance = 0.001) +} +\arguments{ +\item{e1}{The first delay distribution (from a call to \code{\link[=dist_spec]{dist_spec()}}) to +combine.} + +\item{e2}{The second delay distribution (from a call to \code{\link[=dist_spec]{dist_spec()}}) to +combine.} +} +\value{ +A delay distribution representing the sum of the two delays +(with class \code{\link[=dist_spec]{dist_spec()}}) +} +\description{ +This is done via convolution with \code{stats::convolve()}. Nonparametric delays +that can be combined are processed together, and their cumulative +distribution function is truncated at a specified tolerance level, ensuring +numeric stability. +} +\author{ +Sebastian Funk + +Sam Abbott +} diff --git a/man/plus-.dist_spec.Rd b/man/plus-.dist_spec.Rd index 8ffbad7b0..9e737ff78 100644 --- a/man/plus-.dist_spec.Rd +++ b/man/plus-.dist_spec.Rd @@ -4,7 +4,7 @@ \alias{+.dist_spec} \title{Creates a delay distribution as the sum of two other delay distributions} \usage{ -\method{+}{dist_spec}(e1, e2, tolerance = 0.001) +\method{+}{dist_spec}(e1, e2) } \arguments{ \item{e1}{The first delay distribution (from a call to \code{\link[=dist_spec]{dist_spec()}}) to @@ -12,14 +12,6 @@ combine.} \item{e2}{The second delay distribution (from a call to \code{\link[=dist_spec]{dist_spec()}}) to combine.} - -\item{tolerance}{A numeric value that sets the cumulative probability -to retain when truncating the cumulative distribution function of the -combined nonparametric delays. The default value is 0.001 with this retaining -0.999 of the cumulative probability. Note that using a larger tolerance may -result in a smaller number of points in the combined nonparametric delay but -may also impact the accuracy of the combined delay (i.e., change the mean -and standard deviation).} } \value{ A delay distribution representing the sum of the two delays @@ -46,7 +38,7 @@ gamma <- dist_spec( lognormal + gamma # Using tolerance parameter -EpiNow2:::`+.dist_spec`(lognormal, lognormal, tolerance = 0.5) +EpiNow2:::dist_spec_plus(lognormal, lognormal, tolerance = 0.5) } \author{ Sebastian Funk diff --git a/tests/testthat/test-dist_spec.R b/tests/testthat/test-dist_spec.R index 2845157cc..f2887155e 100644 --- a/tests/testthat/test-dist_spec.R +++ b/tests/testthat/test-dist_spec.R @@ -121,7 +121,7 @@ test_that("Testing `+.dist_spec` function with tolerance parameter", { combined_default <- `+.dist_spec`(lognormal, gamma) # Compute combined distribution with larger tolerance - combined_larger_tolerance <- `+.dist_spec`( + combined_larger_tolerance <- EpiNow2:::dist_spec_plus( lognormal, gamma, tolerance = 0.01 )