diff --git a/.github/workflows/check-cmdstan.yaml b/.github/workflows/check-cmdstan.yaml index e75b719..033b7cb 100644 --- a/.github/workflows/check-cmdstan.yaml +++ b/.github/workflows/check-cmdstan.yaml @@ -51,7 +51,7 @@ jobs: - name: Compile model and check syntax run: | stan_file <- file.path(tempdir(), "pcd_functions.stan") - primarycensoreddist::pcd_load_stan_functions( + primarycensored::pcd_load_stan_functions( wrap_in_block = TRUE, write_to_file = TRUE, output_file = stan_file diff --git a/CITATION.cff b/CITATION.cff index 7130f71..cb68354 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,17 +2,17 @@ # CITATION file created with {cffr} R package # See also: https://docs.ropensci.org/cffr/ # -------------------------------------------- - + cff-version: 1.2.0 -message: 'To cite package "primarycensoreddist" in publications use:' +message: 'To cite package "primarycensored" in publications use:' type: software license: MIT -title: 'primarycensoreddist: Primary Event Censored Distributions in R and Stan' +title: 'primarycensored: Primary Event Censored Distributions in R and Stan' version: 0.1.0.1000 doi: 10.5281/zenodo.13632839 identifiers: - type: url - value: https://github.com/epinowcast/primarycensoreddist/ + value: https://github.com/epinowcast/primarycensored/ abstract: This package provides both R functions for working with primary event censored distributions and Stan implementations for use in Bayesian modeling. Primary event censored distributions are useful for modeling delayed reporting scenarios in epidemiology @@ -25,15 +25,15 @@ authors: orcid: https://orcid.org/0000-0001-8057-8037 preferred-citation: type: manual - title: 'primarycensoreddist: Primary Event Censored Distributions in R and Stan' + title: 'primarycensored: Primary Event Censored Distributions in R and Stan' authors: - name: Sam Abbott email: contact@samabbott.co.uk orcid: https://orcid.org/0000-0001-8057-8037 year: '2024' doi: 10.5281/zenodo.13632839 -repository-code: https://github.com/epinowcast/primarycensoreddist/issues/ -url: https://primarycensoreddist.epinowcast.org +repository-code: https://github.com/epinowcast/primarycensored/issues/ +url: https://primarycensored.epinowcast.org contact: - name: Sam Abbott email: contact@samabbott.co.uk @@ -195,4 +195,3 @@ references: orcid: https://orcid.org/0000-0002-7840-692X year: '2024' doi: 10.32614/CRAN.package.usethis - diff --git a/DESCRIPTION b/DESCRIPTION index 16eb8a2..8fd428b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,4 +1,4 @@ -Package: primarycensoreddist +Package: primarycensored Title: Primary Event Censored Distributions in R and Stan Version: 0.5.0.1000 Authors@R: @@ -22,17 +22,18 @@ Authors@R: role = c("ctb"), email = "sebastian.funk@lshtm.ac.uk", comment = c(ORCID = "0000-0002-2842-3406"))) -Description: This package provides both R functions for working with primary +Description: This package provides R functions for working with primary event censored distributions and Stan implementations for use in Bayesian modeling. Primary event censored distributions are useful for modeling delayed reporting scenarios in epidemiology and other fields. It provides support for arbitrary delay distributions, a range of common primary distributions, and allows for truncation and secondary event censoring - to be accounted for. + to be accounted for. In addition, it provides both frequentist and Bayesian + methods for fitting primary event censored distributions to data. License: MIT + file LICENSE -URL: https://primarycensoreddist.epinowcast.org, - https://github.com/epinowcast/primarycensoreddist/ -BugReports: https://github.com/epinowcast/primarycensoreddist/issues/ +URL: https://primarycensored.epinowcast.org, + https://github.com/epinowcast/primarycensored/ +BugReports: https://github.com/epinowcast/primarycensored/issues/ Depends: R (>= 4.0.0) Imports: diff --git a/LICENSE b/LICENSE index 2c010e2..c4ee1cd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,2 +1,2 @@ YEAR: 2024 -COPYRIGHT HOLDER: primarycensoreddist authors +COPYRIGHT HOLDER: primarycensored authors diff --git a/LICENSE.md b/LICENSE.md index 1ccebc0..a730714 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # MIT License -Copyright (c) 2024 primarycensoreddist authors +Copyright (c) 2024 primarycensored authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/NAMESPACE b/NAMESPACE index 96309f2..7257cc4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,17 +1,17 @@ # Generated by roxygen2: do not edit by hand -S3method(primary_censored_cdf,default) -S3method(primary_censored_cdf,pcens_pgamma_dunif) -S3method(primary_censored_cdf,pcens_plnorm_dunif) -S3method(primary_censored_cdf,pcens_pweibull_dunif) +S3method(primarycensored_cdf,default) +S3method(primarycensored_cdf,pcens_pgamma_dunif) +S3method(primarycensored_cdf,pcens_plnorm_dunif) +S3method(primarycensored_cdf,pcens_pweibull_dunif) export(check_dprimary) export(check_pdist) export(check_truncation) export(dexpgrowth) export(dpcens) -export(dprimarycensoreddist) +export(dprimarycensored) export(fitdistdoublecens) -export(new_primary_censored_dist) +export(new_primarycensored) export(pcd_as_stan_data) export(pcd_cmdstan_model) export(pcd_load_stan_functions) @@ -20,11 +20,11 @@ export(pcd_stan_functions) export(pcd_stan_path) export(pexpgrowth) export(ppcens) -export(pprimarycensoreddist) -export(primary_censored_cdf) +export(pprimarycensored) +export(primarycensored_cdf) export(rexpgrowth) export(rpcens) -export(rprimarycensoreddist) +export(rprimarycensored) importFrom(stats,dunif) importFrom(stats,runif) importFrom(stats,setNames) diff --git a/NEWS.md b/NEWS.md index 08e6fe0..e2749a4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ -# primarycensoreddist 0.5.0.1000 +# primarycensored 0.5.0.1000 -This is the development version of `primarycensoreddist` and is not yet ready for release. +This is the development version of `primarycensored` and is not yet ready for release. ## Package @@ -9,6 +9,7 @@ This is the development version of `primarycensoreddist` and is not yet ready fo * `pcd_as_cmdstan_data()` has been renamed to `pcd_as_stan_data()` to better reflect that it is used for `Stan` models in general rather than just the `CmdStan` models. * The stan code has been refactored into a folder of functions within the current `stan` folder and the `stan` model has been moved into the `stan` folder. All paths to the stan code have been updated to reflect this. * Added R and stan implementations of the primary censored cdf for the weibull distribution with uniform primary censoring. +* The package has been renamed to `primarycensored` as have all functions that use "dist" in their name. ## Documentation @@ -18,7 +19,7 @@ This is the development version of `primarycensoreddist` and is not yet ready fo * Fixed error in "Analytic solutions" vignette where the Weibull density was not being treated as zero for negative delays. * Split "Why it works" vignette into two separate vignettes, "Why it works" and "Analytic solutions for censored delay distributions". -# primarycensoreddist 0.5.0 +# primarycensored 0.5.0 This release adds a new `{touchstone}` based benchmark suite to the package. It also adds a new "How it works" vignette which aims to give the reader more details into how the primary censored distributions work. @@ -28,41 +29,41 @@ As part of the "How it works" we (@SamuelBrand1) found analytical solutions for * Add `{touchstone}` based benchmarks for benchmarking R utility functions, and fitting the `stan` and `fitdistplus` models. * Added a "How it works" vignette. -* Added R infrastructure for analytical solutions via the `primary_censored_dist` S3 class. +* Added R infrastructure for analytical solutions via the `primarycensored` S3 class. * Added Weibull analytical solution to "How it works" vignette. * Added analytical solutions for the gamma and lognormal distributions with uniform primary censoring to both the `R` and `stan` code. * Added numerical protection to ensure that CDFs for delays greater than the maximum truncation are exactly 1. -# primarycensoreddist 0.4.0 +# primarycensored 0.4.0 -In this release, we have added a new package `stan` model for fitting distributions using the `cmdstanr` package. We have also added a new function `fitdistdoublecens()` to allow for fitting of double censored and truncated data using the `fitdistrplus` package. As well as these functionality improvements this release focuses on improving the stability of the `stan` model and improving the speed of the `primary_censored_ode` function. +In this release, we have added a new package `stan` model for fitting distributions using the `cmdstanr` package. We have also added a new function `fitdistdoublecens()` to allow for fitting of double censored and truncated data using the `fitdistrplus` package. As well as these functionality improvements this release focuses on improving the stability of the `stan` model and improving the speed of the `primarycensored_ode` function. ## Package * Added a new function `fitdistdoublecens()` to allow for fitting of double censored and truncated data using the `fitdistrplus` package. -* Added low level tests for the Stan `primary_censored_ode` function. +* Added low level tests for the Stan `primarycensored_ode` function. * Rephrased the stan code to use a ODE solver rather than a numerical integration method. This allows for much faster and more stable computation of the likelihood * Added a `CmdStan` model for fitting distributions using the `cmdstanr` package. * Added helpers functions for working with the new `CmdStan` model and added an example to the vignette. -* Added parameter recovery tests for the new `CmdStan` model which tests the `primary_censored_dist_lpmf` function when used with NUTS based fitting. +* Added parameter recovery tests for the new `CmdStan` model which tests the `primarycensored_lpmf` function when used with NUTS based fitting. -# primarycensoreddist 0.3.0 +# primarycensored 0.3.0 -This release fixes and improves truncation handling across the code base. It also adds a new vignette showcasing how to use the `primarycensoreddist` and `fitdistrplus` packages together to fit distributions. +This release fixes and improves truncation handling across the code base. It also adds a new vignette showcasing how to use the `primarycensored` and `fitdistrplus` packages together to fit distributions. ## Package * Updated the approach to truncation to be outside the primary censored distribution integral. * Improved tests that compare random sampling and probability mass/density functions between R and Stan. * Improved cross-testing between R and Stan implementations of the primary censored distributions. -* Worked on improving the stability of the `primary_censored_dist_lpmf` when used for NUTS based fitting (i.e. in Stan). +* Worked on improving the stability of the `primarycensored_lpmf` when used for NUTS based fitting (i.e. in Stan). ## Documentation * @athowes improved the getting started vignette by catching a few grammar errors and simplifying language. -* Added a new vignette showcasing how to use the `primarycensoreddist` and `fitdistrplus` packages together to fit distributions. +* Added a new vignette showcasing how to use the `primarycensored` and `fitdistrplus` packages together to fit distributions. -# primarycensoreddist 0.2.0 +# primarycensored 0.2.0 This release puts in place initial documentation and vignettes. It also includes a new primary censored distribution interface to allow for non-secondary event censored distributions. Development of this release as identified some numerical issues in the gradient evaluations for the primary censored distributions which may lead to breaking @@ -70,8 +71,8 @@ interface changes in `0.3.0` for the Stan code. ## Package -* Added support for `swindow = 0` to `rprimarycensoreddist` to allow for non-secondary event censored distributions. -* Adapted `rprimarycensoreddist` so that truncation is based on the primary censored distribution before secondary events are censored. This better matches the generative process. +* Added support for `swindow = 0` to `rprimarycensored` to allow for non-secondary event censored distributions. +* Adapted `rprimarycensored` so that truncation is based on the primary censored distribution before secondary events are censored. This better matches the generative process. * Added a new Stan interface tool to enable finding which files functions are implemented in the Stan code. ## Documentation @@ -80,9 +81,9 @@ interface changes in `0.3.0` for the Stan code. * Added a vignette showcasing how to use the package Stan code with `cmdstanr`. * Added a vignette showcasing how to fit distributions using the `cmdstanr` package. -# primarycensoreddist 0.1.0 +# primarycensored 0.1.0 -This is the initial `primarycensoreddist` release and includes R and stan tools for dealing with potentially truncated primary event censored delay distributions. We expect all current features to work but the UI may change as the package matures over the next few versions. +This is the initial `primarycensored` release and includes R and stan tools for dealing with potentially truncated primary event censored delay distributions. We expect all current features to work but the UI may change as the package matures over the next few versions. ## Package diff --git a/R/check.R b/R/check.R index 7ee5b69..0be55d2 100644 --- a/R/check.R +++ b/R/check.R @@ -3,7 +3,7 @@ #' This function tests whether a given function behaves like a valid CDF by #' checking if it's monotonically increasing and bounded between 0 and 1. #' -#' @inheritParams pprimarycensoreddist +#' @inheritParams pprimarycensored #' @return NULL. The function will stop execution with an error message if #' pdist is not a valid CDF. #' @export @@ -40,7 +40,7 @@ check_pdist <- function(pdist, D, ...) { #' checking if it integrates to approximately 1 over the specified range #' and if it takes the arguments min and max. #' -#' @inheritParams pprimarycensoreddist +#' @inheritParams pprimarycensored #' @param tolerance The tolerance for the integral to be considered close to 1 #' #' @return NULL. The function will stop execution with an error message if diff --git a/R/dprimarycensoreddist.R b/R/dprimarycensored.R similarity index 91% rename from R/dprimarycensoreddist.R rename to R/dprimarycensored.R index 71a2bb4..9f32778 100644 --- a/R/dprimarycensoreddist.R +++ b/R/dprimarycensored.R @@ -7,7 +7,7 @@ #' truncation at a maximum delay (D). The function allows for custom primary #' event distributions and delay distributions. #' -#' @inheritParams pprimarycensoreddist +#' @inheritParams pprimarycensored #' #' @param x Vector of quantiles #' @@ -37,7 +37,7 @@ #' where \eqn{F_{\text{cens}}} is the primary event censored CDF. #' #' The function first computes the CDFs for all unique points (including both -#' \eqn{d} and \eqn{d + \text{swindow}}) using [pprimarycensoreddist()]. It then +#' \eqn{d} and \eqn{d + \text{swindow}}) using [pprimarycensored()]. It then #' creates a lookup table for these CDFs to efficiently calculate the PMF for #' each input value. For non-positive delays, the function returns 0. #' @@ -51,23 +51,23 @@ #' where \eqn{f_{\text{cens,norm}}(d)} is the normalized PMF and #' \eqn{f_{\text{cens}}(d)} is the unnormalized PMF. For the explanation and #' mathematical details of the CDF, refer to the documentation of -#' [pprimarycensoreddist()]. +#' [pprimarycensored()]. #' -#' @family primarycensoreddist +#' @family rpd_primarycensored #' #' @importFrom stats setNames #' #' @examples #' # Example: Weibull distribution with uniform primary events -#' dprimarycensoreddist(c(0.1, 0.5, 1), pweibull, shape = 1.5, scale = 2.0) +#' dprimarycensored(c(0.1, 0.5, 1), pweibull, shape = 1.5, scale = 2.0) #' #' # Example: Weibull distribution with exponential growth primary events -#' dprimarycensoreddist( +#' dprimarycensored( #' c(0.1, 0.5, 1), pweibull, #' dprimary = dexpgrowth, #' dprimary_args = list(r = 0.2), shape = 1.5, scale = 2.0 #' ) -dprimarycensoreddist <- function( +dprimarycensored <- function( x, pdist, pwindow = 1, swindow = 1, D = Inf, dprimary = stats::dunif, dprimary_args = list(), log = FALSE, @@ -97,7 +97,7 @@ dprimarycensoreddist <- function( return(rep(0, length(x))) } - cdfs <- pprimarycensoreddist( + cdfs <- pprimarycensored( unique_points, pdist, pwindow, Inf, dprimary, dprimary_args, pdist_name = pdist_name, dprimary_name = dprimary_name, ... ) @@ -123,7 +123,7 @@ dprimarycensoreddist <- function( if (max(unique_points) == D) { cdf_D <- max(cdfs) } else { - cdf_D <- pprimarycensoreddist( + cdf_D <- pprimarycensored( D, pdist, pwindow, Inf, dprimary, dprimary_args, ... ) } @@ -137,6 +137,6 @@ dprimarycensoreddist <- function( } } -#' @rdname dprimarycensoreddist +#' @rdname dprimarycensored #' @export -dpcens <- dprimarycensoreddist +dpcens <- dprimarycensored diff --git a/R/fitdistdoublecens.R b/R/fitdistdoublecens.R index b1fa01e..8fc78ef 100644 --- a/R/fitdistdoublecens.R +++ b/R/fitdistdoublecens.R @@ -1,7 +1,7 @@ #' Fit a distribution to doubly censored data #' #' This function wraps the custom approach for fitting distributions to doubly -#' censored data using fitdistrplus and primarycensoreddist. +#' censored data using fitdistrplus and primarycensored. #' #' @details #' This function temporarily assigns and then removes functions from the global @@ -16,7 +16,7 @@ #' #' @param distr A character string naming the distribution to be fitted. #' -#' @inheritParams pprimarycensoreddist +#' @inheritParams pprimarycensored #' #' @param ... Additional arguments to be passed to [fitdistrplus::fitdist()]. #' @@ -37,7 +37,7 @@ #' pwindow <- 2 #' swindow <- 2 #' D <- 10 -#' samples <- rprimarycensoreddist( +#' samples <- rprimarycensored( #' n, rnorm, #' mean = true_mean, sd = true_sd, #' pwindow = pwindow, swindow = swindow, D = D @@ -143,8 +143,8 @@ fitdistdoublecens <- function(censdata, distr, return(fit) } -#' Define a fitdistrplus compatible wrapper around dprimarycensoreddist -#' @inheritParams dprimarycensoreddist +#' Define a fitdistrplus compatible wrapper around dprimarycensored +#' @inheritParams dprimarycensored #' #' @param swindows A numeric vector of secondary window sizes corresponding to #' each element in x @@ -154,7 +154,7 @@ fitdistdoublecens <- function(censdata, distr, tryCatch( { if (length(unique(swindows)) == 1) { - dprimarycensoreddist( + dprimarycensored( x, pdist, pwindow = pwindow, swindow = swindows[1], D = D, dprimary = dprimary, dprimary_args = dprimary_args, pdist_name = pdist_name, @@ -167,7 +167,7 @@ fitdistdoublecens <- function(censdata, distr, for (sw in unique_swindows) { mask <- swindows == sw - result[mask] <- dprimarycensoreddist( + result[mask] <- dprimarycensored( x[mask], pdist, pwindow = pwindow, swindow = sw, D = D, dprimary = dprimary, dprimary_args = dprimary_args, @@ -184,14 +184,14 @@ fitdistdoublecens <- function(censdata, distr, ) } -#' Define a fitdistrplus compatible wrapper around pprimarycensoreddist -#' @inheritParams pprimarycensoreddist +#' Define a fitdistrplus compatible wrapper around pprimarycensored +#' @inheritParams pprimarycensored #' @keywords internal .ppcens <- function(q, pdist, pwindow, D, dprimary, dprimary_args, pdist_name, dprimary_name, ...) { tryCatch( { - pprimarycensoreddist( + pprimarycensored( q, pdist, pwindow = pwindow, D = D, dprimary = dprimary, dprimary_args = dprimary_args, diff --git a/R/pcd-stan-tools.R b/R/pcd-stan-tools.R index 97b39c2..dac46b2 100644 --- a/R/pcd-stan-tools.R +++ b/R/pcd-stan-tools.R @@ -6,7 +6,7 @@ #' #' @export pcd_stan_path <- function() { - system.file("stan", "functions", package = "primarycensoreddist") + system.file("stan", "functions", package = "primarycensored") } #' Count the number of unmatched braces in a line @@ -84,7 +84,7 @@ pcd_stan_path <- function() { #' the names of all functions defined in those files. #' #' @param stan_path Character string specifying the path to the directory -#' containing Stan files. Defaults to the Stan path of the primarycensoreddist +#' containing Stan files. Defaults to the Stan path of the primarycensored #' package. #' #' @return A character vector containing unique names of all functions found in @@ -94,7 +94,7 @@ pcd_stan_path <- function() { #' #' @family stantools pcd_stan_functions <- function( - stan_path = primarycensoreddist::pcd_stan_path()) { + stan_path = primarycensored::pcd_stan_path()) { stan_files <- list.files( stan_path, pattern = "\\.stan$", full.names = TRUE, @@ -126,7 +126,7 @@ pcd_stan_functions <- function( #' @family stantools pcd_stan_files <- function( functions = NULL, - stan_path = primarycensoreddist::pcd_stan_path()) { + stan_path = primarycensored::pcd_stan_path()) { # List all Stan files in the directory all_files <- list.files( stan_path, @@ -164,7 +164,7 @@ pcd_stan_files <- function( #' functions. #' #' @param stan_path Character string, the path to the Stan code. Defaults to the -#' path to the Stan code in the primarycensoreddist package. +#' path to the Stan code in the primarycensored package. #' #' @param wrap_in_block Logical, whether to wrap the functions in a #' `functions{}` block. Default is FALSE. @@ -181,7 +181,7 @@ pcd_stan_files <- function( #' #' @export pcd_load_stan_functions <- function( - functions = NULL, stan_path = primarycensoreddist::pcd_stan_path(), + functions = NULL, stan_path = primarycensored::pcd_stan_path(), wrap_in_block = FALSE, write_to_file = FALSE, output_file = "pcd_functions.stan") { stan_files <- list.files( @@ -209,8 +209,8 @@ pcd_load_stan_functions <- function( # Add version comment version_comment <- paste( - "// Stan functions from primarycensoreddist version", - utils::packageVersion("primarycensoreddist") + "// Stan functions from primarycensored version", + utils::packageVersion("primarycensored") ) all_content <- c(version_comment, all_content) diff --git a/R/pcd_cmdstan_model.R b/R/pcd_cmdstan_model.R index 524f93f..040ddf1 100644 --- a/R/pcd_cmdstan_model.R +++ b/R/pcd_cmdstan_model.R @@ -1,7 +1,7 @@ -#' Create a CmdStanModel with primarycensoreddist Stan functions +#' Create a CmdStanModel with primarycensored Stan functions #' #' This function creates a CmdStanModel object using the Stan model and -#' functions from primarycensoreddist and optionally includes additional +#' functions from primarycensored and optionally includes additional #' user-specified Stan files. #' #' @param include_paths Character vector of paths to include for Stan @@ -30,7 +30,7 @@ #' fit <- model$sample(data = stan_data) #' } pcd_cmdstan_model <- function( - include_paths = primarycensoreddist::pcd_stan_path(), + include_paths = primarycensored::pcd_stan_path(), ...) { if (!requireNamespace("cmdstanr", quietly = TRUE)) { stop("Package 'cmdstanr' is required but not installed for this function.") @@ -38,7 +38,7 @@ pcd_cmdstan_model <- function( pcd_stan_model <- system.file( "stan", "pcens_model.stan", - package = "primarycensoreddist" + package = "primarycensored" ) cmdstanr::cmdstan_model( @@ -48,10 +48,10 @@ pcd_cmdstan_model <- function( ) } -#' Prepare data for primarycensoreddist Stan model +#' Prepare data for primarycensored Stan model #' #' This function takes in delay data and prepares it for use with the -#' primarycensoreddist Stan model. +#' primarycensored Stan model. #' #' @param data A data frame containing the delay data. #' @@ -74,7 +74,7 @@ pcd_cmdstan_model <- function( #' 13 = Chi-square, 14 = Dirichlet, 15 = Gumbel, 16 = Inverse Gamma, #' 17 = Logistic #' -#' @param primary_dist_id Integer identifying the primary distribution: +#' @param primray_id Integer identifying the primary distribution: #' 1 = Uniform, 2 = Exponential growth #' #' @param param_bounds A list with elements `lower` and `upper`, each a numeric @@ -116,7 +116,7 @@ pcd_cmdstan_model <- function( #' stan_data <- pcd_as_stan_data( #' data, #' dist_id = 1, -#' primary_dist_id = 1, +#' primray_id = 1, #' param_bounds = list(lower = c(0, 0), upper = c(10, 10)), #' primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), #' priors = list(location = c(1, 1), scale = c(1, 1)), @@ -127,7 +127,7 @@ pcd_as_stan_data <- function( data, delay = "delay", delay_upper = "delay_upper", n = "n", pwindow = "pwindow", relative_obs_time = "relative_obs_time", - dist_id, primary_dist_id, + dist_id, primray_id, param_bounds, primary_param_bounds, priors, primary_priors, compute_log_lik = FALSE, @@ -168,7 +168,7 @@ pcd_as_stan_data <- function( pwindow = data[[pwindow]], D = data[[relative_obs_time]], dist_id = dist_id, - primary_dist_id = primary_dist_id, + primray_id = primray_id, n_params = length(param_bounds$lower), n_primary_params = length(primary_param_bounds$lower), compute_log_lik = as.integer(compute_log_lik), diff --git a/R/pprimarycensoreddist.R b/R/pprimarycensored.R similarity index 86% rename from R/pprimarycensoreddist.R rename to R/pprimarycensored.R index 3ed45a9..c0f78c8 100644 --- a/R/pprimarycensoreddist.R +++ b/R/pprimarycensored.R @@ -73,9 +73,9 @@ #' } #' where \eqn{F_{\text{cens,norm}}(q)} is the normalized CDF. #' -#' This function creates a `primary_censored_dist` object using -#' [new_primary_censored_dist()] and then computes the primary event -#' censored CDF using [primary_censored_cdf()]. This abstraction allows +#' This function creates a `primarycensored` object using +#' [new_primarycensored()] and then computes the primary event +#' censored CDF using [primarycensored_cdf()]. This abstraction allows #' for automatic use of analytical solutions when available, while #' seamlessly falling back to numerical integration when necessary. #' @@ -84,20 +84,20 @@ #' `pdist_name` and `dprimary_name` must be used to override the default #' extraction of the function name. #' -#' @family primarycensoreddist -#' @seealso [new_primary_censored_dist()] and [primary_censored_cdf()] +#' @family rpd_primarycensored +#' @seealso [new_primarycensored()] and [primarycensored_cdf()] #' #' @examples #' # Example: Lognormal distribution with uniform primary events -#' pprimarycensoreddist(c(0.1, 0.5, 1), plnorm, meanlog = 0, sdlog = 1) +#' pprimarycensored(c(0.1, 0.5, 1), plnorm, meanlog = 0, sdlog = 1) #' #' # Example: Lognormal distribution with exponential growth primary events -#' pprimarycensoreddist( +#' pprimarycensored( #' c(0.1, 0.5, 1), plnorm, #' dprimary = dexpgrowth, #' dprimary_args = list(r = 0.2), meanlog = 0, sdlog = 1 #' ) -pprimarycensoreddist <- function( +pprimarycensored <- function( q, pdist, pwindow = 1, D = Inf, dprimary = stats::dunif, dprimary_args = list(), pdist_name = NULL, dprimary_name = NULL, ...) { check_pdist(pdist, D, ...) @@ -110,8 +110,8 @@ pprimarycensoreddist <- function( dprimary_name <- .extract_function_name(substitute(dprimary)) } - # Create a new primary_censored_dist object - pcens_obj <- new_primary_censored_dist( + # Create a new primarycensored object + pcens_obj <- new_primarycensored( pdist, dprimary, dprimary_args, @@ -121,14 +121,14 @@ pprimarycensoreddist <- function( ) # Compute the CDF using the S3 method - result <- primary_censored_cdf(pcens_obj, q, pwindow) + result <- primarycensored_cdf(pcens_obj, q, pwindow) if (!is.infinite(D)) { # Compute normalization factor for finite D normalizer <- if (max(q) == D) { result[length(result)] } else { - pprimarycensoreddist(D, pdist, pwindow, Inf, dprimary, dprimary_args, ...) + pprimarycensored(D, pdist, pwindow, Inf, dprimary, dprimary_args, ...) } result <- result / normalizer @@ -138,6 +138,6 @@ pprimarycensoreddist <- function( return(result) } -#' @rdname pprimarycensoreddist +#' @rdname pprimarycensored #' @export -ppcens <- pprimarycensoreddist +ppcens <- pprimarycensored diff --git a/R/primary_censored_dist.R b/R/primarycensored.R similarity index 86% rename from R/primary_censored_dist.R rename to R/primarycensored.R index b088895..afaf0e9 100644 --- a/R/primary_censored_dist.R +++ b/R/primarycensored.R @@ -1,13 +1,13 @@ #' S3 class for primary event censored distribution computation #' -#' @inheritParams pprimarycensoreddist +#' @inheritParams pprimarycensored #' -#' @return An object of class primary_censored_cdf +#' @return An object of class primarycensored_cdf #' -#' @family primary_censored_dist +#' @family primarycensored #' #' @export -new_primary_censored_dist <- function( +new_primarycensored <- function( pdist, dprimary, dprimary_args, pdist_name = NULL, dprimary_name = NULL, ...) { @@ -37,10 +37,10 @@ new_primary_censored_dist <- function( #' Compute primary event censored CDF #' -#' @inheritParams pprimarycensoreddist +#' @inheritParams pprimarycensored #' -#' @param object A `primary_censored_dist` object as created by -#' [new_primary_censored_dist()]. +#' @param object A `primarycensored` object as created by +#' [new_primarycensored()]. #' #' @param use_numeric Logical, if TRUE forces use of numeric integration #' even for distributions with analytical solutions. This is primarily @@ -49,12 +49,12 @@ new_primary_censored_dist <- function( #' #' @return Vector of primary event censored CDFs #' -#' @family primary_censored_dist +#' @family primarycensored #' #' @export -primary_censored_cdf <- function( +primarycensored_cdf <- function( object, q, pwindow, use_numeric = FALSE) { - UseMethod("primary_censored_cdf") + UseMethod("primarycensored_cdf") } #' Default method for computing primary event censored CDF @@ -63,22 +63,22 @@ primary_censored_cdf <- function( #' event distributions that don't have specific implementations. It uses #' the numeric integration method. #' -#' @inheritParams primary_censored_cdf -#' @inheritParams pprimarycensoreddist +#' @inheritParams primarycensored_cdf +#' @inheritParams pprimarycensored #' #' @details #' This method implements the numerical integration approach for computing #' the primary event censored CDF. It uses the same mathematical formulation -#' as described in the details section of [pprimarycensoreddist()], but +#' as described in the details section of [pprimarycensored()], but #' applies numerical integration instead of analytical solutions. #' -#' @seealso [pprimarycensoreddist()] for the mathematical details of the +#' @seealso [pprimarycensored()] for the mathematical details of the #' primary event censored CDF computation. #' -#' @family primary_censored_dist +#' @family primarycensored #' #' @export -primary_censored_cdf.default <- function( +primarycensored_cdf.default <- function( object, q, pwindow, use_numeric = FALSE) { result <- vapply(q, function(d) { if (d <= 0) { @@ -105,16 +105,16 @@ primary_censored_cdf.default <- function( #' Method for Gamma delay with uniform primary #' -#' @inheritParams primary_censored_cdf +#' @inheritParams primarycensored_cdf #' -#' @family primary_censored_dist +#' @family primarycensored #' #' @export -primary_censored_cdf.pcens_pgamma_dunif <- function( +primarycensored_cdf.pcens_pgamma_dunif <- function( object, q, pwindow, use_numeric = FALSE) { if (isTRUE(use_numeric)) { return( - primary_censored_cdf.default(object, q, pwindow, use_numeric) + primarycensored_cdf.default(object, q, pwindow, use_numeric) ) } # Extract Gamma distribution parameters @@ -178,16 +178,16 @@ primary_censored_cdf.pcens_pgamma_dunif <- function( #' Method for Log-Normal delay with uniform primary #' -#' @inheritParams primary_censored_cdf +#' @inheritParams primarycensored_cdf #' -#' @family primary_censored_dist +#' @family primarycensored #' #' @export -primary_censored_cdf.pcens_plnorm_dunif <- function( +primarycensored_cdf.pcens_plnorm_dunif <- function( object, q, pwindow, use_numeric = FALSE) { if (isTRUE(use_numeric)) { return( - primary_censored_cdf.default(object, q, pwindow, use_numeric) + primarycensored_cdf.default(object, q, pwindow, use_numeric) ) } @@ -250,22 +250,22 @@ primary_censored_cdf.pcens_plnorm_dunif <- function( #' Method for Weibull delay with uniform primary #' -#' @inheritParams primary_censored_cdf +#' @inheritParams primarycensored_cdf #' -#' @family primary_censored_dist +#' @family primarycensored #' #' @export -primary_censored_cdf.pcens_pweibull_dunif <- function( +primarycensored_cdf.pcens_pweibull_dunif <- function( object, q, pwindow, use_numeric = FALSE) { if (isTRUE(use_numeric)) { return( - primary_censored_cdf.default(object, q, pwindow, use_numeric) + primarycensored_cdf.default(object, q, pwindow, use_numeric) ) } if (pwindow > 3) { return( - primary_censored_cdf.default(object, q, pwindow, use_numeric) + primarycensored_cdf.default(object, q, pwindow, use_numeric) ) } diff --git a/R/rprimarycensoreddist.R b/R/rprimarycensored.R similarity index 87% rename from R/rprimarycensoreddist.R rename to R/rprimarycensored.R index 89f962a..7a94c8d 100644 --- a/R/rprimarycensoreddist.R +++ b/R/rprimarycensored.R @@ -6,7 +6,7 @@ #' function allows for custom primary event distributions and delay #' distributions. #' -#' @inheritParams dprimarycensoreddist +#' @inheritParams dprimarycensored #' #' @param rdist Function to generate random samples from the delay distribution #' for example [stats::rlnorm()] for lognormal distribution. @@ -63,22 +63,22 @@ #' The function oversamples to account for potential truncation and generates #' additional samples if needed to reach the desired number of valid samples. #' -#' @family primarycensoreddist +#' @family rpd_primarycensored #' #' @examples #' # Example: Lognormal distribution with uniform primary events -#' rprimarycensoreddist(10, rlnorm, meanlog = 0, sdlog = 1) +#' rprimarycensored(10, rlnorm, meanlog = 0, sdlog = 1) #' #' # Example: Lognormal distribution with exponential growth primary events -#' rprimarycensoreddist( +#' rprimarycensored( #' 10, rlnorm, #' rprimary = rexpgrowth, rprimary_args = list(r = 0.2), #' meanlog = 0, sdlog = 1 #' ) -rprimarycensoreddist <- function(n, rdist, pwindow = 1, swindow = 1, - D = Inf, rprimary = stats::runif, - rprimary_args = list(), - oversampling_factor = 1.2, ...) { +rprimarycensored <- function(n, rdist, pwindow = 1, swindow = 1, + D = Inf, rprimary = stats::runif, + rprimary_args = list(), + oversampling_factor = 1.2, ...) { # Generate more samples than needed to account for truncation n_generate <- ceiling(n * oversampling_factor) @@ -98,7 +98,7 @@ rprimarycensoreddist <- function(n, rdist, pwindow = 1, swindow = 1, # If we don't have enough samples, generate more while (length(valid_samples) < n) { - additional_samples <- rprimarycensoreddist( + additional_samples <- rprimarycensored( n - length(valid_samples), rdist, pwindow, swindow, D, rprimary, rprimary_args, ... ) @@ -118,6 +118,6 @@ rprimarycensoreddist <- function(n, rdist, pwindow = 1, swindow = 1, return(rounded_samples) } -#' @rdname rprimarycensoreddist +#' @rdname rprimarycensored #' @export -rpcens <- rprimarycensoreddist +rpcens <- rprimarycensored diff --git a/README.Rmd b/README.Rmd index 303f3ab..944b6c6 100644 --- a/README.Rmd +++ b/README.Rmd @@ -13,17 +13,17 @@ knitr::opts_chunk$set( message = FALSE, warning = FALSE ) ``` -# Primary Event Censored Distributions in R and Stan primarycensoreddist website +# Primary event censored distributions in R and Stan primarycensored website [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) -[![R-CMD-check](https://github.com/epinowcast/primarycensoreddist/workflows/R-CMD-check/badge.svg)](https://github.com/epinowcast/primarycensoreddist/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/epinowcast/primarycensoreddist/branch/main/graph/badge.svg)](https://app.codecov.io/gh/epinowcast/primarycensoreddist) +[![R-CMD-check](https://github.com/epinowcast/primarycensored/workflows/R-CMD-check/badge.svg)](https://github.com/epinowcast/primarycensored/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/epinowcast/primarycensored/branch/main/graph/badge.svg)](https://app.codecov.io/gh/epinowcast/primarycensored) -[![Universe](https://epinowcast.r-universe.dev/badges/primarycensoreddist)](https://epinowcast.r-universe.dev/primarycensoreddist) +[![Universe](https://epinowcast.r-universe.dev/badges/primarycensored)](https://epinowcast.r-universe.dev/primarycensored) [![MIT -license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/epinowcast/primarycensoreddist/blob/master/LICENSE.md/) -[![GitHub contributors](https://img.shields.io/github/contributors/epinowcast/primarycensoreddist)](https://github.com/epinowcast/primarycensoreddist/graphs/contributors) +license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/epinowcast/primarycensored/blob/master/LICENSE.md/) +[![GitHub contributors](https://img.shields.io/github/contributors/epinowcast/primarycensored)](https://github.com/epinowcast/primarycensored/graphs/contributors) [![DOI](https://zenodo.org/badge/845633278.svg)](https://zenodo.org/doi/10.5281/zenodo.13632838) @@ -31,14 +31,14 @@ license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/ ## Summary ```{r, results = "asis", echo=FALSE} -cat(gsub("\n[ ]+", " ", packageDescription("primarycensoreddist")$Description)) +cat(gsub("\n[ ]+", " ", packageDescription("primarycensored")$Description)) ``` ## Installation
Installing the package -```{r, child="vignettes/chunks/_readme-install-primarycensoreddist.Rmd"} +```{r, child="vignettes/chunks/_readme-install-primarycensored.Rmd"} ```
@@ -49,7 +49,7 @@ If you wish to use the Stan functions, you will need to install [CmdStan](https: `cmdstanr`_](https://mc-stan.org/cmdstanr/articles/cmdstanr.html) vignette, with other details and support at the [package site](https://mc-stan.org/cmdstanr/) along with some key instructions available in the [Stan resources package vignette](https://package.epinowcast.org/articles/stan-help.html#toolchain), but the brief version is: ```{r, eval = FALSE} -# if you not yet installed `primarycensoreddist`, or you installed it without +# if you not yet installed `primarycensored`, or you installed it without # `Suggests` dependencies install.packages( "cmdstanr", @@ -69,13 +69,13 @@ We provide a range of other documentation, case studies, and community spaces to
Package Website -The [`primarycensoreddist` website](https://primarycensoreddist.epinowcast.org/) includes a function reference, model outline, and case studies using the package. The site mainly concerns the release version, but you can also find documentation for [the latest development version](https://primarycensoreddist.epinowcast.org/dev/). +The [`primarycensored` website](https://primarycensored.epinowcast.org/) includes a function reference, model outline, and case studies using the package. The site mainly concerns the release version, but you can also find documentation for [the latest development version](https://primarycensored.epinowcast.org/dev/).
Vignettes -We have created [package vignettes](https://primarycensoreddist.epinowcast.org/articles) to help you get started with primarycensoreddist and to highlight other features with case studies. +We have created [package vignettes](https://primarycensored.epinowcast.org/articles) to help you get started with primarycensored and to highlight other features with case studies.
@@ -87,27 +87,27 @@ Our [organisation website](https://www.epinowcast.org/) includes links to other
Community Forum -Our [community forum](https://community.epinowcast.org/) has areas for [question and answer](https://community.epinowcast.org/c/interface/15) and [considering new methods and tools](https://community.epinowcast.org/c/projects/11), among others. If you are generally interested in real-time analysis of infectious disease, you may find this useful even if you do not use `primarycensoreddist`. +Our [community forum](https://community.epinowcast.org/) has areas for [question and answer](https://community.epinowcast.org/c/interface/15) and [considering new methods and tools](https://community.epinowcast.org/c/projects/11), among others. If you are generally interested in real-time analysis of infectious disease, you may find this useful even if you do not use `primarycensored`.
## Contributing -We welcome contributions and new contributors! We particularly appreciate help on [identifying and identified issues](https://github.com/epinowcast/primarycensoreddist/issues). Please check and add to the issues, and/or add a [pull request](https://github.com/epinowcast/primarycensoreddist/pulls) and see our [contributing guide](https://github.com/epinowcast/.github/blob/main/CONTRIBUTING.md) for more information. +We welcome contributions and new contributors! We particularly appreciate help on [identifying and identified issues](https://github.com/epinowcast/primarycensored/issues). Please check and add to the issues, and/or add a [pull request](https://github.com/epinowcast/primarycensored/pulls) and see our [contributing guide](https://github.com/epinowcast/.github/blob/main/CONTRIBUTING.md) for more information. -If you need a different underlying model for your work: `primarycensoreddist` provides a flexible framework for censored distributions in both R and Stan. If you implement new distributions or censoring mechanisms that expand the overall flexibility or improve the defaults, please let us know either here or on the [community forum](https://community.epinowcast.org/). We always like to hear about new use-cases and extensions to the package. +If you need a different underlying model for your work: `primarycensored` provides a flexible framework for censored distributions in both R and Stan. If you implement new distributions or censoring mechanisms that expand the overall flexibility or improve the defaults, please let us know either here or on the [community forum](https://community.epinowcast.org/). We always like to hear about new use-cases and extensions to the package. ### How to make a bug report or feature request -Please briefly describe your problem and what output you expect in an [issue](https://github.com/epinowcast/primarycensoreddist/issues). If you have a question, please don't open an issue. Instead, ask on our [Q and A page](https://github.com/epinowcast/primarycensoreddist/discussions/categories/q-a). See our [contributing guide](https://github.com/epinowcast/.github/blob/main/CONTRIBUTING.md) for more information. +Please briefly describe your problem and what output you expect in an [issue](https://github.com/epinowcast/primarycensored/issues). If you have a question, please don't open an issue. Instead, ask on our [Q and A page](https://github.com/epinowcast/primarycensored/discussions/categories/q-a). See our [contributing guide](https://github.com/epinowcast/.github/blob/main/CONTRIBUTING.md) for more information. ### Code of Conduct -Please note that the `primarycensoreddist` project is released with a [Contributor Code of Conduct](https://github.com/epinowcast/.github/blob/main/CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms. +Please note that the `primarycensored` project is released with a [Contributor Code of Conduct](https://github.com/epinowcast/.github/blob/main/CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms. ## Citation -If making use of our methodology or the methodology on which ours is based, please cite the relevant papers from our [methods outline](https://primarycensoreddist.epinowcast.org/articles/primarycensoreddist.html). If you use `primarycensoreddist` in your work, please consider citing it with `citation("primarycensoreddist")`. +If making use of our methodology or the methodology on which ours is based, please cite the relevant papers from our [methods outline](https://primarycensored.epinowcast.org/articles/primarycensored.html). If you use `primarycensored` in your work, please consider citing it with `citation("primarycensored")`. ## Contributors @@ -130,31 +130,27 @@ All contributions to this project are gratefully acknowledged using the [`allcon ### Code -seabbs, -SamuelBrand1, -athowes, -sbfnk +seabbs, +SamuelBrand1, +athowes, +sbfnk ### Issue Authors -zsusswein, -jcblemai +zsusswein, +jcblemai ### Issue Contributors -parksw3 +parksw3 - - - - diff --git a/README.md b/README.md index e244ed8..e1ed199 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ -# Primary Event Censored Distributions in R and Stan primarycensoreddist website +# Primary Event Censored Distributions in R and Stan primarycensored website [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) -[![R-CMD-check](https://github.com/epinowcast/primarycensoreddist/workflows/R-CMD-check/badge.svg)](https://github.com/epinowcast/primarycensoreddist/actions/workflows/R-CMD-check.yaml) +[![R-CMD-check](https://github.com/epinowcast/primarycensored/workflows/R-CMD-check/badge.svg)](https://github.com/epinowcast/primarycensored/actions/workflows/R-CMD-check.yaml) [![Codecov test -coverage](https://codecov.io/gh/epinowcast/primarycensoreddist/branch/main/graph/badge.svg)](https://app.codecov.io/gh/epinowcast/primarycensoreddist) +coverage](https://codecov.io/gh/epinowcast/primarycensored/branch/main/graph/badge.svg)](https://app.codecov.io/gh/epinowcast/primarycensored) -[![Universe](https://epinowcast.r-universe.dev/badges/primarycensoreddist)](https://epinowcast.r-universe.dev/primarycensoreddist) +[![Universe](https://epinowcast.r-universe.dev/badges/primarycensored)](https://epinowcast.r-universe.dev/primarycensored) [![MIT -license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/epinowcast/primarycensoreddist/blob/master/LICENSE.md/) +license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/epinowcast/primarycensored/blob/master/LICENSE.md/) [![GitHub -contributors](https://img.shields.io/github/contributors/epinowcast/primarycensoreddist)](https://github.com/epinowcast/primarycensoreddist/graphs/contributors) +contributors](https://img.shields.io/github/contributors/epinowcast/primarycensored)](https://github.com/epinowcast/primarycensored/graphs/contributors) [![DOI](https://zenodo.org/badge/845633278.svg)](https://zenodo.org/doi/10.5281/zenodo.13632838) @@ -42,7 +42,7 @@ function, though you need to point to `r-universe` instead of CRAN: ``` r install.packages( - "primarycensoreddist", + "primarycensored", repos = "https://epinowcast.r-universe.dev" ) ``` @@ -54,18 +54,18 @@ bugs): ``` r remotes::install_github( - "epinowcast/primarycensoreddist", + "epinowcast/primarycensored", dependencies = TRUE ) ``` Similarly, you can install historical versions by specifying the release tag (e.g. this installs -[`0.2.0`](https://github.com/epinowcast/primarycensoreddist/releases/tag/v0.2.0)): +[`0.2.0`](https://github.com/epinowcast/primarycensored/releases/tag/v0.2.0)): ``` r remotes::install_github( - "epinowcast/primarycensoreddist", + "epinowcast/primarycensored", dependencies = TRUE, ref = "v0.2.0" ) ``` @@ -93,7 +93,7 @@ vignette](https://package.epinowcast.org/articles/stan-help.html#toolchain), but the brief version is: ``` r -# if you not yet installed `primarycensoreddist`, or you installed it without +# if you not yet installed `primarycensored`, or you installed it without # `Suggests` dependencies install.packages( "cmdstanr", @@ -120,12 +120,12 @@ spaces to ask (and answer!) questions: Package Website -The [`primarycensoreddist` -website](https://primarycensoreddist.epinowcast.org/) includes a +The [`primarycensored` +website](https://primarycensored.epinowcast.org/) includes a function reference, model outline, and case studies using the package. The site mainly concerns the release version, but you can also find documentation for [the latest development -version](https://primarycensoreddist.epinowcast.org/dev/). +version](https://primarycensored.epinowcast.org/dev/).
@@ -134,8 +134,8 @@ Vignettes We have created [package -vignettes](https://primarycensoreddist.epinowcast.org/articles) to help -you get started with primarycensoreddist and to highlight other features +vignettes](https://primarycensored.epinowcast.org/articles) to help +you get started with primarycensored and to highlight other features with case studies.
@@ -161,7 +161,7 @@ and [considering new methods and tools](https://community.epinowcast.org/c/projects/11), among others. If you are generally interested in real-time analysis of infectious disease, you may find this useful even if you do not use -`primarycensoreddist`. +`primarycensored`. @@ -169,15 +169,15 @@ disease, you may find this useful even if you do not use We welcome contributions and new contributors! We particularly appreciate help on [identifying and identified -issues](https://github.com/epinowcast/primarycensoreddist/issues). +issues](https://github.com/epinowcast/primarycensored/issues). Please check and add to the issues, and/or add a [pull -request](https://github.com/epinowcast/primarycensoreddist/pulls) and +request](https://github.com/epinowcast/primarycensored/pulls) and see our [contributing guide](https://github.com/epinowcast/.github/blob/main/CONTRIBUTING.md) for more information. If you need a different underlying model for your work: -`primarycensoreddist` provides a flexible framework for censored +`primarycensored` provides a flexible framework for censored distributions in both R and Stan. If you implement new distributions or censoring mechanisms that expand the overall flexibility or improve the defaults, please let us know either here or on the [community @@ -187,17 +187,17 @@ new use-cases and extensions to the package. ### How to make a bug report or feature request Please briefly describe your problem and what output you expect in an -[issue](https://github.com/epinowcast/primarycensoreddist/issues). If +[issue](https://github.com/epinowcast/primarycensored/issues). If you have a question, please don’t open an issue. Instead, ask on our [Q and A -page](https://github.com/epinowcast/primarycensoreddist/discussions/categories/q-a). +page](https://github.com/epinowcast/primarycensored/discussions/categories/q-a). See our [contributing guide](https://github.com/epinowcast/.github/blob/main/CONTRIBUTING.md) for more information. ### Code of Conduct -Please note that the `primarycensoreddist` project is released with a +Please note that the `primarycensored` project is released with a [Contributor Code of Conduct](https://github.com/epinowcast/.github/blob/main/CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms. @@ -206,9 +206,9 @@ By contributing to this project, you agree to abide by its terms. If making use of our methodology or the methodology on which ours is based, please cite the relevant papers from our [methods -outline](https://primarycensoreddist.epinowcast.org/articles/primarycensoreddist.html). -If you use `primarycensoreddist` in your work, please consider citing it -with `citation("primarycensoreddist")`. +outline](https://primarycensored.epinowcast.org/articles/primarycensored.html). +If you use `primarycensored` in your work, please consider citing it +with `citation("primarycensored")`. ## Contributors @@ -224,19 +224,19 @@ Contributions of any kind are welcome! ### Code -seabbs, -SamuelBrand1, -athowes, -sbfnk +seabbs, +SamuelBrand1, +athowes, +sbfnk ### Issue Authors -zsusswein, -jcblemai +zsusswein, +jcblemai ### Issue Contributors -parksw3 +parksw3 diff --git a/_pkgdown.yml b/_pkgdown.yml index 3ff9c86..bfc0e58 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,4 +1,4 @@ -url: https://primarycensoreddist.epinowcast.org/ +url: https://primarycensored.epinowcast.org/ template: package: enwtheme math-rendering: mathjax @@ -17,11 +17,11 @@ navbar: - text: R reference href: reference/index.html - text: Stan reference - href: https://primarycensoreddist.epinowcast.org/stan/ + href: https://primarycensored.epinowcast.org/stan/ articles: text: Articles menu: - - text: How to use primarycensoreddist with Stan + - text: How to use primarycensored with Stan href: articles/using-stan-tools.html - text: Fitting distributions using primarycensorseddist and cmdstan href: articles/fitting-dists-with-stan.html @@ -40,7 +40,7 @@ reference: - title: Primary event censored distribution functions desc: Functions for generating, evaluating density, and computing cumulative probabilities of primary event censored distributions contents: - - has_concept("primarycensoreddist") + - has_concept("primarycensored") - title: Primary event distributions desc: Probability density and random generation functions for primary event distributions contents: @@ -48,7 +48,7 @@ reference: - title: Primary censored distribution class and methods desc: S3 class and methods for computing primary event censored distributions, focusing on the internal machinery used by the package. Unlike the primary event distributions section which deals with specific distribution functions, this section covers the general framework for handling censored distributions. contents: - - has_concept("primary_censored_dist") + - has_concept("primarycensored") - title: Distribution checking functions desc: Functions to validate cumulative distribution functions (CDFs) and probability density functions (PDFs) contents: diff --git a/codemeta.json b/codemeta.json index c1ecb13..de4e87a 100644 --- a/codemeta.json +++ b/codemeta.json @@ -1,12 +1,12 @@ { "@context": "https://doi.org/10.5063/schema/codemeta-2.0", "@type": "SoftwareSourceCode", - "identifier": "primarycensoreddist", + "identifier": "primarycensored", "description": "This package provides both R functions for working with primary event censored distributions and Stan implementations for use in Bayesian modeling. Primary event censored distributions are useful for modeling delayed reporting scenarios in epidemiology and other fields. It provides support for arbitrary delay distributions, a range of common primary distributions, and allows for truncation and secondary event censoring to be accounted for.", - "name": "primarycensoreddist: Primary Event Censored Distributions in R and Stan", - "relatedLink": "https://primarycensoreddist.epinowcast.org", - "codeRepository": "https://github.com/epinowcast/primarycensoreddist/", - "issueTracker": "https://github.com/epinowcast/primarycensoreddist/issues/", + "name": "primarycensored: Primary Event Censored Distributions in R and Stan", + "relatedLink": "https://primarycensored.epinowcast.org", + "codeRepository": "https://github.com/epinowcast/primarycensored/", + "issueTracker": "https://github.com/epinowcast/primarycensored/issues/", "license": "https://spdx.org/licenses/MIT", "version": "0.5.0.1000", "programmingLanguage": { @@ -226,15 +226,15 @@ "@id": "https://orcid.org/0000-0003-0645-5367" } ], - "name": "primarycensoreddist: Primary Event Censored Distributions in R and Stan", + "name": "primarycensored: Primary Event Censored Distributions in R and Stan", "identifier": "10.5281/zenodo.13632839", "@id": "https://doi.org/10.5281/zenodo.13632839", "sameAs": "https://doi.org/10.5281/zenodo.13632839" } ], - "releaseNotes": "https://github.com/epinowcast/primarycensoreddist/blob/master/NEWS.md", - "readme": "https://github.com/epinowcast/primarycensoreddist/blob/main/README.md", - "contIntegration": ["https://github.com/epinowcast/primarycensoreddist/actions/workflows/R-CMD-check.yaml", "https://app.codecov.io/gh/epinowcast/primarycensoreddist"], + "releaseNotes": "https://github.com/epinowcast/primarycensored/blob/master/NEWS.md", + "readme": "https://github.com/epinowcast/primarycensored/blob/main/README.md", + "contIntegration": ["https://github.com/epinowcast/primarycensored/actions/workflows/R-CMD-check.yaml", "https://app.codecov.io/gh/epinowcast/primarycensored"], "developmentStatus": "https://www.tidyverse.org/lifecycle/#experimental", "keywords": ["censoring", "distributions", "truncation"] } diff --git a/inst/WORDLIST b/inst/WORDLIST index 7e8240c..d712560 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -27,7 +27,7 @@ discretising dist dp dprimary -dprimarycensoreddist +dprimarycensored dx dy dz @@ -58,7 +58,7 @@ parksw partexp pcd pdist -pprimarycensoreddist +pprimarycensored primarycensorseddist primaryeventdistributions propto diff --git a/inst/make_hexsticker.R b/inst/make_hexsticker.R index 1227b92..1384438 100644 --- a/inst/make_hexsticker.R +++ b/inst/make_hexsticker.R @@ -37,8 +37,8 @@ data <- data[data$id != 5, ] # Create the plot plot <- ggplot(data, aes(y = id)) + # Add linking bar between primary and secondary events (behind other elements) - geom_segment(data = subset(data, !crosses_observation), aes(x = primary, xend = secondary, yend = id), size = 0.6, color = "#708090") + - geom_segment(data = subset(data, crosses_observation), aes(x = primary, xend = secondary, yend = id), size = 0.6, color = "#708090", linetype = "dotted") + + geom_segment(data = subset(data, !crosses_observation), aes(x = primary, xend = secondary, yend = id), linewidth = 0.6, color = "#708090") + + geom_segment(data = subset(data, crosses_observation), aes(x = primary, xend = secondary, yend = id), linewidth = 0.6, color = "#708090", linetype = "dotted") + # Add primary events geom_point(aes(x = primary), color = "#4682B4", size = 1) + # Add secondary events @@ -62,7 +62,7 @@ plot <- ggplot(data, aes(y = id)) + # make and save hexsticker sticker( plot, - package = "primarycensoreddist", + package = "primarycensored", p_size = 12, p_color = "#4682B4", s_x = 1, diff --git a/inst/stan/functions/primary_censored_dist.stan b/inst/stan/functions/primarycensored.stan similarity index 50% rename from inst/stan/functions/primary_censored_dist.stan rename to inst/stan/functions/primarycensored.stan index bb7d3e0..32cb2d0 100644 --- a/inst/stan/functions/primary_censored_dist.stan +++ b/inst/stan/functions/primarycensored.stan @@ -2,118 +2,6 @@ * Primary event censored distribution functions */ -/** - * Compute the log CDF of the delay distribution - * - * @param delay Time delay - * @param params Distribution parameters - * @param dist_id Distribution identifier - * 1: Lognormal, 2: Gamma, 3: Normal, 4: Exponential, 5: Weibull, - * 6: Beta, 7: Cauchy, 8: Chi-square, 9: Inverse Chi-square, - * 10: Double Exponential, 11: Inverse Gamma, 12: Logistic, - * 13: Pareto, 14: Scaled Inverse Chi-square, 15: Student's t, - * 16: Uniform, 17: von Mises - * - * @return Log CDF of the delay distribution - * - * @code - * // Example: Lognormal distribution - * real delay = 5.0; - * array[2] real params = {0.0, 1.0}; // mean and standard deviation on log scale - * int dist_id = 1; // Lognormal - * real log_cdf = dist_lcdf(delay, params, dist_id); - * @endcode - */ -real dist_lcdf(real delay, array[] real params, int dist_id) { - if (delay <= 0) return negative_infinity(); - - // Use if-else statements to handle different distribution types - if (dist_id == 1) return lognormal_lcdf(delay | params[1], params[2]); - else if (dist_id == 2) return gamma_lcdf(delay | params[1], params[2]); - else if (dist_id == 3) return normal_lcdf(delay | params[1], params[2]); - else if (dist_id == 4) return exponential_lcdf(delay | params[1]); - else if (dist_id == 5) return weibull_lcdf(delay | params[1], params[2]); - else if (dist_id == 6) return beta_lcdf(delay | params[1], params[2]); - else if (dist_id == 7) return cauchy_lcdf(delay | params[1], params[2]); - else if (dist_id == 8) return chi_square_lcdf(delay | params[1]); - else if (dist_id == 9) return inv_chi_square_lcdf(delay | params[1]); - else if (dist_id == 10) return double_exponential_lcdf(delay | params[1], params[2]); - else if (dist_id == 11) return inv_gamma_lcdf(delay | params[1], params[2]); - else if (dist_id == 12) return logistic_lcdf(delay | params[1], params[2]); - else if (dist_id == 13) return pareto_lcdf(delay | params[1], params[2]); - else if (dist_id == 14) return scaled_inv_chi_square_lcdf(delay | params[1], params[2]); - else if (dist_id == 15) return student_t_lcdf(delay | params[1], params[2], params[3]); - else if (dist_id == 16) return uniform_lcdf(delay | params[1], params[2]); - else if (dist_id == 17) return von_mises_lcdf(delay | params[1], params[2]); - else reject("Invalid distribution identifier"); -} - -/** - * Compute the log PDF of the primary distribution - * - * @param x Value - * @param primary_dist_id Primary distribution identifier - * @param params Distribution parameters - * @param min Minimum value - * @param max Maximum value - * - * @return Log PDF of the primary distribution - * - * @code - * // Example: Uniform distribution - * real x = 0.5; - * int primary_dist_id = 1; // Uniform - * array[0] real params = {}; // No additional parameters for uniform - * real min = 0; - * real max = 1; - * real log_pdf = primary_dist_lpdf(x, primary_dist_id, params, min, max); - * @endcode - */ -real primary_dist_lpdf(real x, int primary_dist_id, array[] real params, real min, real max) { - // Implement switch for different primary distributions - if (primary_dist_id == 1) return uniform_lpdf(x | min, max); - if (primary_dist_id == 2) return expgrowth_lpdf(x | min, max, params[1]); - // Add more primary distributions as needed - reject("Invalid primary distribution identifier"); -} - -/** - * ODE system for the primary censored distribution - * - * @param t Time - * @param y State variables - * @param theta Parameters - * @param x_r Real data - * @param x_i Integer data - * - * @return Derivatives of the state variables - */ -vector primary_censored_ode(real t, vector y, array[] real theta, - array[] real x_r, array[] int x_i) { - real d = x_r[1]; - int dist_id = x_i[1]; - int primary_dist_id = x_i[2]; - real pwindow = x_r[2]; - int dist_params_len = x_i[3]; - int primary_params_len = x_i[4]; - - // Extract distribution parameters - array[dist_params_len] real params; - if (dist_params_len) { - params = theta[1:dist_params_len]; - } - array[primary_params_len] real primary_params; - if (primary_params_len) { - int primary_loc = size(theta); - primary_params = theta[primary_loc - primary_params_len + 1:primary_loc]; - } - - real log_cdf = dist_lcdf(t | params, dist_id); - real log_primary_pdf = primary_dist_lpdf(d - t | primary_dist_id, primary_params, 0, pwindow); - - return rep_vector(exp(log_cdf + log_primary_pdf), 1); -} - /** * Compute the primary event censored CDF for a single delay * @@ -122,14 +10,14 @@ vector primary_censored_ode(real t, vector y, array[] real theta, * @param params Array of distribution parameters * @param pwindow Primary event window * @param D Maximum delay (truncation point) - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Primary event censored CDF, normalized by D if finite (truncation adjustment) */ -real primary_censored_dist_cdf(data real d, int dist_id, array[] real params, +real primarycensored_cdf(data real d, int dist_id, array[] real params, data real pwindow, data real D, - int primary_dist_id, + int primray_id, array[] real primary_params) { real result; if (d <= 0) { @@ -141,23 +29,23 @@ real primary_censored_dist_cdf(data real d, int dist_id, array[] real params, } // Check if an analytical solution exists - if (check_for_analytical(dist_id, primary_dist_id)) { + if (check_for_analytical(dist_id, primray_id)) { // Use analytical solution - result = primary_censored_dist_analytical_cdf( - d | dist_id, params, pwindow, D, primary_dist_id, primary_params + result = primarycensored_analytical_cdf( + d | dist_id, params, pwindow, D, primray_id, primary_params ); } else { // Use numerical integration for other cases real lower_bound = max({d - pwindow, 1e-6}); array[size(params) + size(primary_params)] real theta = append_array(params, primary_params); - array[4] int ids = {dist_id, primary_dist_id, size(params), size(primary_params)}; + array[4] int ids = {dist_id, primray_id, size(params), size(primary_params)}; vector[1] y0 = rep_vector(0.0, 1); - result = ode_rk45(primary_censored_ode, y0, lower_bound, {d}, theta, {d, pwindow}, ids)[1, 1]; + result = ode_rk45(primarycensored_ode, y0, lower_bound, {d}, theta, {d, pwindow}, ids)[1, 1]; if (!is_inf(D)) { - real log_cdf_D = primary_censored_dist_lcdf( - D | dist_id, params, pwindow, positive_infinity(), primary_dist_id,primary_params + real log_cdf_D = primarycensored_lcdf( + D | dist_id, params, pwindow, positive_infinity(), primray_id,primary_params ); result = exp(log(result) - log_cdf_D); } @@ -174,7 +62,7 @@ real primary_censored_dist_cdf(data real d, int dist_id, array[] real params, * @param params Array of distribution parameters * @param pwindow Primary event window * @param D Maximum delay (truncation point) - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Primary event censored log CDF, normalized by D if finite (truncation adjustment) @@ -186,16 +74,16 @@ real primary_censored_dist_cdf(data real d, int dist_id, array[] real params, * array[2] real params = {2.0, 1.5}; // shape and scale * real pwindow = 1.0; * real D = positive_infinity(); - * int primary_dist_id = 1; // Uniform + * int primray_id = 1; // Uniform * array[0] real primary_params = {}; - * real log_cdf = primary_censored_dist_lcdf( - * d, dist_id, params, pwindow, D, primary_dist_id, primary_params + * real log_cdf = primarycensored_lcdf( + * d, dist_id, params, pwindow, D, primray_id, primary_params * ); * @endcode */ -real primary_censored_dist_lcdf(data real d, int dist_id, array[] real params, +real primarycensored_lcdf(data real d, int dist_id, array[] real params, data real pwindow, data real D, - int primary_dist_id, + int primray_id, array[] real primary_params) { real result; @@ -208,21 +96,21 @@ real primary_censored_dist_lcdf(data real d, int dist_id, array[] real params, } // Check if an analytical solution exists - if (check_for_analytical(dist_id, primary_dist_id)) { - result = primary_censored_dist_analytical_lcdf( - d | dist_id, params, pwindow, positive_infinity(), primary_dist_id, primary_params + if (check_for_analytical(dist_id, primray_id)) { + result = primarycensored_analytical_lcdf( + d | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params ); } else { // Use numerical integration - result = log(primary_censored_dist_cdf( - d | dist_id, params, pwindow, positive_infinity(), primary_dist_id, primary_params + result = log(primarycensored_cdf( + d | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params )); } // Handle truncation if (!is_inf(D)) { - real log_cdf_D = primary_censored_dist_lcdf( - D | dist_id, params, pwindow, positive_infinity(), primary_dist_id, primary_params + real log_cdf_D = primarycensored_lcdf( + D | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params ); result = result - log_cdf_D; } @@ -239,7 +127,7 @@ real primary_censored_dist_lcdf(data real d, int dist_id, array[] real params, * @param pwindow Primary event window * @param d_upper Upper bound for the delay interval * @param D Maximum delay (truncation point) - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Primary event censored log PMF, normalized by D if finite (truncation adjustment) @@ -252,16 +140,16 @@ real primary_censored_dist_lcdf(data real d, int dist_id, array[] real params, * real pwindow = 1.0; * real d_upper = 4.0; * real D = positive_infinity(); - * int primary_dist_id = 1; // Uniform + * int primray_id = 1; // Uniform * array[0] real primary_params = {}; - * real log_pmf = primary_censored_dist_lpmf( - * d, dist_id, params, pwindow, d_upper, D, primary_dist_id, primary_params + * real log_pmf = primarycensored_lpmf( + * d, dist_id, params, pwindow, d_upper, D, primray_id, primary_params * ); * @endcode */ -real primary_censored_dist_lpmf(data int d, int dist_id, array[] real params, +real primarycensored_lpmf(data int d, int dist_id, array[] real params, data real pwindow, data real d_upper, - data real D, int primary_dist_id, + data real D, int primray_id, array[] real primary_params) { if (d_upper > D) { reject("Upper truncation point is greater than D. It is ", d_upper, @@ -271,11 +159,11 @@ real primary_censored_dist_lpmf(data int d, int dist_id, array[] real params, reject("Upper truncation point is less than or equal to d. It is ", d_upper, " and d is ", d, ". Resolve this by increasing d to be less than d_upper."); } - real log_cdf_upper = primary_censored_dist_lcdf( - d_upper | dist_id, params, pwindow, positive_infinity(), primary_dist_id, primary_params + real log_cdf_upper = primarycensored_lcdf( + d_upper | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params ); - real log_cdf_lower = primary_censored_dist_lcdf( - d | dist_id, params, pwindow, positive_infinity(), primary_dist_id, primary_params + real log_cdf_lower = primarycensored_lcdf( + d | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params ); if (!is_inf(D)) { real log_cdf_D; @@ -283,8 +171,8 @@ real primary_censored_dist_lpmf(data int d, int dist_id, array[] real params, if (d_upper == D) { log_cdf_D = log_cdf_upper; } else { - log_cdf_D = primary_censored_dist_lcdf( - D | dist_id, params, pwindow, positive_infinity(), primary_dist_id, primary_params + log_cdf_D = primarycensored_lcdf( + D | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params ); } return log_diff_exp(log_cdf_upper, log_cdf_lower) - log_cdf_D; @@ -302,7 +190,7 @@ real primary_censored_dist_lpmf(data int d, int dist_id, array[] real params, * @param pwindow Primary event window * @param d_upper Upper bound for the delay interval * @param D Maximum delay (truncation point) - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Primary event censored PMF, normalized by D if finite (truncation adjustment) @@ -316,18 +204,18 @@ real primary_censored_dist_lpmf(data int d, int dist_id, array[] real params, * real pwindow = 1.0; * real swindow = 0.1; * real D = positive_infinity(); - * int primary_dist_id = 1; // Uniform + * int primray_id = 1; // Uniform * array[0] real primary_params = {}; - * real pmf = primary_censored_dist_pmf(d, dist_id, params, pwindow, swindow, D, primary_dist_id, primary_params); + * real pmf = primarycensored_pmf(d, dist_id, params, pwindow, swindow, D, primray_id, primary_params); * @endcode */ -real primary_censored_dist_pmf(data int d, int dist_id, array[] real params, +real primarycensored_pmf(data int d, int dist_id, array[] real params, data real pwindow, data real d_upper, - data real D, int primary_dist_id, + data real D, int primray_id, array[] real primary_params) { return exp( - primary_censored_dist_lpmf( - d | dist_id, params, pwindow, d_upper, D, primary_dist_id, primary_params + primarycensored_lpmf( + d | dist_id, params, pwindow, d_upper, D, primray_id, primary_params ) ); } @@ -340,13 +228,13 @@ real primary_censored_dist_pmf(data int d, int dist_id, array[] real params, * @param dist_id Distribution identifier * @param params Array of distribution parameters * @param pwindow Primary event window - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Vector of primary event censored log PMFs for delays \[0, 1\] to * \[max_delay, max_delay + 1\]. * - * This function differs from primary_censored_dist_lpmf in that it: + * This function differs from primarycensored_lpmf in that it: * 1. Computes PMFs for all integer delays from \[0, 1\] to \[max_delay, * max_delay + 1\] in one call. * 2. Assumes integer delays (swindow = 1) @@ -360,20 +248,20 @@ real primary_censored_dist_pmf(data int d, int dist_id, array[] real params, * int dist_id = 5; // Weibull * array[2] real params = {2.0, 1.5}; // shape and scale * real pwindow = 7.0; - * int primary_dist_id = 1; // Uniform + * int primray_id = 1; // Uniform * array[0] real primary_params = {}; * vector[max_delay] log_pmf = - * primary_censored_sone_lpmf_vectorized( - * max_delay, D, dist_id, params, pwindow, primary_dist_id, + * primarycensored_sone_lpmf_vectorized( + * max_delay, D, dist_id, params, pwindow, primray_id, * primary_params * ); * @endcode */ -vector primary_censored_sone_lpmf_vectorized( +vector primarycensored_sone_lpmf_vectorized( int max_delay, data real D, int dist_id, array[] real params, data real pwindow, - int primary_dist_id, array[] real primary_params + int primray_id, array[] real primary_params ) { int upper_interval = max_delay + 1; @@ -388,8 +276,8 @@ vector primary_censored_sone_lpmf_vectorized( // Compute log CDFs for (d in 1:upper_interval) { - log_cdfs[d] = primary_censored_dist_lcdf( - d | dist_id, params, pwindow, positive_infinity(), primary_dist_id, + log_cdfs[d] = primarycensored_lcdf( + d | dist_id, params, pwindow, positive_infinity(), primray_id, primary_params ); } @@ -399,9 +287,9 @@ vector primary_censored_sone_lpmf_vectorized( if (is_inf(D)) { log_normalizer = 0; // No normalization needed for infinite D } else { - log_normalizer = primary_censored_dist_lcdf( + log_normalizer = primarycensored_lcdf( D | dist_id, params, pwindow, positive_infinity(), - primary_dist_id, primary_params + primray_id, primary_params ); } } else { @@ -425,13 +313,13 @@ vector primary_censored_sone_lpmf_vectorized( * @param dist_id Distribution identifier * @param params Array of distribution parameters * @param pwindow Primary event window - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Vector of primary event censored PMFs for integer delays 1 to * max_delay * - * This function differs from primary_censored_dist_pmf in that it: + * This function differs from primarycensored_pmf in that it: * 1. Computes PMFs for all integer delays from \[0, 1\] to \[max_delay, * max_delay + 1\] in one call. * 2. Assumes integer delays (swindow = 1) @@ -444,23 +332,23 @@ vector primary_censored_sone_lpmf_vectorized( * int dist_id = 5; // Weibull * array[2] real params = {2.0, 1.5}; // shape and scale * real pwindow = 7.0; - * int primary_dist_id = 1; // Uniform + * int primray_id = 1; // Uniform * array[0] real primary_params = {}; * vector[max_delay] pmf = - * primary_censored_sone_pmf_vectorized( - * max_delay, D, dist_id, params, pwindow, primary_dist_id, primary_params + * primarycensored_sone_lpmf_vectorized( + * max_delay, D, dist_id, params, pwindow, primray_id, primary_params * ); * @endcode */ -vector primary_censored_sone_pmf_vectorized( +vector primarycensored_sone_pmf_vectorized( int max_delay, data real D, int dist_id, array[] real params, data real pwindow, - int primary_dist_id, + int primray_id, array[] real primary_params ) { return exp( - primary_censored_sone_lpmf_vectorized( - max_delay, D, dist_id, params, pwindow, primary_dist_id, primary_params + primarycensored_sone_lpmf_vectorized( + max_delay, D, dist_id, params, pwindow, primray_id, primary_params ) ); } diff --git a/inst/stan/functions/primary_censored_dist_analytical_cdf.stan b/inst/stan/functions/primarycensored_analytical_cdf.stan similarity index 80% rename from inst/stan/functions/primary_censored_dist_analytical_cdf.stan rename to inst/stan/functions/primarycensored_analytical_cdf.stan index ae96298..83672b0 100644 --- a/inst/stan/functions/primary_censored_dist_analytical_cdf.stan +++ b/inst/stan/functions/primarycensored_analytical_cdf.stan @@ -3,14 +3,14 @@ * Check if an analytical solution exists for the given distribution combination * * @param dist_id Distribution identifier for the delay distribution - * @param primary_dist_id Distribution identifier for the primary distribution + * @param primray_id Distribution identifier for the primary distribution * * @return 1 if an analytical solution exists, 0 otherwise */ -int check_for_analytical(int dist_id, int primary_dist_id) { - if (dist_id == 2 && primary_dist_id == 1) return 1; // Gamma delay with Uniform primary - if (dist_id == 1 && primary_dist_id == 1) return 1; // Lognormal delay with Uniform primary - if (dist_id == 3 && primary_dist_id == 1) return 1; // Weibull delay with Uniform primary +int check_for_analytical(int dist_id, int primray_id) { + if (dist_id == 2 && primray_id == 1) return 1; // Gamma delay with Uniform primary + if (dist_id == 1 && primray_id == 1) return 1; // Lognormal delay with Uniform primary + if (dist_id == 3 && primray_id == 1) return 1; // Weibull delay with Uniform primary return 0; // No analytical solution for other combinations } @@ -25,7 +25,7 @@ int check_for_analytical(int dist_id, int primary_dist_id) { * @return Log of the primary event censored CDF for Gamma delay with Uniform * primary */ -real primary_censored_gamma_uniform_lcdf(data real d, real q, array[] real params, data real pwindow) { +real primarycensored_gamma_uniform_lcdf(data real d, real q, array[] real params, data real pwindow) { real shape = params[1]; real rate = params[2]; real shape_1 = shape + 1; @@ -80,7 +80,7 @@ real primary_censored_gamma_uniform_lcdf(data real d, real q, array[] real param * @return Log of the primary event censored CDF for Lognormal delay with * Uniform primary */ -real primary_censored_lognormal_uniform_lcdf(data real d, real q, array[] real params, data real pwindow) { +real primarycensored_lognormal_uniform_lcdf(data real d, real q, array[] real params, data real pwindow) { real mu = params[1]; real sigma = params[2]; real mu_sigma2 = mu + square(sigma); @@ -156,7 +156,7 @@ real log_weibull_g(real t, real shape, real scale) { * @return Log of the primary event censored CDF for Weibull delay with * Uniform primary */ -real primary_censored_weibull_uniform_lcdf(data real d, real q, array[] real params, data real pwindow) { +real primarycensored_weibull_uniform_lcdf(data real d, real q, array[] real params, data real pwindow) { real shape = params[1]; real scale = params[2]; real log_window = log(pwindow); @@ -207,15 +207,15 @@ real primary_censored_weibull_uniform_lcdf(data real d, real q, array[] real par * @param params Array of distribution parameters * @param pwindow Primary event window * @param D Maximum delay (truncation point) - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Primary event censored log CDF, normalized by D if finite (truncation adjustment) */ -real primary_censored_dist_analytical_lcdf(data real d, int dist_id, +real primarycensored_analytical_lcdf(data real d, int dist_id, array[] real params, data real pwindow, data real D, - int primary_dist_id, + int primray_id, array[] real primary_params) { real result; real log_cdf_D; @@ -225,24 +225,24 @@ real primary_censored_dist_analytical_lcdf(data real d, int dist_id, real q = max({d - pwindow, 0}); - if (dist_id == 2 && primary_dist_id == 1) { + if (dist_id == 2 && primray_id == 1) { // Gamma delay with Uniform primary - result = primary_censored_gamma_uniform_lcdf(d | q, params, pwindow); - } else if (dist_id == 1 && primary_dist_id == 1) { + result = primarycensored_gamma_uniform_lcdf(d | q, params, pwindow); + } else if (dist_id == 1 && primray_id == 1) { // Lognormal delay with Uniform primary - result = primary_censored_lognormal_uniform_lcdf(d | q, params, pwindow); - } else if (dist_id == 3 && primary_dist_id == 1) { + result = primarycensored_lognormal_uniform_lcdf(d | q, params, pwindow); + } else if (dist_id == 3 && primray_id == 1) { // Weibull delay with Uniform primary - result = primary_censored_weibull_uniform_lcdf(d | q, params, pwindow); + result = primarycensored_weibull_uniform_lcdf(d | q, params, pwindow); } else { // No analytical solution available return negative_infinity(); } if (!is_inf(D)) { - log_cdf_D = primary_censored_dist_lcdf( + log_cdf_D = primarycensored_lcdf( D | dist_id, params, pwindow, positive_infinity(), - primary_dist_id, primary_params + primray_id, primary_params ); result = result - log_cdf_D; } @@ -258,15 +258,15 @@ real primary_censored_dist_analytical_lcdf(data real d, int dist_id, * @param params Array of distribution parameters * @param pwindow Primary event window * @param D Maximum delay (truncation point) - * @param primary_dist_id Primary distribution identifier + * @param primray_id Primary distribution identifier * @param primary_params Primary distribution parameters * * @return Primary event censored CDF, normalized by D if finite (truncation adjustment) */ -real primary_censored_dist_analytical_cdf(data real d, int dist_id, +real primarycensored_analytical_cdf(data real d, int dist_id, array[] real params, data real pwindow, data real D, - int primary_dist_id, + int primray_id, array[] real primary_params) { - return exp(primary_censored_dist_analytical_lcdf(d | dist_id, params, pwindow, D, primary_dist_id, primary_params)); + return exp(primarycensored_analytical_lcdf(d | dist_id, params, pwindow, D, primray_id, primary_params)); } diff --git a/inst/stan/functions/primarycensored_ode.stan b/inst/stan/functions/primarycensored_ode.stan new file mode 100644 index 0000000..b40ddba --- /dev/null +++ b/inst/stan/functions/primarycensored_ode.stan @@ -0,0 +1,111 @@ +/** + * Compute the log CDF of the delay distribution + * + * @param delay Time delay + * @param params Distribution parameters + * @param dist_id Distribution identifier + * 1: Lognormal, 2: Gamma, 3: Normal, 4: Exponential, 5: Weibull, + * 6: Beta, 7: Cauchy, 8: Chi-square, 9: Inverse Chi-square, + * 10: Double Exponential, 11: Inverse Gamma, 12: Logistic, + * 13: Pareto, 14: Scaled Inverse Chi-square, 15: Student's t, + * 16: Uniform, 17: von Mises + * + * @return Log CDF of the delay distribution + * + * @code + * // Example: Lognormal distribution + * real delay = 5.0; + * array[2] real params = {0.0, 1.0}; // mean and standard deviation on log scale + * int dist_id = 1; // Lognormal + * real log_cdf = dist_lcdf(delay, params, dist_id); + * @endcode + */ +real dist_lcdf(real delay, array[] real params, int dist_id) { + if (delay <= 0) return negative_infinity(); + + // Use if-else statements to handle different distribution types + if (dist_id == 1) return lognormal_lcdf(delay | params[1], params[2]); + else if (dist_id == 2) return gamma_lcdf(delay | params[1], params[2]); + else if (dist_id == 3) return normal_lcdf(delay | params[1], params[2]); + else if (dist_id == 4) return exponential_lcdf(delay | params[1]); + else if (dist_id == 5) return weibull_lcdf(delay | params[1], params[2]); + else if (dist_id == 6) return beta_lcdf(delay | params[1], params[2]); + else if (dist_id == 7) return cauchy_lcdf(delay | params[1], params[2]); + else if (dist_id == 8) return chi_square_lcdf(delay | params[1]); + else if (dist_id == 9) return inv_chi_square_lcdf(delay | params[1]); + else if (dist_id == 10) return double_exponential_lcdf(delay | params[1], params[2]); + else if (dist_id == 11) return inv_gamma_lcdf(delay | params[1], params[2]); + else if (dist_id == 12) return logistic_lcdf(delay | params[1], params[2]); + else if (dist_id == 13) return pareto_lcdf(delay | params[1], params[2]); + else if (dist_id == 14) return scaled_inv_chi_square_lcdf(delay | params[1], params[2]); + else if (dist_id == 15) return student_t_lcdf(delay | params[1], params[2], params[3]); + else if (dist_id == 16) return uniform_lcdf(delay | params[1], params[2]); + else if (dist_id == 17) return von_mises_lcdf(delay | params[1], params[2]); + else reject("Invalid distribution identifier"); +} + +/** + * Compute the log PDF of the primary distribution + * + * @param x Value + * @param primray_id Primary distribution identifier + * @param params Distribution parameters + * @param min Minimum value + * @param max Maximum value + * + * @return Log PDF of the primary distribution + * + * @code + * // Example: Uniform distribution + * real x = 0.5; + * int primray_id = 1; // Uniform + * array[0] real params = {}; // No additional parameters for uniform + * real min = 0; + * real max = 1; + * real log_pdf = primray_lpdf(x, primray_id, params, min, max); + * @endcode + */ +real primray_lpdf(real x, int primray_id, array[] real params, real min, real max) { + // Implement switch for different primary distributions + if (primray_id == 1) return uniform_lpdf(x | min, max); + if (primray_id == 2) return expgrowth_lpdf(x | min, max, params[1]); + // Add more primary distributions as needed + reject("Invalid primary distribution identifier"); +} + +/** + * ODE system for the primary censored distribution + * + * @param t Time + * @param y State variables + * @param theta Parameters + * @param x_r Real data + * @param x_i Integer data + * + * @return Derivatives of the state variables + */ +vector primarycensored_ode(real t, vector y, array[] real theta, + array[] real x_r, array[] int x_i) { + real d = x_r[1]; + int dist_id = x_i[1]; + int primray_id = x_i[2]; + real pwindow = x_r[2]; + int dist_params_len = x_i[3]; + int primary_params_len = x_i[4]; + + // Extract distribution parameters + array[dist_params_len] real params; + if (dist_params_len) { + params = theta[1:dist_params_len]; + } + array[primary_params_len] real primary_params; + if (primary_params_len) { + int primary_loc = size(theta); + primary_params = theta[primary_loc - primary_params_len + 1:primary_loc]; + } + + real log_cdf = dist_lcdf(t | params, dist_id); + real log_primary_pdf = primray_lpdf(d - t | primray_id, primary_params, 0, pwindow); + + return rep_vector(exp(log_cdf + log_primary_pdf), 1); +} diff --git a/inst/stan/pcens_model.stan b/inst/stan/pcens_model.stan index 8083098..0884932 100644 --- a/inst/stan/pcens_model.stan +++ b/inst/stan/pcens_model.stan @@ -1,19 +1,20 @@ functions { - #include primary_censored_dist.stan - #include primary_censored_dist_analytical_cdf.stan + #include primarycensored.stan + #include primarycensored_ode.stan + #include primarycensored_analytical_cdf.stan #include expgrowth.stan real partial_sum(array[] int dummy, int start, int end, array[] int d, array[] int d_upper, array[] int n, array[] int pwindow, array[] int D, int dist_id, array[] real params, - int primary_dist_id, array[] real primary_params) { + int primray_id, array[] real primary_params) { real partial_target = 0; for (i in start:end) { - partial_target += n[i] * primary_censored_dist_lpmf( + partial_target += n[i] * primarycensored_lpmf( d[i] | dist_id, params, pwindow[i], d_upper[i], D[i], - primary_dist_id, primary_params + primray_id, primary_params ); } return partial_target; @@ -28,7 +29,7 @@ data { array[N] int pwindow; // primary censoring window array[N] int D; // maximum delay int dist_id; // distribution identifier - int primary_dist_id; // primary distribution identifier + int primray_id; // primary distribution identifier int n_params; // number of distribution parameters int n_primary_params; // number of primary distribution parameters int compute_log_lik; // whether to compute log likelihood @@ -71,13 +72,13 @@ model { if (use_reduce_sum) { target += reduce_sum(partial_sum, indexes, 1, d, d_upper, n, pwindow, D, dist_id, to_array_1d(params), - primary_dist_id, to_array_1d(primary_params)); + primray_id, to_array_1d(primary_params)); } else { for (i in 1:N) { - target += n[i] * primary_censored_dist_lpmf( + target += n[i] * primarycensored_lpmf( d[i] | dist_id, to_array_1d(params), pwindow[i], d_upper[i], D[i], - primary_dist_id, to_array_1d(primary_params) + primray_id, to_array_1d(primary_params) ); } } @@ -87,10 +88,10 @@ generated quantities { vector[compute_log_lik ? N : 0] log_lik; if (compute_log_lik) { for (i in 1:N) { - log_lik[i] = primary_censored_dist_lpmf( + log_lik[i] = primarycensored_lpmf( d[i] | dist_id, to_array_1d(params), pwindow[i], d_upper[i], D[i], - primary_dist_id, to_array_1d(primary_params) + primray_id, to_array_1d(primary_params) ); } } diff --git a/man/dot-dpcens.Rd b/man/dot-dpcens.Rd index 135baaf..6d7ec6a 100644 --- a/man/dot-dpcens.Rd +++ b/man/dot-dpcens.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/fitdistdoublecens.R \name{.dpcens} \alias{.dpcens} -\title{Define a fitdistrplus compatible wrapper around dprimarycensoreddist} +\title{Define a fitdistrplus compatible wrapper around dprimarycensored} \usage{ .dpcens( x, @@ -58,6 +58,6 @@ passed a pre-assigned variable rather than a function name.} \item{...}{Additional arguments to be passed to the distribution function} } \description{ -Define a fitdistrplus compatible wrapper around dprimarycensoreddist +Define a fitdistrplus compatible wrapper around dprimarycensored } \keyword{internal} diff --git a/man/dot-ppcens.Rd b/man/dot-ppcens.Rd index 65f5428..61aad72 100644 --- a/man/dot-ppcens.Rd +++ b/man/dot-ppcens.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/fitdistdoublecens.R \name{.ppcens} \alias{.ppcens} -\title{Define a fitdistrplus compatible wrapper around pprimarycensoreddist} +\title{Define a fitdistrplus compatible wrapper around pprimarycensored} \usage{ .ppcens( q, @@ -54,6 +54,6 @@ passed a pre-assigned variable rather than a function name.} \item{...}{Additional arguments to be passed to pdist} } \description{ -Define a fitdistrplus compatible wrapper around pprimarycensoreddist +Define a fitdistrplus compatible wrapper around pprimarycensored } \keyword{internal} diff --git a/man/dprimarycensoreddist.Rd b/man/dprimarycensored.Rd similarity index 90% rename from man/dprimarycensoreddist.Rd rename to man/dprimarycensored.Rd index 0608eb2..ac2c8db 100644 --- a/man/dprimarycensoreddist.Rd +++ b/man/dprimarycensored.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dprimarycensoreddist.R -\name{dprimarycensoreddist} -\alias{dprimarycensoreddist} +% Please edit documentation in R/dprimarycensored.R +\name{dprimarycensored} +\alias{dprimarycensored} \alias{dpcens} \title{Compute the primary event censored PMF for delays} \usage{ -dprimarycensoreddist( +dprimarycensored( x, pdist, pwindow = 1, @@ -96,7 +96,7 @@ f_{\text{cens}}(d) = F_{\text{cens}}(d + \text{swindow}) - F_{\text{cens}}(d) where \eqn{F_{\text{cens}}} is the primary event censored CDF. The function first computes the CDFs for all unique points (including both -\eqn{d} and \eqn{d + \text{swindow}}) using \code{\link[=pprimarycensoreddist]{pprimarycensoreddist()}}. It then +\eqn{d} and \eqn{d + \text{swindow}}) using \code{\link[=pprimarycensored]{pprimarycensored()}}. It then creates a lookup table for these CDFs to efficiently calculate the PMF for each input value. For non-positive delays, the function returns 0. @@ -110,14 +110,14 @@ f_{\text{cens,norm}}(d) = \frac{f_{\text{cens}}(d)}{\sum_{i=0}^{D-1} where \eqn{f_{\text{cens,norm}}(d)} is the normalized PMF and \eqn{f_{\text{cens}}(d)} is the unnormalized PMF. For the explanation and mathematical details of the CDF, refer to the documentation of -\code{\link[=pprimarycensoreddist]{pprimarycensoreddist()}}. +\code{\link[=pprimarycensored]{pprimarycensored()}}. } \examples{ # Example: Weibull distribution with uniform primary events -dprimarycensoreddist(c(0.1, 0.5, 1), pweibull, shape = 1.5, scale = 2.0) +dprimarycensored(c(0.1, 0.5, 1), pweibull, shape = 1.5, scale = 2.0) # Example: Weibull distribution with exponential growth primary events -dprimarycensoreddist( +dprimarycensored( c(0.1, 0.5, 1), pweibull, dprimary = dexpgrowth, dprimary_args = list(r = 0.2), shape = 1.5, scale = 2.0 @@ -125,7 +125,7 @@ dprimarycensoreddist( } \seealso{ Primary event censored distribution functions -\code{\link{pprimarycensoreddist}()}, -\code{\link{rprimarycensoreddist}()} +\code{\link{pprimarycensored}()}, +\code{\link{rprimarycensored}()} } -\concept{primarycensoreddist} +\concept{rpd_primarycensored} diff --git a/man/figures/logo.png b/man/figures/logo.png index 2e233d4..7999c8e 100644 Binary files a/man/figures/logo.png and b/man/figures/logo.png differ diff --git a/man/fitdistdoublecens.Rd b/man/fitdistdoublecens.Rd index c09700d..f5d73b0 100644 --- a/man/fitdistdoublecens.Rd +++ b/man/fitdistdoublecens.Rd @@ -59,7 +59,7 @@ An object of class "fitdist" as returned by fitdistrplus::fitdist. } \description{ This function wraps the custom approach for fitting distributions to doubly -censored data using fitdistrplus and primarycensoreddist. +censored data using fitdistrplus and primarycensored. } \details{ This function temporarily assigns and then removes functions from the global @@ -76,7 +76,7 @@ true_sd <- 2 pwindow <- 2 swindow <- 2 D <- 10 -samples <- rprimarycensoreddist( +samples <- rprimarycensored( n, rnorm, mean = true_mean, sd = true_sd, pwindow = pwindow, swindow = swindow, D = D diff --git a/man/new_primary_censored_dist.Rd b/man/new_primarycensored.Rd similarity index 80% rename from man/new_primary_censored_dist.Rd rename to man/new_primarycensored.Rd index 8413302..d54d92c 100644 --- a/man/new_primary_censored_dist.Rd +++ b/man/new_primarycensored.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/primary_censored_dist.R -\name{new_primary_censored_dist} -\alias{new_primary_censored_dist} +% Please edit documentation in R/primarycensored.R +\name{new_primarycensored} +\alias{new_primarycensored} \title{S3 class for primary event censored distribution computation} \usage{ -new_primary_censored_dist( +new_primarycensored( pdist, dprimary, dprimary_args, @@ -44,17 +44,17 @@ passed a pre-assigned variable rather than a function name.} \item{...}{Additional arguments to be passed to pdist} } \value{ -An object of class primary_censored_cdf +An object of class primarycensored_cdf } \description{ S3 class for primary event censored distribution computation } \seealso{ Low level primary event censored distribution objects and methods -\code{\link{primary_censored_cdf}()}, -\code{\link{primary_censored_cdf.default}()}, -\code{\link{primary_censored_cdf.pcens_pgamma_dunif}()}, -\code{\link{primary_censored_cdf.pcens_plnorm_dunif}()}, -\code{\link{primary_censored_cdf.pcens_pweibull_dunif}()} +\code{\link{primarycensored_cdf}()}, +\code{\link{primarycensored_cdf.default}()}, +\code{\link{primarycensored_cdf.pcens_pgamma_dunif}()}, +\code{\link{primarycensored_cdf.pcens_plnorm_dunif}()}, +\code{\link{primarycensored_cdf.pcens_pweibull_dunif}()} } -\concept{primary_censored_dist} +\concept{primarycensored} diff --git a/man/pcd_as_stan_data.Rd b/man/pcd_as_stan_data.Rd index 1180c29..b40330d 100644 --- a/man/pcd_as_stan_data.Rd +++ b/man/pcd_as_stan_data.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/pcd_cmdstan_model.R \name{pcd_as_stan_data} \alias{pcd_as_stan_data} -\title{Prepare data for primarycensoreddist Stan model} +\title{Prepare data for primarycensored Stan model} \usage{ pcd_as_stan_data( data, @@ -12,7 +12,7 @@ pcd_as_stan_data( pwindow = "pwindow", relative_obs_time = "relative_obs_time", dist_id, - primary_dist_id, + primray_id, param_bounds, primary_param_bounds, priors, @@ -44,7 +44,7 @@ pcd_as_stan_data( 13 = Chi-square, 14 = Dirichlet, 15 = Gumbel, 16 = Inverse Gamma, 17 = Logistic} -\item{primary_dist_id}{Integer identifying the primary distribution: +\item{primray_id}{Integer identifying the primary distribution: 1 = Uniform, 2 = Exponential growth} \item{param_bounds}{A list with elements \code{lower} and \code{upper}, each a numeric @@ -74,7 +74,7 @@ A list containing the data formatted for use with } \description{ This function takes in delay data and prepares it for use with the -primarycensoreddist Stan model. +primarycensored Stan model. } \examples{ \dontrun{ @@ -88,7 +88,7 @@ data <- data.frame( stan_data <- pcd_as_stan_data( data, dist_id = 1, - primary_dist_id = 1, + primray_id = 1, param_bounds = list(lower = c(0, 0), upper = c(10, 10)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(1, 1), scale = c(1, 1)), diff --git a/man/pcd_cmdstan_model.Rd b/man/pcd_cmdstan_model.Rd index 152889c..4b3eb9a 100644 --- a/man/pcd_cmdstan_model.Rd +++ b/man/pcd_cmdstan_model.Rd @@ -2,9 +2,9 @@ % Please edit documentation in R/pcd_cmdstan_model.R \name{pcd_cmdstan_model} \alias{pcd_cmdstan_model} -\title{Create a CmdStanModel with primarycensoreddist Stan functions} +\title{Create a CmdStanModel with primarycensored Stan functions} \usage{ -pcd_cmdstan_model(include_paths = primarycensoreddist::pcd_stan_path(), ...) +pcd_cmdstan_model(include_paths = primarycensored::pcd_stan_path(), ...) } \arguments{ \item{include_paths}{Character vector of paths to include for Stan @@ -17,7 +17,7 @@ A CmdStanModel object. } \description{ This function creates a CmdStanModel object using the Stan model and -functions from primarycensoreddist and optionally includes additional +functions from primarycensored and optionally includes additional user-specified Stan files. } \details{ diff --git a/man/pcd_load_stan_functions.Rd b/man/pcd_load_stan_functions.Rd index d63be90..f70c99f 100644 --- a/man/pcd_load_stan_functions.Rd +++ b/man/pcd_load_stan_functions.Rd @@ -6,7 +6,7 @@ \usage{ pcd_load_stan_functions( functions = NULL, - stan_path = primarycensoreddist::pcd_stan_path(), + stan_path = primarycensored::pcd_stan_path(), wrap_in_block = FALSE, write_to_file = FALSE, output_file = "pcd_functions.stan" @@ -17,7 +17,7 @@ pcd_load_stan_functions( functions.} \item{stan_path}{Character string, the path to the Stan code. Defaults to the -path to the Stan code in the primarycensoreddist package.} +path to the Stan code in the primarycensored package.} \item{wrap_in_block}{Logical, whether to wrap the functions in a \verb{functions\{\}} block. Default is FALSE.} diff --git a/man/pcd_stan_files.Rd b/man/pcd_stan_files.Rd index b386f06..3508d9f 100644 --- a/man/pcd_stan_files.Rd +++ b/man/pcd_stan_files.Rd @@ -4,17 +4,14 @@ \alias{pcd_stan_files} \title{Get Stan files containing specified functions} \usage{ -pcd_stan_files( - functions = NULL, - stan_path = primarycensoreddist::pcd_stan_path() -) +pcd_stan_files(functions = NULL, stan_path = primarycensored::pcd_stan_path()) } \arguments{ \item{functions}{Character vector of function names to search for. If NULL, all Stan files are returned.} \item{stan_path}{Character string specifying the path to the directory -containing Stan files. Defaults to the Stan path of the primarycensoreddist +containing Stan files. Defaults to the Stan path of the primarycensored package.} } \value{ diff --git a/man/pcd_stan_functions.Rd b/man/pcd_stan_functions.Rd index e501852..5437b34 100644 --- a/man/pcd_stan_functions.Rd +++ b/man/pcd_stan_functions.Rd @@ -4,11 +4,11 @@ \alias{pcd_stan_functions} \title{Get Stan function names from Stan files} \usage{ -pcd_stan_functions(stan_path = primarycensoreddist::pcd_stan_path()) +pcd_stan_functions(stan_path = primarycensored::pcd_stan_path()) } \arguments{ \item{stan_path}{Character string specifying the path to the directory -containing Stan files. Defaults to the Stan path of the primarycensoreddist +containing Stan files. Defaults to the Stan path of the primarycensored package.} } \value{ diff --git a/man/pprimarycensoreddist.Rd b/man/pprimarycensored.Rd similarity index 85% rename from man/pprimarycensoreddist.Rd rename to man/pprimarycensored.Rd index bbd4abf..f1b83ac 100644 --- a/man/pprimarycensoreddist.Rd +++ b/man/pprimarycensored.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pprimarycensoreddist.R -\name{pprimarycensoreddist} -\alias{pprimarycensoreddist} +% Please edit documentation in R/pprimarycensored.R +\name{pprimarycensored} +\alias{pprimarycensored} \alias{ppcens} \title{Compute the primary event censored CDF for delays} \usage{ -pprimarycensoreddist( +pprimarycensored( q, pdist, pwindow = 1, @@ -99,9 +99,9 @@ F_{\text{cens,norm}}(q) = \frac{F_{\text{cens}}(q)}{F_{\text{cens}}(D)} } where \eqn{F_{\text{cens,norm}}(q)} is the normalized CDF. -This function creates a \code{primary_censored_dist} object using -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}} and then computes the primary event -censored CDF using \code{\link[=primary_censored_cdf]{primary_censored_cdf()}}. This abstraction allows +This function creates a \code{primarycensored} object using +\code{\link[=new_primarycensored]{new_primarycensored()}} and then computes the primary event +censored CDF using \code{\link[=primarycensored_cdf]{primarycensored_cdf()}}. This abstraction allows for automatic use of analytical solutions when available, while seamlessly falling back to numerical integration when necessary. @@ -112,20 +112,20 @@ extraction of the function name. } \examples{ # Example: Lognormal distribution with uniform primary events -pprimarycensoreddist(c(0.1, 0.5, 1), plnorm, meanlog = 0, sdlog = 1) +pprimarycensored(c(0.1, 0.5, 1), plnorm, meanlog = 0, sdlog = 1) # Example: Lognormal distribution with exponential growth primary events -pprimarycensoreddist( +pprimarycensored( c(0.1, 0.5, 1), plnorm, dprimary = dexpgrowth, dprimary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) } \seealso{ -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}} and \code{\link[=primary_censored_cdf]{primary_censored_cdf()}} +\code{\link[=new_primarycensored]{new_primarycensored()}} and \code{\link[=primarycensored_cdf]{primarycensored_cdf()}} Primary event censored distribution functions -\code{\link{dprimarycensoreddist}()}, -\code{\link{rprimarycensoreddist}()} +\code{\link{dprimarycensored}()}, +\code{\link{rprimarycensored}()} } -\concept{primarycensoreddist} +\concept{rpd_primarycensored} diff --git a/man/primary_censored_cdf.Rd b/man/primary_censored_cdf.Rd deleted file mode 100644 index d425fd5..0000000 --- a/man/primary_censored_cdf.Rd +++ /dev/null @@ -1,36 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/primary_censored_dist.R -\name{primary_censored_cdf} -\alias{primary_censored_cdf} -\title{Compute primary event censored CDF} -\usage{ -primary_censored_cdf(object, q, pwindow, use_numeric = FALSE) -} -\arguments{ -\item{object}{A \code{primary_censored_dist} object as created by -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}}.} - -\item{q}{Vector of quantiles} - -\item{pwindow}{Primary event window} - -\item{use_numeric}{Logical, if TRUE forces use of numeric integration -even for distributions with analytical solutions. This is primarily -useful for testing purposes or for settings where the analytical solution -breaks down.} -} -\value{ -Vector of primary event censored CDFs -} -\description{ -Compute primary event censored CDF -} -\seealso{ -Low level primary event censored distribution objects and methods -\code{\link{new_primary_censored_dist}()}, -\code{\link{primary_censored_cdf.default}()}, -\code{\link{primary_censored_cdf.pcens_pgamma_dunif}()}, -\code{\link{primary_censored_cdf.pcens_plnorm_dunif}()}, -\code{\link{primary_censored_cdf.pcens_pweibull_dunif}()} -} -\concept{primary_censored_dist} diff --git a/man/primary_censored_cdf.pcens_pgamma_dunif.Rd b/man/primary_censored_cdf.pcens_pgamma_dunif.Rd deleted file mode 100644 index b88845a..0000000 --- a/man/primary_censored_cdf.pcens_pgamma_dunif.Rd +++ /dev/null @@ -1,33 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/primary_censored_dist.R -\name{primary_censored_cdf.pcens_pgamma_dunif} -\alias{primary_censored_cdf.pcens_pgamma_dunif} -\title{Method for Gamma delay with uniform primary} -\usage{ -\method{primary_censored_cdf}{pcens_pgamma_dunif}(object, q, pwindow, use_numeric = FALSE) -} -\arguments{ -\item{object}{A \code{primary_censored_dist} object as created by -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}}.} - -\item{q}{Vector of quantiles} - -\item{pwindow}{Primary event window} - -\item{use_numeric}{Logical, if TRUE forces use of numeric integration -even for distributions with analytical solutions. This is primarily -useful for testing purposes or for settings where the analytical solution -breaks down.} -} -\description{ -Method for Gamma delay with uniform primary -} -\seealso{ -Low level primary event censored distribution objects and methods -\code{\link{new_primary_censored_dist}()}, -\code{\link{primary_censored_cdf}()}, -\code{\link{primary_censored_cdf.default}()}, -\code{\link{primary_censored_cdf.pcens_plnorm_dunif}()}, -\code{\link{primary_censored_cdf.pcens_pweibull_dunif}()} -} -\concept{primary_censored_dist} diff --git a/man/primary_censored_cdf.pcens_plnorm_dunif.Rd b/man/primary_censored_cdf.pcens_plnorm_dunif.Rd deleted file mode 100644 index 2059694..0000000 --- a/man/primary_censored_cdf.pcens_plnorm_dunif.Rd +++ /dev/null @@ -1,33 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/primary_censored_dist.R -\name{primary_censored_cdf.pcens_plnorm_dunif} -\alias{primary_censored_cdf.pcens_plnorm_dunif} -\title{Method for Log-Normal delay with uniform primary} -\usage{ -\method{primary_censored_cdf}{pcens_plnorm_dunif}(object, q, pwindow, use_numeric = FALSE) -} -\arguments{ -\item{object}{A \code{primary_censored_dist} object as created by -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}}.} - -\item{q}{Vector of quantiles} - -\item{pwindow}{Primary event window} - -\item{use_numeric}{Logical, if TRUE forces use of numeric integration -even for distributions with analytical solutions. This is primarily -useful for testing purposes or for settings where the analytical solution -breaks down.} -} -\description{ -Method for Log-Normal delay with uniform primary -} -\seealso{ -Low level primary event censored distribution objects and methods -\code{\link{new_primary_censored_dist}()}, -\code{\link{primary_censored_cdf}()}, -\code{\link{primary_censored_cdf.default}()}, -\code{\link{primary_censored_cdf.pcens_pgamma_dunif}()}, -\code{\link{primary_censored_cdf.pcens_pweibull_dunif}()} -} -\concept{primary_censored_dist} diff --git a/man/primary_censored_cdf.pcens_pweibull_dunif.Rd b/man/primary_censored_cdf.pcens_pweibull_dunif.Rd deleted file mode 100644 index 3e1839e..0000000 --- a/man/primary_censored_cdf.pcens_pweibull_dunif.Rd +++ /dev/null @@ -1,33 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/primary_censored_dist.R -\name{primary_censored_cdf.pcens_pweibull_dunif} -\alias{primary_censored_cdf.pcens_pweibull_dunif} -\title{Method for Weibull delay with uniform primary} -\usage{ -\method{primary_censored_cdf}{pcens_pweibull_dunif}(object, q, pwindow, use_numeric = FALSE) -} -\arguments{ -\item{object}{A \code{primary_censored_dist} object as created by -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}}.} - -\item{q}{Vector of quantiles} - -\item{pwindow}{Primary event window} - -\item{use_numeric}{Logical, if TRUE forces use of numeric integration -even for distributions with analytical solutions. This is primarily -useful for testing purposes or for settings where the analytical solution -breaks down.} -} -\description{ -Method for Weibull delay with uniform primary -} -\seealso{ -Low level primary event censored distribution objects and methods -\code{\link{new_primary_censored_dist}()}, -\code{\link{primary_censored_cdf}()}, -\code{\link{primary_censored_cdf.default}()}, -\code{\link{primary_censored_cdf.pcens_pgamma_dunif}()}, -\code{\link{primary_censored_cdf.pcens_plnorm_dunif}()} -} -\concept{primary_censored_dist} diff --git a/man/primarycensored_cdf.Rd b/man/primarycensored_cdf.Rd new file mode 100644 index 0000000..e541b1e --- /dev/null +++ b/man/primarycensored_cdf.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/primarycensored.R +\name{primarycensored_cdf} +\alias{primarycensored_cdf} +\title{Compute primary event censored CDF} +\usage{ +primarycensored_cdf(object, q, pwindow, use_numeric = FALSE) +} +\arguments{ +\item{object}{A \code{primarycensored} object as created by +\code{\link[=new_primarycensored]{new_primarycensored()}}.} + +\item{q}{Vector of quantiles} + +\item{pwindow}{Primary event window} + +\item{use_numeric}{Logical, if TRUE forces use of numeric integration +even for distributions with analytical solutions. This is primarily +useful for testing purposes or for settings where the analytical solution +breaks down.} +} +\value{ +Vector of primary event censored CDFs +} +\description{ +Compute primary event censored CDF +} +\seealso{ +Low level primary event censored distribution objects and methods +\code{\link{new_primarycensored}()}, +\code{\link{primarycensored_cdf.default}()}, +\code{\link{primarycensored_cdf.pcens_pgamma_dunif}()}, +\code{\link{primarycensored_cdf.pcens_plnorm_dunif}()}, +\code{\link{primarycensored_cdf.pcens_pweibull_dunif}()} +} +\concept{primarycensored} diff --git a/man/primary_censored_cdf.default.Rd b/man/primarycensored_cdf.default.Rd similarity index 57% rename from man/primary_censored_cdf.default.Rd rename to man/primarycensored_cdf.default.Rd index 6efe5ff..60fdc39 100644 --- a/man/primary_censored_cdf.default.Rd +++ b/man/primarycensored_cdf.default.Rd @@ -1,14 +1,14 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/primary_censored_dist.R -\name{primary_censored_cdf.default} -\alias{primary_censored_cdf.default} +% Please edit documentation in R/primarycensored.R +\name{primarycensored_cdf.default} +\alias{primarycensored_cdf.default} \title{Default method for computing primary event censored CDF} \usage{ -\method{primary_censored_cdf}{default}(object, q, pwindow, use_numeric = FALSE) +\method{primarycensored_cdf}{default}(object, q, pwindow, use_numeric = FALSE) } \arguments{ -\item{object}{A \code{primary_censored_dist} object as created by -\code{\link[=new_primary_censored_dist]{new_primary_censored_dist()}}.} +\item{object}{A \code{primarycensored} object as created by +\code{\link[=new_primarycensored]{new_primarycensored()}}.} \item{q}{Vector of quantiles} @@ -27,18 +27,18 @@ the numeric integration method. \details{ This method implements the numerical integration approach for computing the primary event censored CDF. It uses the same mathematical formulation -as described in the details section of \code{\link[=pprimarycensoreddist]{pprimarycensoreddist()}}, but +as described in the details section of \code{\link[=pprimarycensored]{pprimarycensored()}}, but applies numerical integration instead of analytical solutions. } \seealso{ -\code{\link[=pprimarycensoreddist]{pprimarycensoreddist()}} for the mathematical details of the +\code{\link[=pprimarycensored]{pprimarycensored()}} for the mathematical details of the primary event censored CDF computation. Low level primary event censored distribution objects and methods -\code{\link{new_primary_censored_dist}()}, -\code{\link{primary_censored_cdf}()}, -\code{\link{primary_censored_cdf.pcens_pgamma_dunif}()}, -\code{\link{primary_censored_cdf.pcens_plnorm_dunif}()}, -\code{\link{primary_censored_cdf.pcens_pweibull_dunif}()} +\code{\link{new_primarycensored}()}, +\code{\link{primarycensored_cdf}()}, +\code{\link{primarycensored_cdf.pcens_pgamma_dunif}()}, +\code{\link{primarycensored_cdf.pcens_plnorm_dunif}()}, +\code{\link{primarycensored_cdf.pcens_pweibull_dunif}()} } -\concept{primary_censored_dist} +\concept{primarycensored} diff --git a/man/primarycensored_cdf.pcens_pgamma_dunif.Rd b/man/primarycensored_cdf.pcens_pgamma_dunif.Rd new file mode 100644 index 0000000..2a2d67d --- /dev/null +++ b/man/primarycensored_cdf.pcens_pgamma_dunif.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/primarycensored.R +\name{primarycensored_cdf.pcens_pgamma_dunif} +\alias{primarycensored_cdf.pcens_pgamma_dunif} +\title{Method for Gamma delay with uniform primary} +\usage{ +\method{primarycensored_cdf}{pcens_pgamma_dunif}(object, q, pwindow, use_numeric = FALSE) +} +\arguments{ +\item{object}{A \code{primarycensored} object as created by +\code{\link[=new_primarycensored]{new_primarycensored()}}.} + +\item{q}{Vector of quantiles} + +\item{pwindow}{Primary event window} + +\item{use_numeric}{Logical, if TRUE forces use of numeric integration +even for distributions with analytical solutions. This is primarily +useful for testing purposes or for settings where the analytical solution +breaks down.} +} +\description{ +Method for Gamma delay with uniform primary +} +\seealso{ +Low level primary event censored distribution objects and methods +\code{\link{new_primarycensored}()}, +\code{\link{primarycensored_cdf}()}, +\code{\link{primarycensored_cdf.default}()}, +\code{\link{primarycensored_cdf.pcens_plnorm_dunif}()}, +\code{\link{primarycensored_cdf.pcens_pweibull_dunif}()} +} +\concept{primarycensored} diff --git a/man/primarycensored_cdf.pcens_plnorm_dunif.Rd b/man/primarycensored_cdf.pcens_plnorm_dunif.Rd new file mode 100644 index 0000000..9f02711 --- /dev/null +++ b/man/primarycensored_cdf.pcens_plnorm_dunif.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/primarycensored.R +\name{primarycensored_cdf.pcens_plnorm_dunif} +\alias{primarycensored_cdf.pcens_plnorm_dunif} +\title{Method for Log-Normal delay with uniform primary} +\usage{ +\method{primarycensored_cdf}{pcens_plnorm_dunif}(object, q, pwindow, use_numeric = FALSE) +} +\arguments{ +\item{object}{A \code{primarycensored} object as created by +\code{\link[=new_primarycensored]{new_primarycensored()}}.} + +\item{q}{Vector of quantiles} + +\item{pwindow}{Primary event window} + +\item{use_numeric}{Logical, if TRUE forces use of numeric integration +even for distributions with analytical solutions. This is primarily +useful for testing purposes or for settings where the analytical solution +breaks down.} +} +\description{ +Method for Log-Normal delay with uniform primary +} +\seealso{ +Low level primary event censored distribution objects and methods +\code{\link{new_primarycensored}()}, +\code{\link{primarycensored_cdf}()}, +\code{\link{primarycensored_cdf.default}()}, +\code{\link{primarycensored_cdf.pcens_pgamma_dunif}()}, +\code{\link{primarycensored_cdf.pcens_pweibull_dunif}()} +} +\concept{primarycensored} diff --git a/man/primarycensored_cdf.pcens_pweibull_dunif.Rd b/man/primarycensored_cdf.pcens_pweibull_dunif.Rd new file mode 100644 index 0000000..93793e2 --- /dev/null +++ b/man/primarycensored_cdf.pcens_pweibull_dunif.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/primarycensored.R +\name{primarycensored_cdf.pcens_pweibull_dunif} +\alias{primarycensored_cdf.pcens_pweibull_dunif} +\title{Method for Weibull delay with uniform primary} +\usage{ +\method{primarycensored_cdf}{pcens_pweibull_dunif}(object, q, pwindow, use_numeric = FALSE) +} +\arguments{ +\item{object}{A \code{primarycensored} object as created by +\code{\link[=new_primarycensored]{new_primarycensored()}}.} + +\item{q}{Vector of quantiles} + +\item{pwindow}{Primary event window} + +\item{use_numeric}{Logical, if TRUE forces use of numeric integration +even for distributions with analytical solutions. This is primarily +useful for testing purposes or for settings where the analytical solution +breaks down.} +} +\description{ +Method for Weibull delay with uniform primary +} +\seealso{ +Low level primary event censored distribution objects and methods +\code{\link{new_primarycensored}()}, +\code{\link{primarycensored_cdf}()}, +\code{\link{primarycensored_cdf.default}()}, +\code{\link{primarycensored_cdf.pcens_pgamma_dunif}()}, +\code{\link{primarycensored_cdf.pcens_plnorm_dunif}()} +} +\concept{primarycensored} diff --git a/man/roxygen/meta.R b/man/roxygen/meta.R index ed60282..c775986 100644 --- a/man/roxygen/meta.R +++ b/man/roxygen/meta.R @@ -1,7 +1,7 @@ list( # nolint rd_family_title = list( # nolint - primarycensoreddist = "Primary event censored distribution functions", - primary_censored_dist = + rpd_primarycensored = "Primary event censored distribution functions", + primarycensored = "Low level primary event censored distribution objects and methods", primaryeventdistributions = "Primary event distributions", check = "Distribution checking functions", diff --git a/man/rprimarycensoreddist.Rd b/man/rprimarycensored.Rd similarity index 90% rename from man/rprimarycensoreddist.Rd rename to man/rprimarycensored.Rd index 39e27ba..d18096c 100644 --- a/man/rprimarycensoreddist.Rd +++ b/man/rprimarycensored.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/rprimarycensoreddist.R -\name{rprimarycensoreddist} -\alias{rprimarycensoreddist} +% Please edit documentation in R/rprimarycensored.R +\name{rprimarycensored} +\alias{rprimarycensored} \alias{rpcens} \title{Generate random samples from a primary event censored distribution} \usage{ -rprimarycensoreddist( +rprimarycensored( n, rdist, pwindow = 1, @@ -91,10 +91,10 @@ additional samples if needed to reach the desired number of valid samples. } \examples{ # Example: Lognormal distribution with uniform primary events -rprimarycensoreddist(10, rlnorm, meanlog = 0, sdlog = 1) +rprimarycensored(10, rlnorm, meanlog = 0, sdlog = 1) # Example: Lognormal distribution with exponential growth primary events -rprimarycensoreddist( +rprimarycensored( 10, rlnorm, rprimary = rexpgrowth, rprimary_args = list(r = 0.2), meanlog = 0, sdlog = 1 @@ -102,7 +102,7 @@ rprimarycensoreddist( } \seealso{ Primary event censored distribution functions -\code{\link{dprimarycensoreddist}()}, -\code{\link{pprimarycensoreddist}()} +\code{\link{dprimarycensored}()}, +\code{\link{pprimarycensored}()} } -\concept{primarycensoreddist} +\concept{rpd_primarycensored} diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png index 00f7792..e95f068 100644 Binary files a/pkgdown/favicon/apple-touch-icon.png and b/pkgdown/favicon/apple-touch-icon.png differ diff --git a/pkgdown/favicon/favicon-48x48.png b/pkgdown/favicon/favicon-48x48.png new file mode 100644 index 0000000..f05c681 Binary files /dev/null and b/pkgdown/favicon/favicon-48x48.png differ diff --git a/pkgdown/favicon/favicon.ico b/pkgdown/favicon/favicon.ico index 85ba374..486f5cd 100644 Binary files a/pkgdown/favicon/favicon.ico and b/pkgdown/favicon/favicon.ico differ diff --git a/pkgdown/favicon/favicon.svg b/pkgdown/favicon/favicon.svg new file mode 100644 index 0000000..f2587e2 --- /dev/null +++ b/pkgdown/favicon/favicon.svg @@ -0,0 +1,3 @@ + diff --git a/pkgdown/favicon/site.webmanifest b/pkgdown/favicon/site.webmanifest new file mode 100644 index 0000000..ac9612c --- /dev/null +++ b/pkgdown/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/pkgdown/favicon/web-app-manifest-192x192.png b/pkgdown/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000..0e85452 Binary files /dev/null and b/pkgdown/favicon/web-app-manifest-192x192.png differ diff --git a/pkgdown/favicon/web-app-manifest-512x512.png b/pkgdown/favicon/web-app-manifest-512x512.png new file mode 100644 index 0000000..7376fa6 Binary files /dev/null and b/pkgdown/favicon/web-app-manifest-512x512.png differ diff --git a/tests/testthat.R b/tests/testthat.R index 334138e..759de50 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -1,7 +1,7 @@ library(testthat) -library(primarycensoreddist) +library(primarycensored) -test_results <- test_check("primarycensoreddist") +test_results <- test_check("primarycensored") if (any(as.data.frame(test_results)$warning > 0)) { stop("tests failed with warnings") diff --git a/tests/testthat/test-dprimarycensoreddist.R b/tests/testthat/test-dprimarycensored.R similarity index 79% rename from tests/testthat/test-dprimarycensoreddist.R rename to tests/testthat/test-dprimarycensored.R index 3273aa6..1733380 100644 --- a/tests/testthat/test-dprimarycensoreddist.R +++ b/tests/testthat/test-dprimarycensored.R @@ -1,4 +1,4 @@ -test_that("dprimarycensoreddist sums to 1 for discrete values", { +test_that("dprimarycensored sums to 1 for discrete values", { pwindow <- 1 D <- 10 pmf <- dpcens( @@ -8,7 +8,7 @@ test_that("dprimarycensoreddist sums to 1 for discrete values", { expect_equal(sum(pmf), 1, tolerance = 1e-6) }) -test_that("dprimarycensoreddist handles log probabilities", { +test_that("dprimarycensored handles log probabilities", { pwindow <- 1 D <- 10 pmf <- dpcens( @@ -22,7 +22,7 @@ test_that("dprimarycensoreddist handles log probabilities", { expect_equal(exp(log_pmf), pmf, tolerance = 1e-6) }) -test_that("dprimarycensoreddist handles non-finite D", { +test_that("dprimarycensored handles non-finite D", { pwindow <- 1 D <- Inf pmf <- dpcens( @@ -33,7 +33,7 @@ test_that("dprimarycensoreddist handles non-finite D", { expect_equal(sum(pmf), 1, tolerance = 0.01) }) -test_that("dprimarycensoreddist matches difference of pprimarycensoreddist", { +test_that("dprimarycensored matches difference of pprimarycensored", { x <- c(1, 2, 3) pwindow <- 5 swindow <- 0.5 @@ -58,7 +58,7 @@ test_that("dprimarycensoreddist matches difference of pprimarycensoreddist", { }) test_that( - "dprimarycensoreddist throws an error for invalid upper truncation point", + "dprimarycensored throws an error for invalid upper truncation point", { d <- 10 pwindow <- 1 @@ -75,7 +75,7 @@ test_that( } ) -test_that("dprimarycensoreddist returns 0 for negative d", { +test_that("dprimarycensored returns 0 for negative d", { d <- -1 pwindow <- 1 swindow <- 0.5 diff --git a/tests/testthat/test-fitdistdoublecens.R b/tests/testthat/test-fitdistdoublecens.R index d2a3abb..b845fde 100644 --- a/tests/testthat/test-fitdistdoublecens.R +++ b/tests/testthat/test-fitdistdoublecens.R @@ -13,7 +13,7 @@ test_that("fitdistdoublecens works correctly", { rate <- 0.44 # Generate samples - samples <- rprimarycensoreddist( + samples <- rprimarycensored( n, rgamma, shape = shape, rate = rate, pwindow = 1, swindow = 1, D = 8 @@ -75,7 +75,7 @@ test_that("fitdistdoublecens works with different distributions", { # Test with normal distribution true_mean <- 5 true_sd <- 2 - samples <- rprimarycensoreddist( + samples <- rprimarycensored( n, rnorm, mean = true_mean, sd = true_sd, pwindow = 2, swindow = 2, D = 10 diff --git a/tests/testthat/test-pcd-stan-tools.R b/tests/testthat/test-pcd-stan-tools.R index ded5a2d..5985e96 100644 --- a/tests/testthat/test-pcd-stan-tools.R +++ b/tests/testthat/test-pcd-stan-tools.R @@ -14,8 +14,8 @@ test_that("pcd_stan_functions returns unique function names", { # Check if specific Stan functions are included expected_functions <- c( "expgrowth_pdf", "expgrowth_lpdf", "expgrowth_cdf", "expgrowth_lcdf", - "expgrowth_rng", "primary_censored_ode", "dist_lcdf", - "primary_censored_dist_lcdf", "primary_censored_dist_lpmf" + "expgrowth_rng", "primarycensored_ode", "dist_lcdf", + "primarycensored_lcdf", "primarycensored_lpmf" ) for (func in expected_functions) { expect_true( @@ -27,7 +27,7 @@ test_that("pcd_stan_functions returns unique function names", { test_that("pcd_load_stan_functions loads specific functions", { specific_functions <- c( - "expgrowth_pdf", "expgrowth_lpdf", "primary_censored_ode" + "expgrowth_pdf", "expgrowth_lpdf", "primarycensored_ode" ) stan_code <- pcd_load_stan_functions(functions = specific_functions) expect_type(stan_code, "character") @@ -75,7 +75,7 @@ test_that("pcd_load_stan_functions writes to file when specified", { file_content <- readLines(output_file) expect_gt(length(file_content), 0) expect_true( - grepl("Stan functions from primarycensoreddist version", file_content[1], + grepl("Stan functions from primarycensored version", file_content[1], fixed = TRUE ) ) @@ -100,13 +100,13 @@ test_that("pcd_load_stan_functions loads functions from specific files", { info = paste("Function", func, "not found in loaded Stan code") ) } - expect_false(grepl("primary_censored_ode", stan_code, fixed = TRUE)) + expect_false(grepl("primarycensored_ode", stan_code, fixed = TRUE)) - primary_censored_functions <- c( - "primary_censored_ode", "dist_lcdf", "primary_censored_dist_lcdf" + primarycensored_functions <- c( + "primarycensored_ode", "dist_lcdf", "primarycensored_lcdf" ) - stan_code <- pcd_load_stan_functions(functions = primary_censored_functions) - for (func in primary_censored_functions) { + stan_code <- pcd_load_stan_functions(functions = primarycensored_functions) + for (func in primarycensored_functions) { expect_true( grepl(func, stan_code), info = paste("Function", func, "not found in loaded Stan code") @@ -130,7 +130,7 @@ test_that("pcd_stan_files returns correct files", { expect_true(all(grepl("expgrowth", expgrowth_files, fixed = TRUE))) # Test with functions from different files - mixed_functions <- c("expgrowth_pdf", "primary_censored_ode") + mixed_functions <- c("expgrowth_pdf", "primarycensored_ode") mixed_files <- pcd_stan_files(functions = mixed_functions) expect_type(mixed_files, "character") expect_gt(length(mixed_files), 1) diff --git a/tests/testthat/test-pcd_as_cmdstan_data.R b/tests/testthat/test-pcd_as_stan_data.R similarity index 95% rename from tests/testthat/test-pcd_as_cmdstan_data.R rename to tests/testthat/test-pcd_as_stan_data.R index c52f603..862f4b1 100644 --- a/tests/testthat/test-pcd_as_cmdstan_data.R +++ b/tests/testthat/test-pcd_as_stan_data.R @@ -8,7 +8,7 @@ test_that("pcd_as_stan_data correctly formats data", { ) dist_id <- 1 - primary_dist_id <- 1 + primray_id <- 1 param_bounds <- list(lower = c(0, 0), upper = c(10, 10)) primary_param_bounds <- list(lower = numeric(0), upper = numeric(0)) priors <- list(location = c(1, 1), scale = c(1, 1)) @@ -18,7 +18,7 @@ test_that("pcd_as_stan_data correctly formats data", { result <- pcd_as_stan_data( # nolint data, dist_id = dist_id, - primary_dist_id = primary_dist_id, + primray_id = primray_id, param_bounds = param_bounds, primary_param_bounds = primary_param_bounds, priors = priors, @@ -34,7 +34,7 @@ test_that("pcd_as_stan_data correctly formats data", { expect_identical(result$pwindow, data$pwindow) expect_identical(result$D, data$relative_obs_time) expect_identical(result$dist_id, dist_id) - expect_identical(result$primary_dist_id, primary_dist_id) + expect_identical(result$primray_id, primray_id) expect_identical(result$n_params, length(param_bounds$lower)) expect_identical(result$n_primary_params, length(primary_param_bounds$lower)) expect_identical(result$compute_log_lik, 0L) @@ -64,7 +64,7 @@ test_that("pcd_as_stan_data handles missing columns correctly", { pcd_as_stan_data( data, dist_id = 1, - primary_dist_id = 1, + primray_id = 1, param_bounds = list(lower = c(0, 0), upper = c(10, 10)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(1, 1), scale = c(1, 1)), @@ -87,7 +87,7 @@ test_that("pcd_as_stan_data handles optional parameters correctly", { result <- pcd_as_stan_data( # nolint data, dist_id = 1, - primary_dist_id = 1, + primray_id = 1, param_bounds = list(lower = c(0, 0), upper = c(10, 10)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(1, 1), scale = c(1, 1)), @@ -119,7 +119,7 @@ test_that("pcd_as_stan_data handles custom column names correctly", { pwindow = "primary_window", relative_obs_time = "obs_time", dist_id = 1, - primary_dist_id = 1, + primray_id = 1, param_bounds = list(lower = c(0, 0), upper = c(10, 10)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(1, 1), scale = c(1, 1)), diff --git a/tests/testthat/test-pcd_cmdstan_model.R b/tests/testthat/test-pcd_cmdstan_model.R index 3f2b492..2212b9d 100644 --- a/tests/testthat/test-pcd_cmdstan_model.R +++ b/tests/testthat/test-pcd_cmdstan_model.R @@ -41,7 +41,7 @@ test_that("pcd_cmdstan_model recovers true values for simple lognormal data", { true_meanlog <- 1.5 true_sdlog <- 0.5 - simulated_delays <- rprimarycensoreddist( + simulated_delays <- rprimarycensored( n = n, rdist = rlnorm, meanlog = true_meanlog, @@ -67,7 +67,7 @@ test_that("pcd_cmdstan_model recovers true values for simple lognormal data", { stan_data <- pcd_as_stan_data( delay_counts, dist_id = 1, # Lognormal - primary_dist_id = 1, # Uniform + primray_id = 1, # Uniform param_bounds = list(lower = c(-Inf, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(0, 1), scale = c(1, 1)), @@ -113,7 +113,7 @@ test_that( true_shape <- 2 true_rate <- 0.5 - simulated_delays <- rprimarycensoreddist( + simulated_delays <- rprimarycensored( n = n, rdist = rgamma, shape = true_shape, @@ -142,7 +142,7 @@ test_that( stan_data <- pcd_as_stan_data( delay_counts, dist_id = 2, # Gamma - primary_dist_id = 2, # Exponential growth + primray_id = 2, # Exponential growth param_bounds = list(lower = c(0, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = 0, upper = Inf), priors = list(location = c(2, 1), scale = c(0.5, 0.5)), @@ -194,7 +194,7 @@ test_that( true_meanlog <- 1.6 true_sdlog <- 0.5 - simulated_delays <- rprimarycensoreddist( + simulated_delays <- rprimarycensored( n = n, rdist = rlnorm, meanlog = true_meanlog, @@ -221,7 +221,7 @@ test_that( stan_data <- pcd_as_stan_data( delay_counts, dist_id = 1, # Lognormal - primary_dist_id = 1, # Uniform + primray_id = 1, # Uniform param_bounds = list(lower = c(-Inf, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(1, 0.5), scale = c(1, 1)), @@ -277,7 +277,7 @@ test_that( D <- 30 simulated_data <- data.frame( - delay = rprimarycensoreddist( + delay = rprimarycensored( n = n_obs, rdist = rlnorm, meanlog = true_meanlog, @@ -302,7 +302,7 @@ test_that( stan_data <- pcd_as_stan_data( delay_counts, dist_id = 1, # Lognormal - primary_dist_id = 1, # Uniform + primray_id = 1, # Uniform param_bounds = list(lower = c(-Inf, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(0, 1), scale = c(1, 1)), diff --git a/tests/testthat/test-pprimarycensoreddist.R b/tests/testthat/test-pprimarycensored.R similarity index 74% rename from tests/testthat/test-pprimarycensoreddist.R rename to tests/testthat/test-pprimarycensored.R index 3805860..b48e1da 100644 --- a/tests/testthat/test-pprimarycensoreddist.R +++ b/tests/testthat/test-pprimarycensored.R @@ -1,18 +1,18 @@ -test_that("pprimarycensoreddist returns 0 for non-positive quantiles", { +test_that("pprimarycensored returns 0 for non-positive quantiles", { pwindow <- 1 D <- 10 cdf <- ppcens(c(-1, 0), plnorm, pwindow, D = D, meanlog = 1, sdlog = 1) expect_identical(cdf, c(0, 0)) }) -test_that("pprimarycensoreddist approaches 1 for large quantiles", { +test_that("pprimarycensored approaches 1 for large quantiles", { pwindow <- 1 D <- Inf cdf <- ppcens(1000, plnorm, pwindow, D = D, meanlog = 1, sdlog = 1) expect_equal(cdf, 1, tolerance = 1e-6) }) -test_that("pprimarycensoreddist is monotonically increasing", { +test_that("pprimarycensored is monotonically increasing", { pwindow <- 1 D <- 10 q <- seq(0, D, by = 0.5) @@ -20,14 +20,14 @@ test_that("pprimarycensoreddist is monotonically increasing", { expect_true(all(diff(cdf) >= 0)) }) -test_that("pprimarycensoreddist handles finite D correctly", { +test_that("pprimarycensored handles finite D correctly", { pwindow <- 1 D <- 10 cdf <- ppcens(D, plnorm, pwindow, D = D, meanlog = 1, sdlog = 1) expect_equal(cdf, 1, tolerance = 1e-6) }) -test_that("pprimarycensoreddist handles custom primary distributions", { +test_that("pprimarycensored handles custom primary distributions", { pwindow <- 5 D <- 20 cdf_uniform <- ppcens( @@ -44,7 +44,7 @@ test_that("pprimarycensoreddist handles custom primary distributions", { expect_false(all(cdf_uniform == cdf_expgrowth)) }) -test_that("pprimarycensoreddist is consistent with dprimarycensoreddist", { +test_that("pprimarycensored is consistent with dprimarycensored", { pwindow <- 1 D <- 10 q <- 0:9 diff --git a/tests/testthat/test-primary_censored_dist.R b/tests/testthat/test-primarycensored.R similarity index 75% rename from tests/testthat/test-primary_censored_dist.R rename to tests/testthat/test-primarycensored.R index 5a0bdf7..168f2ad 100644 --- a/tests/testthat/test-primary_censored_dist.R +++ b/tests/testthat/test-primarycensored.R @@ -1,4 +1,4 @@ -test_that("new_primary_censored_dist creates object with correct structure", { +test_that("new_primarycensored creates object with correct structure", { pdist_name <- "pgamma" pdist <- pgamma dprimary_name <- "dunif" @@ -6,7 +6,7 @@ test_that("new_primary_censored_dist creates object with correct structure", { shape <- 2 rate <- 1 - obj <- new_primary_censored_dist( + obj <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, @@ -18,7 +18,7 @@ test_that("new_primary_censored_dist creates object with correct structure", { expect_identical(obj$dprimary, dunif) expect_identical(obj$args, list(shape = shape, rate = rate)) - new_obj <- new_primary_censored_dist( + new_obj <- new_primarycensored( pgamma, dunif, list(), shape = shape, rate = rate ) @@ -26,7 +26,7 @@ test_that("new_primary_censored_dist creates object with correct structure", { }) test_that( - "primary_censored_cdf methods dispatch correctly to existing + "primarycensored_cdf methods dispatch correctly to existing analytical solutions", { pdist_name <- "pgamma" @@ -34,7 +34,7 @@ test_that( dprimary_name <- "dunif" dprimary <- dunif - obj_gamma <- new_primary_censored_dist( + obj_gamma <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, shape = 2, rate = 1 @@ -45,7 +45,7 @@ test_that( dprimary_name <- "dunif" dprimary <- dunif - obj_lnorm <- new_primary_censored_dist( + obj_lnorm <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, meanlog = 0, sdlog = 1 @@ -56,7 +56,7 @@ test_that( dprimary_name <- "dunif" dprimary <- dunif - obj_weibull <- new_primary_censored_dist( + obj_weibull <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, shape = 2, scale = 1 @@ -70,19 +70,19 @@ test_that( pwindow <- 2 expect_no_error( - primary_censored_cdf(obj_gamma, q = q_values, pwindow = pwindow) + primarycensored_cdf(obj_gamma, q = q_values, pwindow = pwindow) ) expect_no_error( - primary_censored_cdf(obj_lnorm, q = q_values, pwindow = pwindow) + primarycensored_cdf(obj_lnorm, q = q_values, pwindow = pwindow) ) expect_no_error( - primary_censored_cdf(obj_weibull, q = q_values, pwindow = pwindow) + primarycensored_cdf(obj_weibull, q = q_values, pwindow = pwindow) ) } ) test_that( - "primary_censored_cdf errors as expected when the wrong distributional + "primarycensored_cdf errors as expected when the wrong distributional parameters are supplied", { pdist_name <- "pgamma" @@ -90,83 +90,83 @@ test_that( dprimary_name <- "dunif" dprimary <- dunif - obj_gamma <- new_primary_censored_dist( + obj_gamma <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, rate = 1 ) expect_error( - primary_censored_cdf(obj_gamma, q = 1, pwindow = 1), + primarycensored_cdf(obj_gamma, q = 1, pwindow = 1), "shape parameter is required for Gamma distribution" ) - obj_gamma_no_rate <- new_primary_censored_dist( + obj_gamma_no_rate <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, shape = 2 ) expect_error( - primary_censored_cdf(obj_gamma_no_rate, q = 1, pwindow = 1), + primarycensored_cdf(obj_gamma_no_rate, q = 1, pwindow = 1), "scale or rate parameter is required for Gamma distribution" ) pdist_name <- "plnorm" pdist <- plnorm - obj_lnorm_no_meanlog <- new_primary_censored_dist( + obj_lnorm_no_meanlog <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, sdlog = 1 ) expect_error( - primary_censored_cdf(obj_lnorm_no_meanlog, q = 1, pwindow = 1), + primarycensored_cdf(obj_lnorm_no_meanlog, q = 1, pwindow = 1), "meanlog parameter is required for Log-Normal distribution" ) - obj_lnorm_no_sdlog <- new_primary_censored_dist( + obj_lnorm_no_sdlog <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, meanlog = 0 ) expect_error( - primary_censored_cdf(obj_lnorm_no_sdlog, q = 1, pwindow = 1), + primarycensored_cdf(obj_lnorm_no_sdlog, q = 1, pwindow = 1), "sdlog parameter is required for Log-Normal distribution" ) pdist_name <- "pweibull" pdist <- pweibull - obj_weibull_no_shape <- new_primary_censored_dist( + obj_weibull_no_shape <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, scale = 1 ) expect_error( - primary_censored_cdf(obj_weibull_no_shape, q = 1, pwindow = 1), + primarycensored_cdf(obj_weibull_no_shape, q = 1, pwindow = 1), "shape parameter is required for Weibull distribution" ) - obj_weibull_no_scale <- new_primary_censored_dist( + obj_weibull_no_scale <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, shape = 2 ) expect_error( - primary_censored_cdf(obj_weibull_no_scale, q = 1, pwindow = 1), + primarycensored_cdf(obj_weibull_no_scale, q = 1, pwindow = 1), "scale parameter is required for Weibull distribution" ) } ) test_that( - "primary_censored_cdf.default computes the same values as - primary_censored_cdf.pcens_pgamma_dunif", + "primarycensored_cdf.default computes the same values as + primarycensored_cdf.pcens_pgamma_dunif", { pdist_name <- "pgamma" pdist <- pgamma @@ -180,7 +180,7 @@ test_that( for (shape in shapes) { for (rate in rates) { for (pwindow in pwindows) { - obj <- new_primary_censored_dist( + obj <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, @@ -188,11 +188,11 @@ test_that( ) q_values <- seq(0, 30, by = 0.1) - result_numeric <- primary_censored_cdf( + result_numeric <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = TRUE ) - result_analytical <- primary_censored_cdf( + result_analytical <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = FALSE ) @@ -220,8 +220,8 @@ test_that( ) test_that( - "primary_censored_cdf.default computes the same values as - primary_censored_cdf.pcens_plnorm_dunif", + "primarycensored_cdf.default computes the same values as + primarycensored_cdf.pcens_plnorm_dunif", { pdist_name <- "plnorm" pdist <- plnorm @@ -235,7 +235,7 @@ test_that( for (meanlog in meanlogs) { for (sdlog in sdlogs) { for (pwindow in pwindows) { - obj <- new_primary_censored_dist( + obj <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, @@ -243,11 +243,11 @@ test_that( ) q_values <- seq(0, 30, by = 0.1) - result_numeric <- primary_censored_cdf( + result_numeric <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = TRUE ) - result_analytical <- primary_censored_cdf( + result_analytical <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = FALSE ) @@ -274,8 +274,8 @@ test_that( ) test_that( - "primary_censored_cdf.default computes the same values as - primary_censored_cdf.pcens_pweibull_dunif", + "primarycensored_cdf.default computes the same values as + primarycensored_cdf.pcens_pweibull_dunif", { pdist_name <- "pweibull" pdist <- pweibull @@ -289,7 +289,7 @@ test_that( for (shape in shapes) { for (scale in scales) { for (pwindow in pwindows) { - obj <- new_primary_censored_dist( + obj <- new_primarycensored( pdist, dprimary, list(), pdist_name, dprimary_name, @@ -297,11 +297,11 @@ test_that( ) q_values <- seq(0, 30, by = 0.1) - result_numeric <- primary_censored_cdf( + result_numeric <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = TRUE ) - result_analytical <- primary_censored_cdf( + result_analytical <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = FALSE ) diff --git a/tests/testthat/test-rpd-primarycensoreddist.R b/tests/testthat/test-rpd-primarycensored.R similarity index 93% rename from tests/testthat/test-rpd-primarycensoreddist.R rename to tests/testthat/test-rpd-primarycensored.R index b85c97d..5596154 100644 --- a/tests/testthat/test-rpd-primarycensoreddist.R +++ b/tests/testthat/test-rpd-primarycensored.R @@ -1,9 +1,9 @@ -# Test the interactions between dprimarycensoreddist, pprimarycensoreddist, +# Test the interactions between dprimarycensored, pprimarycensored, # and the random number generators for primary events test_that( - "rprimarycensoreddist is consistent with dprimarycensoreddist and - pprimarycensoreddist", + "rprimarycensored is consistent with dprimarycensored and + pprimarycensored", { # nolint n <- 10000 pwindow <- 4 @@ -40,8 +40,8 @@ test_that( test_that( - "rprimarycensoreddist is consistent with dprimarycensoreddist and - pprimarycensoreddist for exponential growth primary distribution", + "rprimarycensored is consistent with dprimarycensored and + pprimarycensored for exponential growth primary distribution", { # nolint n <- 1e6 pwindow <- 3 @@ -90,7 +90,7 @@ test_that( ) test_that( - "rprimarycensoreddist with wider windows and different delay distribution + "rprimarycensored with wider windows and different delay distribution mathches p and d numerically", { n <- 1e6 diff --git a/tests/testthat/test-rprimarycensoreddist.R b/tests/testthat/test-rprimarycensored.R similarity index 77% rename from tests/testthat/test-rprimarycensoreddist.R rename to tests/testthat/test-rprimarycensored.R index d2d8039..a6a1d63 100644 --- a/tests/testthat/test-rprimarycensoreddist.R +++ b/tests/testthat/test-rprimarycensored.R @@ -1,4 +1,4 @@ -test_that("rprimarycensoreddist generates samples within the correct range", { +test_that("rprimarycensored generates samples within the correct range", { n <- 1000 pwindow <- 5 D <- 10 @@ -10,7 +10,7 @@ test_that("rprimarycensoreddist generates samples within the correct range", { expect_true(all(samples >= 0 & samples < D)) }) -test_that("rprimarycensoreddist handles different primary distributions", { +test_that("rprimarycensored handles different primary distributions", { n <- 1000 pwindow <- 5 D <- 10 @@ -24,7 +24,7 @@ test_that("rprimarycensoreddist handles different primary distributions", { expect_true(all(samples >= 0 & samples < D)) }) -test_that("rprimarycensoreddist handles very truncated distributions", { +test_that("rprimarycensored handles very truncated distributions", { n <- 1000 pwindow <- 0.1 D <- 1 @@ -38,7 +38,7 @@ test_that("rprimarycensoreddist handles very truncated distributions", { }) test_that( - "rprimarycensoreddist supports non-secondary event censored distributions", + "rprimarycensored supports non-secondary event censored distributions", { n <- 1000 pwindow <- 5 diff --git a/tests/testthat/test-stan-primary_censored_dist_analytical_cdf.R b/tests/testthat/test-stan-primarycensored_analytical_cdf.R similarity index 82% rename from tests/testthat/test-stan-primary_censored_dist_analytical_cdf.R rename to tests/testthat/test-stan-primarycensored_analytical_cdf.R index 7698746..a9212ed 100644 --- a/tests/testthat/test-stan-primary_censored_dist_analytical_cdf.R +++ b/tests/testthat/test-stan-primarycensored_analytical_cdf.R @@ -5,7 +5,7 @@ if (on_ci()) { } test_that( - "Stan primary_censored_dist_analytical_lcdf matches R implementation for + "Stan primarycensored_analytical_lcdf matches R implementation for Gamma", { shapes <- c(0.5, 1, 2, 5) @@ -15,7 +15,7 @@ test_that( for (shape in shapes) { for (rate in rates) { for (pwindow in pwindows) { - obj <- new_primary_censored_dist( + obj <- new_primarycensored( pgamma, dunif, list(), "pgamma", "dunif", @@ -23,13 +23,13 @@ test_that( ) q_values <- seq(0, 30, by = 1) - r_result <- primary_censored_cdf( + r_result <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = FALSE ) stan_result <- vapply(q_values, function(q) { - primary_censored_dist_analytical_cdf( + primarycensored_analytical_cdf( q, 2, c(shape, rate), pwindow, Inf, 1, numeric(0) ) }, numeric(1)) @@ -50,7 +50,7 @@ test_that( ) test_that( - "Stan primary_censored_dist_analytical_lcdf matches R implementation for + "Stan primarycensored_analytical_lcdf matches R implementation for Lognormal", { meanlogs <- c(-1, 0, 1, 2) @@ -60,7 +60,7 @@ test_that( for (meanlog in meanlogs) { for (sdlog in sdlogs) { for (pwindow in pwindows) { - obj <- new_primary_censored_dist( + obj <- new_primarycensored( plnorm, dunif, list(), "plnorm", "dunif", @@ -68,13 +68,13 @@ test_that( ) q_values <- seq(0, 30, by = 1) - r_result <- primary_censored_cdf( + r_result <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = FALSE ) stan_result <- vapply(q_values, function(q) { - primary_censored_dist_analytical_cdf( + primarycensored_analytical_cdf( q, 1, c(meanlog, sdlog), pwindow, Inf, 1, numeric(0) ) }, numeric(1)) @@ -95,7 +95,7 @@ test_that( ) test_that( - "Stan primary_censored_dist_analytical_lcdf matches R implementation for + "Stan primarycensored_analytical_lcdf matches R implementation for Weibull", { shapes <- c(0.5, 1, 2, 3) @@ -105,7 +105,7 @@ test_that( for (shape in shapes) { for (scale in scales) { for (pwindow in pwindows) { - obj <- new_primary_censored_dist( + obj <- new_primarycensored( pweibull, dunif, list(), "pweibull", "dunif", @@ -113,13 +113,13 @@ test_that( ) q_values <- seq(0, 30, by = 1) - r_result <- primary_censored_cdf( + r_result <- primarycensored_cdf( obj, q = q_values, pwindow = pwindow, use_numeric = FALSE ) stan_result <- vapply(q_values, function(q) { - primary_censored_dist_analytical_cdf( + primarycensored_analytical_cdf( q, 3, c(shape, scale), pwindow, Inf, 1, numeric(0) ) }, numeric(1)) diff --git a/tests/testthat/test-stan-primary_censored_ode.R b/tests/testthat/test-stan-primarycensored_ode.R similarity index 68% rename from tests/testthat/test-stan-primary_censored_ode.R rename to tests/testthat/test-stan-primarycensored_ode.R index d540839..bb41329 100644 --- a/tests/testthat/test-stan-primary_censored_ode.R +++ b/tests/testthat/test-stan-primarycensored_ode.R @@ -5,15 +5,15 @@ if (on_ci()) { } -test_that("Stan primary_censored_ode produces expected output", { +test_that("Stan primarycensored_ode produces expected output", { t <- 4.5 y <- 0.5 theta <- c(1.0, 0.5) # Example parameters for lognormal distribution x_r <- c(5.0, 1.0) # d and pwindow - # dist_id, primary_dist_id, dist_params_len, primary_params_len + # dist_id, primray_id, dist_params_len, primary_params_len x_i <- c(1, 1, 2, 0) - result <- primary_censored_ode(t, y, theta, x_r, x_i) + result <- primarycensored_ode(t, y, theta, x_r, x_i) expect_type(result, "double") expect_length(result, 1) @@ -22,36 +22,36 @@ test_that("Stan primary_censored_ode produces expected output", { expect_gt(result[1], 0) }) -test_that("Stan primary_censored_ode handles edge cases", { +test_that("Stan primarycensored_ode handles edge cases", { theta <- c(1.0, 0.5) # Example parameters for lognormal distribution x_r <- c(1.0, 1.0) # d and pwindow - # dist_id, primary_dist_id, dist_params_len, primary_params_len + # dist_id, primray_id, dist_params_len, primary_params_len x_i <- c(1, 1, 2, 0) - result_near_zero <- primary_censored_ode(1e-10, 1e-10, theta, x_r, x_i) + result_near_zero <- primarycensored_ode(1e-10, 1e-10, theta, x_r, x_i) expect_true(is.finite(result_near_zero[1])) - result_at_d <- primary_censored_ode(1, 0.0, theta, x_r, x_i) + result_at_d <- primarycensored_ode(1, 0.0, theta, x_r, x_i) expect_true(is.finite(result_at_d[1])) expect_gt(result_at_d[1], result_near_zero[1]) - result_near_d <- primary_censored_ode( + result_near_d <- primarycensored_ode( 0.99999, 0.00001, theta, x_r, x_i ) expect_true(is.finite(result_near_d[1])) expect_gt(result_at_d[1], result_near_d[1]) }) -test_that("Stan primary_censored_ode is continuous", { +test_that("Stan primarycensored_ode is continuous", { theta <- c(1.5, 0.75) # Example parameters for lognormal distribution x_r <- c(5.0, 5.0) # d and pwindow - # dist_id, primary_dist_id, dist_params_len, primary_params_len + # dist_id, primray_id, dist_params_len, primary_params_len x_i <- c(1, 1, 2, 0) t_values <- seq(0.1, 4.9, by = 0.1) results <- vapply( t_values, - function(t) primary_censored_ode(t, 0.1, theta, x_r, x_i)[1], + function(t) primarycensored_ode(t, 0.1, theta, x_r, x_i)[1], numeric(1) ) @@ -60,7 +60,7 @@ test_that("Stan primary_censored_ode is continuous", { expect_lt(max(abs(diffs)), 1e-2) }) -test_that("Stan primary_censored_ode handles different distributions", { +test_that("Stan primarycensored_ode handles different distributions", { t <- 4.5 y <- 0.5 x_r <- c(5.0, 1.0) # d and pwindow @@ -68,7 +68,7 @@ test_that("Stan primary_censored_ode handles different distributions", { # Test for lognormal distribution theta_lognormal <- c(1.0, 0.5) x_i_lognormal <- c(1, 1, 2, 0) - result_lognormal <- primary_censored_ode( + result_lognormal <- primarycensored_ode( t, y, theta_lognormal, x_r, x_i_lognormal ) expect_true(is.finite(result_lognormal[1])) @@ -76,7 +76,7 @@ test_that("Stan primary_censored_ode handles different distributions", { # Test for gamma distribution theta_gamma <- c(2.0, 1.0) x_i_gamma <- c(2, 1, 2, 0) - result_gamma <- primary_censored_ode( + result_gamma <- primarycensored_ode( t, y, theta_gamma, x_r, x_i_gamma ) expect_true(is.finite(result_gamma[1])) @@ -84,28 +84,28 @@ test_that("Stan primary_censored_ode handles different distributions", { # Test for weibull distribution theta_weibull <- c(1.5, 2.0) x_i_weibull <- c(5, 1, 2, 0) - result_weibull <- primary_censored_ode( + result_weibull <- primarycensored_ode( t, y, theta_weibull, x_r, x_i_weibull ) expect_true(is.finite(result_weibull[1])) }) -test_that("Stan primary_censored_ode handles extreme parameter values", { +test_that("Stan primarycensored_ode handles extreme parameter values", { t <- 4.5 y <- 0.5 x_r <- c(5.0, 1.0) # d and pwindow - # dist_id, primary_dist_id, dist_params_len, primary_params_len + # dist_id, primray_id, dist_params_len, primary_params_len x_i <- c(1, 1, 2, 0) # Test with very small scale parameter theta_small_scale <- c(1.0, 1e-10) - result_small_scale <- primary_censored_ode( + result_small_scale <- primarycensored_ode( t, y, theta_small_scale, x_r, x_i ) expect_true(is.finite(result_small_scale[1])) # Test with very large scale parameter theta_large_scale <- c(1.0, 1e10) - result_large_scale <- primary_censored_ode( + result_large_scale <- primarycensored_ode( t, y, theta_large_scale, x_r, x_i ) expect_true(is.finite(result_large_scale[1])) @@ -113,14 +113,14 @@ test_that("Stan primary_censored_ode handles extreme parameter values", { # Test with very small shape parameter (for distributions that use it) x_i_weibull <- c(5, 1, 2, 0) theta_small_shape <- c(1e-10, 1.0) - result_small_shape <- primary_censored_ode( + result_small_shape <- primarycensored_ode( t, y, theta_small_shape, x_r, x_i_weibull ) expect_true(is.finite(result_small_shape[1])) # Test with very large shape parameter theta_large_shape <- c(1e10, 1.0) - result_large_shape <- primary_censored_ode( + result_large_shape <- primarycensored_ode( t, y, theta_large_shape, x_r, x_i_weibull ) expect_true(is.finite(result_large_shape[1])) diff --git a/tests/testthat/test-stan-rpd-primarycensoreddist.R b/tests/testthat/test-stan-rpd-primarycensored.R similarity index 66% rename from tests/testthat/test-stan-rpd-primarycensoreddist.R rename to tests/testthat/test-stan-rpd-primarycensored.R index 600ed75..2d92e54 100644 --- a/tests/testthat/test-stan-rpd-primarycensoreddist.R +++ b/tests/testthat/test-stan-rpd-primarycensored.R @@ -5,7 +5,7 @@ if (on_ci()) { } -test_that("Stan primary_censored_dist_cdf matches R pprimarycensoreddist", { +test_that("Stan primarycensored_cdf matches R pprimarycensored", { d_values <- list( seq(0, 10, by = 0.5), seq(0, 5, by = 0.25), @@ -18,14 +18,14 @@ test_that("Stan primary_censored_dist_cdf matches R pprimarycensoreddist", { dist_id <- 1 # Lognormal params <- c(0, 1) # meanlog, sdlog pwindow <- 1 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- array(numeric(0)) stan_cdf <- sapply( - d, primary_censored_dist_cdf, dist_id, params, pwindow, D, - primary_dist_id, primary_params + d, primarycensored_cdf, dist_id, params, pwindow, D, + primray_id, primary_params ) - r_cdf <- pprimarycensoreddist( + r_cdf <- pprimarycensored( d, plnorm, pwindow = pwindow, D = D, meanlog = params[1], sdlog = params[2] ) @@ -43,7 +43,7 @@ test_that("Stan primary_censored_dist_cdf matches R pprimarycensoreddist", { }) test_that( - "Stan primary_censored_dist_lcdf matches R pprimarycensoreddist with + "Stan primarycensored_lcdf matches R pprimarycensored with log.p = TRUE", { d <- seq(0, 10, by = 0.5) @@ -51,14 +51,14 @@ test_that( params <- c(0, 1) # meanlog, sdlog pwindow <- 1 D <- 12 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) stan_lcdf <- sapply( - d, primary_censored_dist_lcdf, dist_id, params, pwindow, D, - primary_dist_id, primary_params + d, primarycensored_lcdf, dist_id, params, pwindow, D, + primray_id, primary_params ) - r_cdf <- pprimarycensoreddist( + r_cdf <- pprimarycensored( d, plnorm, pwindow = pwindow, D = D, meanlog = params[1], sdlog = params[2] @@ -71,14 +71,14 @@ test_that( params <- c(2, 1) # shape, scale pwindow <- 2 D <- 12 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) stan_lcdf <- sapply( - d, primary_censored_dist_lcdf, dist_id, params, pwindow, D, - primary_dist_id, primary_params + d, primarycensored_lcdf, dist_id, params, pwindow, D, + primray_id, primary_params ) - r_cdf <- pprimarycensoreddist( + r_cdf <- pprimarycensored( d, pgamma, pwindow = pwindow, D = D, shape = params[1], scale = params[2] ) @@ -88,7 +88,7 @@ test_that( ) test_that( - "Stan primary_censored_dist_lpmf throws an error for invalid upper truncation + "Stan primarycensored_lpmf throws an error for invalid upper truncation point", { d <- 10 @@ -97,12 +97,12 @@ test_that( pwindow <- 1 d_upper <- 11 D <- 10 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) expect_error( - primary_censored_dist_lpmf( - d, dist_id, params, pwindow, d_upper, D, primary_dist_id, primary_params + primarycensored_lpmf( + d, dist_id, params, pwindow, d_upper, D, primray_id, primary_params ), "Upper truncation point is greater than D" ) @@ -110,13 +110,13 @@ test_that( ) test_that( - "Stan primary_censored_dist matches R primarycensoreddist when d is the same + "Stan primarycensored matches R primarycensored when d is the same as D - 1", { dist_id <- 1 # Lognormal params <- c(0, 1) # meanlog, sdlog pwindow <- 1 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) d_values <- 1:10 @@ -129,11 +129,11 @@ test_that( "with truncation" } for (d in d_values) { - stan_pmf <- primary_censored_dist_pmf( - d, dist_id, params, pwindow, d + 1, D, primary_dist_id, + stan_pmf <- primarycensored_pmf( + d, dist_id, params, pwindow, d + 1, D, primray_id, primary_params ) - r_pmf <- dprimarycensoreddist( + r_pmf <- dprimarycensored( d, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2] @@ -153,18 +153,18 @@ test_that( } ) -test_that("Stan primary_censored_dist_pmf matches R dprimarycensoreddist", { +test_that("Stan primarycensored_pmf matches R dprimarycensored", { d <- 0:10 dist_id <- 1 # Lognormal params <- c(0, 1) # meanlog, sdlog pwindow <- 1 d_upper <- d + 1 D <- Inf - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) stan_pmf <- mapply( - primary_censored_dist_pmf, + primarycensored_pmf, d = d, d_upper = d + 1, MoreArgs = list( @@ -172,11 +172,11 @@ test_that("Stan primary_censored_dist_pmf matches R dprimarycensoreddist", { params = params, pwindow = pwindow, D = D, - primary_dist_id = primary_dist_id, + primray_id = primray_id, primary_params = primary_params ) ) - r_pmf <- dprimarycensoreddist( + r_pmf <- dprimarycensored( d, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2] @@ -186,7 +186,7 @@ test_that("Stan primary_censored_dist_pmf matches R dprimarycensoreddist", { }) test_that( - "Stan primary_censored_dist_lpmf matches R dprimarycensoreddist with + "Stan primarycensored_lpmf matches R dprimarycensored with log = TRUE", { d <- 0:10 @@ -195,11 +195,11 @@ test_that( pwindow <- 1 d_upper <- d + 1 D <- Inf - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) stan_lpmf <- mapply( - primary_censored_dist_lpmf, + primarycensored_lpmf, d = d, d_upper = d_upper, MoreArgs = list( @@ -207,12 +207,12 @@ test_that( params = params, pwindow = pwindow, D = D, - primary_dist_id = primary_dist_id, + primray_id = primray_id, primary_params = primary_params ) ) r_lpmf <- log( - dprimarycensoreddist( + dprimarycensored( d, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2] @@ -224,20 +224,20 @@ test_that( ) test_that( - "Stan primary_censored_sone_pmf_vectorized matches R dprimarycensoreddist", + "Stan primarycensored_sone_lpmf_vectorized matches R dprimarycensored", { max_delay <- 10 dist_id <- 1 # Lognormal params <- c(0, 1) # meanlog, sdlog pwindow <- 1 D <- Inf - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) - stan_pmf <- primary_censored_sone_pmf_vectorized( - max_delay, D, dist_id, params, pwindow, primary_dist_id, primary_params + stan_pmf <- primarycensored_sone_lpmf_vectorized( + max_delay, D, dist_id, params, pwindow, primray_id, primary_params ) - r_pmf <- dprimarycensoreddist( + r_pmf <- dprimarycensored( 0:max_delay, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2] @@ -248,7 +248,7 @@ test_that( ) test_that( - "Stan primary_censored_sone_pmf_vectorized matches R dprimarycensoreddist + "Stan primarycensored_sone_lpmf_vectorized matches R dprimarycensored with finite D", { max_delay <- 10 @@ -256,13 +256,13 @@ test_that( params <- c(0, 1) # meanlog, sdlog pwindow <- 1 D <- 15 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) - stan_pmf <- primary_censored_sone_pmf_vectorized( - max_delay, D, dist_id, params, pwindow, primary_dist_id, primary_params + stan_pmf <- primarycensored_sone_lpmf_vectorized( + max_delay, D, dist_id, params, pwindow, primray_id, primary_params ) - r_pmf <- dprimarycensoreddist( + r_pmf <- dprimarycensored( 0:max_delay, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2] @@ -273,7 +273,7 @@ test_that( ) test_that( - "Stan primary_censored_sone_pmf_vectorized matches R dprimarycensoreddist + "Stan primarycensored_sone_lpmf_vectorized matches R dprimarycensored with D equal to max_delay + 1", { max_delay <- 10 @@ -281,13 +281,13 @@ test_that( params <- c(0, 1) # meanlog, sdlog pwindow <- 1 D <- max_delay + 1 - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) - stan_pmf <- primary_censored_sone_pmf_vectorized( - max_delay, D, dist_id, params, pwindow, primary_dist_id, primary_params + stan_pmf <- primarycensored_sone_lpmf_vectorized( + max_delay, D, dist_id, params, pwindow, primray_id, primary_params ) - r_pmf <- dprimarycensoreddist( + r_pmf <- dprimarycensored( 0:max_delay, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2] @@ -298,7 +298,7 @@ test_that( ) test_that( - "Stan primary_censored_sone_lpmf_vectorized matches R dprimarycensoreddist + "Stan primarycensored_sone_lpmf_vectorized matches R dprimarycensored with log = TRUE", { max_delay <- 10 @@ -306,13 +306,13 @@ test_that( params <- c(0, 1) # meanlog, sdlog pwindow <- 1 D <- Inf - primary_dist_id <- 1 # Uniform + primray_id <- 1 # Uniform primary_params <- numeric(0) - stan_lpmf <- primary_censored_sone_lpmf_vectorized( - max_delay, D, dist_id, params, pwindow, primary_dist_id, primary_params + stan_lpmf <- primarycensored_sone_lpmf_vectorized( + max_delay, D, dist_id, params, pwindow, primray_id, primary_params ) - r_lpmf <- dprimarycensoreddist( + r_lpmf <- dprimarycensored( 0:max_delay, plnorm, pwindow = pwindow, swindow = 1, D = D, meanlog = params[1], sdlog = params[2], log = TRUE diff --git a/touchstone/script.R b/touchstone/script.R index 61d3d0d..d56278a 100644 --- a/touchstone/script.R +++ b/touchstone/script.R @@ -4,26 +4,26 @@ # installs branches to benchmark touchstone::branch_install() -# Benchmark for pprimarycensoreddist with lognormal distribution +# Benchmark for pprimarycensored with lognormal distribution touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) q <- seq(0, 10, by = 0.01) }, - pprimarycensoreddist_lnorm = { - pprimarycensoreddist(q, plnorm, meanlog = 0, sdlog = 1, D = 12) + pprimarycensored_lnorm = { + pprimarycensored(q, plnorm, meanlog = 0, sdlog = 1, D = 12) }, n = 20 ) -# Benchmark for pprimarycensoreddist with exponential growth +# Benchmark for pprimarycensored with exponential growth touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) q <- seq(0, 10, by = 0.01) }, - pprimarycensoreddist_plnrom_expgrowth = { - pprimarycensoreddist( + pprimarycensored_plnrom_expgrowth = { + pprimarycensored( q, plnorm, dprimary = dexpgrowth, dprimary_args = list(r = 0.2), @@ -33,26 +33,26 @@ touchstone::benchmark_run( n = 20 ) -# Benchmark for dprimarycensoreddist with Weibull distribution +# Benchmark for dprimarycensored with Weibull distribution touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) x <- seq(0, 10, by = 1) }, - dprimarycensoreddist_weibull = { - dprimarycensoreddist(x, pweibull, shape = 1.5, scale = 2.0, D = 12) + dprimarycensored_weibull = { + dprimarycensored(x, pweibull, shape = 1.5, scale = 2.0, D = 12) }, n = 20 ) -# Benchmark for dprimarycensoreddist with exponential growth +# Benchmark for dprimarycensored with exponential growth touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) x <- seq(0, 10, by = 1) }, - dprimarycensoreddist_pweibull_expgrowth = { - dprimarycensoreddist( + dprimarycensored_pweibull_expgrowth = { + dprimarycensored( x, pweibull, dprimary = dexpgrowth, dprimary_args = list(r = 0.2), @@ -65,7 +65,7 @@ touchstone::benchmark_run( # Benchmark for fitdistdoublecens with normal distribution touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) library(fitdistrplus) set.seed(123) n <- 1000 @@ -74,7 +74,7 @@ touchstone::benchmark_run( pwindow <- 1 swindow <- 1 D <- 10 - samples <- rprimarycensoreddist( + samples <- rprimarycensored( n, rnorm, mean = true_mean, sd = true_sd, pwindow = pwindow, swindow = swindow, D = D @@ -99,7 +99,7 @@ touchstone::benchmark_run( # Benchmark for fitdistdoublecens with exponential growth touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) library(fitdistrplus) set.seed(456) n <- 1000 @@ -108,7 +108,7 @@ touchstone::benchmark_run( pwindow <- 1 swindow <- 1 D <- 8 - samples <- rprimarycensoreddist( + samples <- rprimarycensored( n, rgamma, shape = true_shape, rate = true_rate, pwindow = pwindow, swindow = swindow, D = D, @@ -133,7 +133,7 @@ touchstone::benchmark_run( # Benchmark for fitting lognormal distribution touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) library(dplyr) library(cmdstanr) @@ -145,7 +145,7 @@ touchstone::benchmark_run( true_meanlog1 <- 1.5 true_sdlog1 <- 0.5 - simulated_delays1 <- rprimarycensoreddist( + simulated_delays1 <- rprimarycensored( n = n1, rdist = rlnorm, meanlog = true_meanlog1, @@ -170,7 +170,7 @@ touchstone::benchmark_run( stan_data1 <- pcd_as_stan_data( delay_counts1, dist_id = 1, - primary_dist_id = 1, + primray_id = 1, param_bounds = list(lower = c(-Inf, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(0, 1), scale = c(1, 1)), @@ -197,7 +197,7 @@ touchstone::benchmark_run( # Benchmark for fitting gamma distribution touchstone::benchmark_run( expr_before_benchmark = { - library(primarycensoreddist) + library(primarycensored) library(dplyr) library(cmdstanr) @@ -209,7 +209,7 @@ touchstone::benchmark_run( true_shape2 <- 2 true_rate2 <- 0.5 - simulated_delays2 <- rprimarycensoreddist( + simulated_delays2 <- rprimarycensored( n = n2, rdist = rgamma, shape = true_shape2, @@ -237,7 +237,7 @@ touchstone::benchmark_run( stan_data2 <- pcd_as_stan_data( delay_counts2, dist_id = 2, - primary_dist_id = 2, + primray_id = 2, param_bounds = list(lower = c(0, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = 0, upper = Inf), priors = list(location = c(2, 1), scale = c(0.5, 0.5)), diff --git a/vignettes/analytic-solutions.Rmd b/vignettes/analytic-solutions.Rmd index efbae01..615d57d 100644 --- a/vignettes/analytic-solutions.Rmd +++ b/vignettes/analytic-solutions.Rmd @@ -273,6 +273,6 @@ Which was also found by Cori _et al_ [@cori2013new]. # Learning more - For more mathematical background on the analytic solutions see the `vignette("why-it-works")`. -- For a more introductory explanation of the primary event censored distribution see the `vignette("primarycensoreddist")`. +- For a more introductory explanation of the primary event censored distribution see the `vignette("primarycensored")`. # References diff --git a/vignettes/chunks/_readme-install-primarycensoreddist.Rmd b/vignettes/chunks/_readme-install-primarycensoreddist.Rmd index e91684a..1abb53f 100644 --- a/vignettes/chunks/_readme-install-primarycensoreddist.Rmd +++ b/vignettes/chunks/_readme-install-primarycensoreddist.Rmd @@ -2,7 +2,7 @@ You can install the latest released version using the normal `R` function, thoug ```{r, eval = FALSE} install.packages( - "primarycensoreddist", + "primarycensored", repos = "https://epinowcast.r-universe.dev" ) ``` @@ -11,16 +11,16 @@ Alternatively, you can use the [`remotes` package](https://remotes.r-lib.org/) t ```{r, eval = FALSE} remotes::install_github( - "epinowcast/primarycensoreddist", + "epinowcast/primarycensored", dependencies = TRUE ) ``` -Similarly, you can install historical versions by specifying the release tag (e.g. this installs [`0.2.0`](https://github.com/epinowcast/primarycensoreddist/releases/tag/v0.2.0)): +Similarly, you can install historical versions by specifying the release tag (e.g. this installs [`0.2.0`](https://github.com/epinowcast/primarycensored/releases/tag/v0.2.0)): ```{r, eval = FALSE} remotes::install_github( - "epinowcast/primarycensoreddist", + "epinowcast/primarycensored", dependencies = TRUE, ref = "v0.2.0" ) ``` diff --git a/vignettes/fitting-dists-with-fitdistrplus.Rmd b/vignettes/fitting-dists-with-fitdistrplus.Rmd index 0e2ee60..c9ae29f 100644 --- a/vignettes/fitting-dists-with-fitdistrplus.Rmd +++ b/vignettes/fitting-dists-with-fitdistrplus.Rmd @@ -1,6 +1,6 @@ --- title: "Fitting distributions using primarycensorseddist and fitdistrplus" -description: "A guide on how to fit distributions using primarycensoreddist and fitdistrplus." +description: "A guide on how to fit distributions using primarycensored and fitdistrplus." author: Sam Abbott output: bookdown::html_document2: @@ -12,7 +12,7 @@ bibliography: library.bib csl: https://raw.githubusercontent.com/citation-style-language/styles/master/apa-numeric-superscript-brackets.csl link-citations: true vignette: > - %\VignetteIndexEntry{Fitting distributions using primarycensoreddist and fitdistrplus} + %\VignetteIndexEntry{Fitting distributions using primarycensored and fitdistrplus} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -21,13 +21,13 @@ vignette: > ## What are we going to do in this Vignette -In this vignette, we'll demonstrate how to use `primarycensoreddist` in conjunction with `fitdistrplus` for fitting distributions. We'll cover the following key points: +In this vignette, we'll demonstrate how to use `primarycensored` in conjunction with `fitdistrplus` for fitting distributions. We'll cover the following key points: 1. Simulating censored delay distribution data 2. Fitting a naive model using `fitdistrplus` 3. Evaluating the naive model's performance -4. Fitting an improved model using `primarycensoreddist` functionality -5. Comparing the `primarycensoreddist` model's performance to the naive model +4. Fitting an improved model using `primarycensored` functionality +5. Comparing the `primarycensored` model's performance to the naive model ## What might I need to know before starting @@ -35,10 +35,10 @@ This vignette assumes some familiarity with the `fitdistrplus` package. If you a ## Packages used in this vignette -Alongside the `primarycensoreddist` package we will use the `fitdistrplus` package for fitting distributions. We will also use the `ggplot2` package for plotting and `dplyr` for data manipulation. +Alongside the `primarycensored` package we will use the `fitdistrplus` package for fitting distributions. We will also use the `ggplot2` package for plotting and `dplyr` for data manipulation. ```{r setup, message = FALSE} -library(primarycensoreddist) +library(primarycensored) library(fitdistrplus) library(ggplot2) library(dplyr) @@ -46,7 +46,7 @@ library(dplyr) # Simulating censored and truncated delay distribution data -We'll start by simulating some censored and truncated delay distribution data. We'll use the `rprimarycensoreddist` function (actually we will use the `rpcens ` alias for brevity). +We'll start by simulating some censored and truncated delay distribution data. We'll use the `rprimarycensored` function (actually we will use the `rpcens ` alias for brevity). ```{r sample-lognormal} set.seed(123) # For reproducibility @@ -149,17 +149,17 @@ summary(fit) We see that the naive model has fit poorly due to the primary censoring and right truncation in the data. -# Fitting an improved model using `primarycensoreddist` and `fitdistrplus` +# Fitting an improved model using `primarycensored` and `fitdistrplus` -We'll now fit an improved model using the `primarycensoreddist` package. To do this we need to define the custom distribution functions using the `primarycensoreddist` package that are required by `fitdistrplus`. Rather than using `fitdistcens` we use `fitdist` because our functions are handling the censoring themselves. +We'll now fit an improved model using the `primarycensored` package. To do this we need to define the custom distribution functions using the `primarycensored` package that are required by `fitdistrplus`. Rather than using `fitdistcens` we use `fitdist` because our functions are handling the censoring themselves. ```{r fit-improved-model} -# Define custom distribution functions using primarycensoreddist +# Define custom distribution functions using primarycensored # The try catch is required by fitdistrplus dpcens_gamma <- function(x, shape, rate) { result <- tryCatch( { - dprimarycensoreddist( + dprimarycensored( x, pgamma, shape = shape, rate = rate, pwindow = 1, swindow = 1, D = 8 @@ -175,7 +175,7 @@ dpcens_gamma <- function(x, shape, rate) { ppcens_gamma <- function(q, shape, rate) { result <- tryCatch( { - pprimarycensoreddist( + pprimarycensored( q, pgamma, shape = shape, rate = rate, pwindow = 1, D = 8 @@ -200,9 +200,9 @@ summary(pcens_fit) We see very good agreement between the true and estimated parameters. -Rather than using `fitdist()` directly `primarycensoreddist` provides a wrapper function `fitdistdoublecens()` that can be used to estimate double censored and truncated data. A bonus of this approach is we can specify our data using the `fitdistcens` `left` and `right` formulation and support mixed secondary censoring intervals. +Rather than using `fitdist()` directly `primarycensored` provides a wrapper function `fitdistdoublecens()` that can be used to estimate double censored and truncated data. A bonus of this approach is we can specify our data using the `fitdistcens` `left` and `right` formulation and support mixed secondary censoring intervals. -```{r primarycensoreddist-fitdistdoublecens} +```{r primarycensored-fitdistdoublecens} fitdistdoublecens_fit <- delay_data |> dplyr::select(left = observed_delay, right = observed_delay_upper) |> fitdistdoublecens( @@ -215,4 +215,4 @@ summary(fitdistdoublecens_fit) ``` -**Note** Currently this functionality is limited to a single pwindow, and observation time for all data. If this functionality is of interest then please open an issue on the `primarycensoreddist` GitHub page. +**Note** Currently this functionality is limited to a single pwindow, and observation time for all data. If this functionality is of interest then please open an issue on the `primarycensored` GitHub page. diff --git a/vignettes/fitting-dists-with-stan.Rmd b/vignettes/fitting-dists-with-stan.Rmd index eaee40d..f3698bb 100644 --- a/vignettes/fitting-dists-with-stan.Rmd +++ b/vignettes/fitting-dists-with-stan.Rmd @@ -1,6 +1,6 @@ --- title: "Fitting distributions using primarycensorseddist and cmdstan" -description: "A guide on how to use primarycensoreddist with Stan for Bayesian inference of epidemiological delay distributions." +description: "A guide on how to use primarycensored with Stan for Bayesian inference of epidemiological delay distributions." author: Sam Abbott output: bookdown::html_document2: @@ -21,24 +21,24 @@ vignette: > ## What are we going to do in this Vignette -In this vignette, we'll demonstrate how to use `primarycensoreddist` in conjunction with Stan for Bayesian inference of epidemiological delay distributions. We'll cover the following key points: +In this vignette, we'll demonstrate how to use `primarycensored` in conjunction with Stan for Bayesian inference of epidemiological delay distributions. We'll cover the following key points: 1. Simulating censored delay distribution data 2. Fitting a naive model using cmdstan 3. Evaluating the naive model's performance -4. Fitting an improved model using `primarycensoreddist` functionality -5. Comparing the `primarycensoreddist` model's performance to the naive model +4. Fitting an improved model using `primarycensored` functionality +5. Comparing the `primarycensored` model's performance to the naive model ## What might I need to know before starting -This vignette builds on the concepts introduced in the [Getting Started with primarycensoreddist](primarycensoreddist.html) vignette and assumes familiarity with using Stan tools as covered in the [How to use primarycensoreddist with Stan](using-stan-tools.html) vignette. +This vignette builds on the concepts introduced in the [Getting Started with primarycensored](primarycensored.html) vignette and assumes familiarity with using Stan tools as covered in the [How to use primarycensored with Stan](using-stan-tools.html) vignette. ## Packages used in this vignette -Alongside the `primarycensoreddist` package we will use the `cmdstanr` package for interfacing with cmdstan. We will also use the `ggplot2` package for plotting and `dplyr` for data manipulation. +Alongside the `primarycensored` package we will use the `cmdstanr` package for interfacing with cmdstan. We will also use the `ggplot2` package for plotting and `dplyr` for data manipulation. ```{r setup, message = FALSE} -library(primarycensoreddist) +library(primarycensored) library(cmdstanr) library(ggplot2) library(dplyr) @@ -46,7 +46,7 @@ library(dplyr) # Simulating censored and truncated delay distribution data -We'll start by simulating some censored and truncated delay distribution data. We'll use the `rprimarycensoreddist` function (actually we will use the `rpcens ` alias for brevity). +We'll start by simulating some censored and truncated delay distribution data. We'll use the `rprimarycensored` function (actually we will use the `rpcens ` alias for brevity). ```{r sample-lognormal} set.seed(123) # For reproducibility @@ -147,7 +147,7 @@ We've aggregated the data to unique combinations of `pwindow`, `swindow`, and `o # Fitting a naive model using cmdstan -We'll start by fitting a naive model using cmdstan. We'll use the `cmdstanr` package to interface with cmdstan. We define the model in a string and then write it to a file as in the [How to use primarycensoreddist with Stan](using-stan-tools.html) vignette. +We'll start by fitting a naive model using cmdstan. We'll use the `cmdstanr` package to interface with cmdstan. We define the model in a string and then write it to a file as in the [How to use primarycensored with Stan](using-stan-tools.html) vignette. ```{r naive-model} writeLines( @@ -198,16 +198,18 @@ naive_fit We see that the model has converged and the diagnostics look good. However, just from the model posterior summary we see that we might not be very happy with the fit. `mu` is smaller than the target `r meanlog` and `sigma` is larger than the target `r sdlog`. -# Fitting an improved model using primarycensoreddist +# Fitting an improved model using primarycensored -We'll now fit an improved model using the `primarycensoreddist` package. The main improvement is that we will use the `primary_censored_dist_lpdf` function to fit the model. This is the Stan version of the `pcens()` function and accounts for the primary and secondary censoring windows as well as the truncation. We encode that our primary distribution is a lognormal distribution by passing 1 as the `dist_id` parameter and that our primary event distribution is uniform by passing 1 as the `primary_dist_id` parameter. See the [Stan documentation](https://primarycensoreddist.epinowcast.org/stan/primary__censored__dist_8stan.html#acc97240dee1bc19e4f02013118f3857d) for more details on the `primary_censored_dist_lpdf` function. +We'll now fit an improved model using the `primarycensored` package. The main improvement is that we will use the `primarycensored_lpdf` function to fit the model. This is the Stan version of the `pcens()` function and accounts for the primary and secondary censoring windows as well as the truncation. We encode that our primary distribution is a lognormal distribution by passing 1 as the `dist_id` parameter and that our primary event distribution is uniform by passing 1 as the `primray_id` parameter. See the [Stan documentation](https://primarycensored.epinowcast.org/stan/primary__censored__dist_8stan.html#acc97240dee1bc19e4f02013118f3857d) for more details on the `primarycensored_lpdf` function. ```{r pimarycensoreddist-model} writeLines( " functions { - #include primary_censored_dist.stan - #include primary_censored_dist_analytical_cdf.stan + #include primarycensored.stan + // These functions are required for the primarycensored_lpdf function + #include primarycensored_ode.stan + #include primarycensored_analytical_cdf.stan #include expgrowth.stan } data { @@ -232,30 +234,30 @@ writeLines( // Likelihood for (i in 1:N) { - target += n[i] * primary_censored_dist_lpmf( + target += n[i] * primarycensored_lpmf( y[i] | 1, {mu, sigma}, pwindow[i], y_upper[i], D[i], 1, primary_params ); } }", - con = file.path(tempdir(), "primarycensoreddist_lognormal.stan") + con = file.path(tempdir(), "primarycensored_lognormal.stan") ) ``` Now let's compile the model -```{r compile-primarycensoreddist-model, message = FALSE} -primarycensoreddist_model <- cmdstan_model( - file.path(tempdir(), "primarycensoreddist_lognormal.stan"), +```{r compile-primarycensored-model, message = FALSE} +primarycensored_model <- cmdstan_model( + file.path(tempdir(), "primarycensored_lognormal.stan"), include_paths = pcd_stan_path() ) ``` Now let's fit the compiled model. -```{r fit-primarycensoreddist-model, message = FALSE} -primarycensoreddist_fit <- primarycensoreddist_model$sample( +```{r fit-primarycensored-model, message = FALSE} +primarycensored_fit <- primarycensored_model$sample( data = list( y = delay_counts$observed_delay, y_upper = delay_counts$observed_delay_upper, @@ -269,7 +271,7 @@ primarycensoreddist_fit <- primarycensoreddist_model$sample( refresh = ifelse(interactive(), 50, 0), show_messages = interactive() ) -primarycensoreddist_fit +primarycensored_fit ``` We see that the model has converged and the diagnostics look good. We also see that the posterior means are very near the true parameters and the 90% credible intervals include the true parameters. @@ -277,7 +279,7 @@ We see that the model has converged and the diagnostics look good. We also see t # Using `pcd_cmdstan_model()` for a more efficient approach -While the previous approach works well, `primarycensoreddist` provides a more efficient and convenient model which we can compile using `pcd_cmdstan_model()`. This approach not only saves time in model specification but also leverages within chain parallelisation to make best use of your machine's resources. Alongside this we also supply a convenience function `pcd_as_stan_data()` to convert our data into a format that can be used to fit the model and supply priors, bounds, and other settings. +While the previous approach works well, `primarycensored` provides a more efficient and convenient model which we can compile using `pcd_cmdstan_model()`. This approach not only saves time in model specification but also leverages within chain parallelisation to make best use of your machine's resources. Alongside this we also supply a convenience function `pcd_as_stan_data()` to convert our data into a format that can be used to fit the model and supply priors, bounds, and other settings. Let's use this function to fit our data: @@ -291,7 +293,7 @@ pcd_data <- pcd_as_stan_data( delay_upper = "observed_delay_upper", relative_obs_time = "obs_time", dist_id = 1, # Lognormal distribution - primary_dist_id = 1, # Uniform primary distribution + primray_id = 1, # Uniform primary distribution param_bounds = list(lower = c(-Inf, 0), upper = c(Inf, Inf)), primary_param_bounds = list(lower = numeric(0), upper = numeric(0)), priors = list(location = c(1, 0.5), scale = c(1, 0.5)), diff --git a/vignettes/primarycensoreddist.Rmd b/vignettes/primarycensoreddist.Rmd index a2ca97a..4804ac4 100644 --- a/vignettes/primarycensoreddist.Rmd +++ b/vignettes/primarycensoreddist.Rmd @@ -1,6 +1,6 @@ --- -title: "Getting Started with primarycensoreddist" -description: "A quick start example demonstrating use of primarycensoreddist." +title: "Getting Started with primarycensored" +description: "A quick start example demonstrating use of primarycensored." author: Sam Abbott output: bookdown::html_document2: @@ -12,7 +12,7 @@ bibliography: library.bib csl: https://raw.githubusercontent.com/citation-style-language/styles/master/apa-numeric-superscript-brackets.csl link-citations: true vignette: > - %\VignetteIndexEntry{Getting Started with primarycensoreddist} + %\VignetteIndexEntry{Getting Started with primarycensored} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -29,23 +29,23 @@ The estimation of delay distributions often faces the following challenges: - **Secondary event censoring**: The secondary event (e.g., symptom onset or the end of a process) is also frequently observed with interval censoring. This additional layer of censoring further complicates the estimation of the delay distribution. -The `primarycensoreddist` package aims to address these challenges by providing tools to manipulate primary censored delay distributions. By accounting for the censoring and truncation present in the data, the package enables more accurate estimation and use of the underlying true distribution. +The `primarycensored` package aims to address these challenges by providing tools to manipulate primary censored delay distributions. By accounting for the censoring and truncation present in the data, the package enables more accurate estimation and use of the underlying true distribution. -In this vignette, we will provide a quick introduction to the main functions and concepts in the `primarycensoreddist` package. We will cover the mathematical formulation of the problem, demonstrate the usage of the key functions, and provide signposting on how to learn more. +In this vignette, we will provide a quick introduction to the main functions and concepts in the `primarycensored` package. We will cover the mathematical formulation of the problem, demonstrate the usage of the key functions, and provide signposting on how to learn more. # Packages in this getting started vignette. -As well as the `primarycensoreddist` package this vignette also uses `ggplot2`. +As well as the `primarycensored` package this vignette also uses `ggplot2`. ```{r setup, message = FALSE} # Load packages -library(primarycensoreddist) +library(primarycensored) library(ggplot2) # Set seed for reproducibility set.seed(123) ``` -# Generating random samples with `rprimarycensoreddist()` +# Generating random samples with `rprimarycensored()` This function generates random samples from a primary event censored distribution. It adjusts the distribution by accounting for the primary event distribution, potential truncation at a maximum delay ($D$), and secondary event censoring. @@ -71,7 +71,7 @@ $$t_{truncated} = \{t \mid 0 \leq t < D\}$$ $$t_{valid} = \lfloor \frac{t_{truncated}}{swindow} \rfloor \times swindow$$ -Here's an example of how to use `rprimarycensoreddist()` to sample from a log-normal distribution with and without secondary interval censoring. For simplicity we will use a daily censoring window for both events. +Here's an example of how to use `rprimarycensored()` to sample from a log-normal distribution with and without secondary interval censoring. For simplicity we will use a daily censoring window for both events. ```{r sample-lognormal} n <- 1e4 @@ -81,14 +81,14 @@ obs_time <- 10 pwindow <- 1 # Random samples without secondary censoring -samples <- rprimarycensoreddist( +samples <- rprimarycensored( n, rdist = rlnorm, rprimary = runif, pwindow = pwindow, swindow = 0, D = obs_time, meanlog = meanlog, sdlog = sdlog ) # Random samples with secondary censoring -samples_sc <- rprimarycensoreddist( +samples_sc <- rprimarycensored( n, rdist = rlnorm, rprimary = runif, pwindow = pwindow, swindow = 1, D = obs_time, @@ -148,7 +148,7 @@ ggplot() + Neither distribution matches the true distribution due to the truncation at `D` which biases both observed distributions towards shorter delays, as well as the primary and secondary event censoring. -# Compute the primary event censored cumulative distribution function (CDF) for delays with `pprimarycensoreddist()` +# Compute the primary event censored cumulative distribution function (CDF) for delays with `pprimarycensored()` This function computes the primary event censored cumulative distribution function (CDF) for a given set of quantiles. It adjusts the CDF of delay distribution by accounting for the primary event distribution and potential truncation at a maximum delay ($D$). @@ -168,11 +168,11 @@ $$ where $F_{\text{cens,norm}}(q)$ is the normalized CDF. -Let's compare the empirical CDF of our samples without secondary censoring to the theoretical CDF computed using `pprimarycensoreddist()`: +Let's compare the empirical CDF of our samples without secondary censoring to the theoretical CDF computed using `pprimarycensored()`: ```{r cdf-lognormal} empirical_cdf <- ecdf(samples) -theoretical_cdf <- pprimarycensoreddist( +theoretical_cdf <- pprimarycensored( seq(0, obs_time, length.out = 100), pdist = plnorm, dprimary = dunif, pwindow = pwindow, D = obs_time, @@ -196,7 +196,7 @@ ggplot(cdf_data, aes(x = x)) + y = "Cumulative Probability", caption = paste0( "Blue line: Empirical CDF from samples without secondary censoring\n", - "Black line: Theoretical CDF computed using pprimarycensoreddist()" + "Black line: Theoretical CDF computed using pprimarycensored()" ) ) + scale_y_continuous(expand = expansion(mult = c(0, 0.05))) + @@ -207,10 +207,10 @@ ggplot(cdf_data, aes(x = x)) + ) ``` -The theoretical CDF matches the empirical CDF very well, confirming that `pprimarycensoreddist()` is working as expected. +The theoretical CDF matches the empirical CDF very well, confirming that `pprimarycensored()` is working as expected. -# Compute the primary event censored probability mass function (PMF) with `dprimarycensoreddist()` +# Compute the primary event censored probability mass function (PMF) with `dprimarycensored()` This function computes the primary event censored probability mass function (PMF) for a given set of quantiles using the CDF. On top of accounting for the primary event distribution and truncation, it also accounts for secondary event censoring. @@ -222,11 +222,11 @@ $$ where ($F_{\text{cens}}$) is the potentially right truncated primary event censored CDF and ($\text{swindow}$) is the secondary event window. -Let's compare the empirical PMF of our samples with secondary censoring to the theoretical PMF computed using `dprimarycensoreddist()`: +Let's compare the empirical PMF of our samples with secondary censoring to the theoretical PMF computed using `dprimarycensored()`: ```{r pmf-lognormal} -# Calculate the theoretical PMF using dprimarycensoreddist -theoretical_pmf <- dprimarycensoreddist( +# Calculate the theoretical PMF using dprimarycensored +theoretical_pmf <- dprimarycensored( 0:(obs_time - 1), pdist = plnorm, dprimary = dunif, pwindow = pwindow, swindow = 1, D = obs_time, @@ -264,7 +264,7 @@ ggplot() + y = "Density", caption = paste0( "Green bars: Empirical PMF from samples with secondary censoring\n", - "Black line: Theoretical PMF computed using dprimarycensoreddist()" + "Black line: Theoretical PMF computed using dprimarycensored()" ) ) + scale_y_continuous(expand = expansion(mult = c(0, 0.05))) + @@ -275,7 +275,7 @@ ggplot() + ) ``` -Again the theoretical PMF matches the empirical PMF very well, confirming that `dprimarycensoreddist()` is also working as expected. +Again the theoretical PMF matches the empirical PMF very well, confirming that `dprimarycensored()` is also working as expected. # Other key functionality @@ -287,7 +287,7 @@ In addition to these main functions, the package also includes: # Learning more -- For more on `primarycensoreddist` see the other package vignettes and the function documentation. +- For more on `primarycensored` see the other package vignettes and the function documentation. - For a more detailed explanation of the mathematical formulation of the primary event censored distribution see the `vignette("why-it-works")`. - For more mathematical details on the analytic solutions see the `vignette("analytic-solutions")`. - For more methodological background on delay distributions see Park et al.[@Park2024]. diff --git a/vignettes/using-stan-tools.Rmd b/vignettes/using-stan-tools.Rmd index 0c1b81c..9e22040 100644 --- a/vignettes/using-stan-tools.Rmd +++ b/vignettes/using-stan-tools.Rmd @@ -1,6 +1,6 @@ --- -title: "How to use primarycensoreddist with Stan" -description: "A guide on how to use primarycensoreddist with Stan." +title: "How to use primarycensored with Stan" +description: "A guide on how to use primarycensored with Stan." author: Sam Abbott output: bookdown::html_document2: @@ -12,7 +12,7 @@ bibliography: library.bib csl: https://raw.githubusercontent.com/citation-style-language/styles/master/apa-numeric-superscript-brackets.csl link-citations: true vignette: > - %\VignetteIndexEntry{How to use primarycensoreddist with Stan} + %\VignetteIndexEntry{How to use primarycensored with Stan} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -22,16 +22,16 @@ vignette: > ## What are we going to do in this Vignette -In this vignette, we'll explore how to use the `primarycensoreddist` package in conjunction with Stan. We'll cover the following key points: +In this vignette, we'll explore how to use the `primarycensored` package in conjunction with Stan. We'll cover the following key points: 1. Introduction to Stan and its relevance for our analysis 2. Overview of the packages we'll be using -3. How to access and use Stan functions provided by `primarycensoreddist` +3. How to access and use Stan functions provided by `primarycensored` 4. Methods for integrating these Stan functions into your workflow ## What is Stan and why are we using it -Stan is a probabilistic programming language for statistical inference. It provides a flexible and efficient platform for Bayesian modeling and is widely used in various fields of data science and statistics. In this vignette, we'll use Stan in conjunction with `primarycensoreddist` to perform Bayesian inference on censored data. +Stan is a probabilistic programming language for statistical inference. It provides a flexible and efficient platform for Bayesian modeling and is widely used in various fields of data science and statistics. In this vignette, we'll use Stan in conjunction with `primarycensored` to perform Bayesian inference on censored data. For more information on Stan: @@ -41,16 +41,16 @@ For more information on Stan: ## Packages used in this vignette -Alongside the `primarycensoreddist` package we will use the `cmdstanr` package for interfacing with cmdstan. +Alongside the `primarycensored` package we will use the `cmdstanr` package for interfacing with cmdstan. ```{r setup, message = FALSE} -library(primarycensoreddist) +library(primarycensored) library(cmdstanr) ``` -# Using Stan code in primarycensoreddist +# Using Stan code in primarycensored -`primarycensoreddist` includes a set of Stan functions that mirror the R functions in `primarycensoreddist`. Documentation for these functions can be found [here](https://primarycensoreddist.epinowcast.org/stan/). We support a range of approaches to integrate this Stan code into your workflow. +`primarycensored` includes a set of Stan functions that mirror the R functions in `primarycensored`. Documentation for these functions can be found [here](https://primarycensored.epinowcast.org/stan/). We support a range of approaches to integrate this Stan code into your workflow. ## Checking available Stan functions using `pcd_stan_functions()` @@ -65,7 +65,7 @@ pcd_stan_functions() Stan functions are accessed using the `pcd_load_stan_functions()` function. This function takes the name of the function as an argument and returns the function as a string. It can additionally write the functions to a file and wrap them in a `functions{}` block. ```{r} -pcd_load_stan_functions("primary_censored_dist_lpmf") +pcd_load_stan_functions("primarycensored_lpmf") ``` ## Linking the Stan functions to your workflow @@ -95,7 +95,7 @@ Alternatively, you could use `#include expgrowth_rng.stan` in a stan file functi ### Including the functions directly via `include_paths` -Rather than writing the functions to a file it is also possible to include them directly in the stan file using the `include_paths` argument to `cmdstan_model()`. This is useful if you don't to clutter your model with the stan code from `primarycensoreddist` and want automatic updating of the functions. To demonstrate we will first write a small model has has `expgrowth.stan` in its include paths (rather than writing it to a file and then including it). The first step is find the file and path for the `expgrowth_rng` function. +Rather than writing the functions to a file it is also possible to include them directly in the stan file using the `include_paths` argument to `cmdstan_model()`. This is useful if you don't to clutter your model with the stan code from `primarycensored` and want automatic updating of the functions. To demonstrate we will first write a small model has has `expgrowth.stan` in its include paths (rather than writing it to a file and then including it). The first step is find the file and path for the `expgrowth_rng` function. ```{r} pcd_stan_files("expgrowth_rng") @@ -118,7 +118,7 @@ writeLines( ) ``` -We can now use this file to compile a model. **Note** that we need to include the path to the `primarycensoreddist` Stan functions using the `include_paths` argument to `cmdstan_model()`. +We can now use this file to compile a model. **Note** that we need to include the path to the `primarycensored` Stan functions using the `include_paths` argument to `cmdstan_model()`. ```{r} model <- cmdstan_model(expgrowth_stan_file, include_paths = pcd_stan_path()) @@ -134,7 +134,7 @@ samples ## Using Stan functions directly in R -Whilst it is possible to use Stan functions directly in R it is not recommended for most use cases (use the R functions in `primarycensoreddist` instead). However, it can be useful to understand what is going on under the hood or for exploration (indeed we use this internally in `primarycensoreddist` to check our functions against the R implementations). To do this we use the `expose_functions()` method on our already compiled model. +Whilst it is possible to use Stan functions directly in R it is not recommended for most use cases (use the R functions in `primarycensored` instead). However, it can be useful to understand what is going on under the hood or for exploration (indeed we use this internally in `primarycensored` to check our functions against the R implementations). To do this we use the `expose_functions()` method on our already compiled model. ```{r, message = FALSE} model$expose_functions(global = TRUE) diff --git a/vignettes/why-it-works.Rmd b/vignettes/why-it-works.Rmd index d50617f..5db4a4a 100644 --- a/vignettes/why-it-works.Rmd +++ b/vignettes/why-it-works.Rmd @@ -20,18 +20,18 @@ vignette: > ## What are we going to do in this Vignette -In this vignette, we'll explain the underlying statistical model that the `primarycensoreddist` package. We'll cover the following key points: +In this vignette, we'll explain the underlying statistical model that the `primarycensored` package. We'll cover the following key points: 1. Introduction to the censored data problems in time to event analysis. 2. Discuss the relevant issues from censoring in epidemiological data. -3. Introduce the statistical model used in `primarycensoreddist`. +3. Introduce the statistical model used in `primarycensored`. 4. Distributions where we can derive the censored delay distribution analytically. -If you are new to the package, we recommend that you start with the `vignette("primarycensoreddist")` vignette. +If you are new to the package, we recommend that you start with the `vignette("primarycensored")` vignette. # Censoring and right truncation problems in time to event analysis -Time to event analysis, also known as survival analysis, concerns estimating the distribution of delay times between events. A distinctive feature of the field are the methodological techniques used to deal with the missing data problems common in data sets of delay times [@leung1997censoring]. In `primarycensoreddist` we focus on two particular missing data problems: +Time to event analysis, also known as survival analysis, concerns estimating the distribution of delay times between events. A distinctive feature of the field are the methodological techniques used to deal with the missing data problems common in data sets of delay times [@leung1997censoring]. In `primarycensored` we focus on two particular missing data problems: - **Interval censoring**. The primary (start) time and/or the secondary (end) time of the delay are unobserved but both are known to be within intervals. - **Right truncation**. Truncated delay data items are only reported if their secondary events are less than a known time, for example the current data collection time. @@ -40,11 +40,11 @@ In statistical epidemiology, these missing data problems occur frequently in bot In data analysis, events in epidemiology are commonly reported as occurring on a particular day or week (*interval censoring*). In an emerging outbreak, datasets can be incompletely observed (*right truncation*) and their can be a great deal of uncertainty around the precise timing of events (*interval censoring*). -In theoretical epidemiological modelling, it is often appropriate to model the evolution of an infectious disease as occurring in discrete time, for example in the [`EpiNow2`](https://epiforecasts.io/EpiNow2/) and [EpiEstim](https://mrc-ide.github.io/EpiEstim/index.html) modelling packages. This means appropriately discretising continuous distributions, such as the generation interval distribution. In `primarycensoreddist` we treat the discretisation of intrinsically continuous distributions as an *interval censoring* problem which allows us to simultaneously provide methods for both applied and theoretical contexts. +In theoretical epidemiological modelling, it is often appropriate to model the evolution of an infectious disease as occurring in discrete time, for example in the [`EpiNow2`](https://epiforecasts.io/EpiNow2/) and [EpiEstim](https://mrc-ide.github.io/EpiEstim/index.html) modelling packages. This means appropriately discretising continuous distributions, such as the generation interval distribution. In `primarycensored` we treat the discretisation of intrinsically continuous distributions as an *interval censoring* problem which allows us to simultaneously provide methods for both applied and theoretical contexts. -# Statistical model used in `primarycensoreddist` +# Statistical model used in `primarycensored` -As described in [Getting Started with `primarycensoreddist`](primarycensoreddist.html), `primarycensoreddist` focuses on a subset of methods from time to event analysis that address data missingness problems commonly found in epidemiological datasets. We present the statistical problem as a double interval censoring problem, where both the primary event time and the secondary event times are interval censored. We can recover single interval censoring problems by reducing one of the intervals to a point. In particular, a key assumption we make is that the censoring window for events is known and independent of the event time. This is known as non-informative censoring. +As described in [Getting Started with `primarycensored`](primarycensored.html), `primarycensored` focuses on a subset of methods from time to event analysis that address data missingness problems commonly found in epidemiological datasets. We present the statistical problem as a double interval censoring problem, where both the primary event time and the secondary event times are interval censored. We can recover single interval censoring problems by reducing one of the intervals to a point. In particular, a key assumption we make is that the censoring window for events is known and independent of the event time. This is known as non-informative censoring. The target for inference is the distribution of the delay time between the primary and secondary events. We assume that the delay time is a random variable $T = S - P_{u}$ with distribution function $F_T(t) = Pr(T < t)$ and density function $f_T(t)$. In this treatment we assume that the delay time is shift-invariant, that is, the distribution of the delay time is the same regardless of the primary event time. @@ -59,7 +59,7 @@ f_{P}(p) &= 0, \qquad &\text{otherwise}. \end{aligned} $$ -In this note, we measure the *censored delay time* $T_c$ between the primary and secondary event windows from endpoint to endpoint: $T_c = t_S + w_S - (t_P + w_P)$. Note that in the [generative model for delays](primarycensoreddist.html#generating-random-samples-with-rprimarycensoreddist) from "Getting started" the truncated delay $t_{\text{valid}}$ is measured from startpoint to startpoint of event windows. +In this note, we measure the *censored delay time* $T_c$ between the primary and secondary event windows from endpoint to endpoint: $T_c = t_S + w_S - (t_P + w_P)$. Note that in the [generative model for delays](primarycensored.html#generating-random-samples-with-rprimarycensored) from "Getting started" the truncated delay $t_{\text{valid}}$ is measured from startpoint to startpoint of event windows. In our treatment below we focus on the [survival function](https://en.wikipedia.org/wiki/Survival_function) of the time after the end of the primary window to the secondary event time which we denote $S_{+}$. We then use this to derive the distribution of the censored delay time $T_c$. This is equivalent to, but differs in mathematical approach from other treatments of the censoring problems in epidemiology, such as [@Park2024], see section [Connections to other approaches](#connections-to-other-approaches) for details. @@ -102,7 +102,7 @@ Equation \@ref(eq:survivalfunc) is the key equation in this note and is used to 1. The probability that the _actual_ delay time $T$ is greater than $t + w_P$. 2. The probability that the _actual_ delay time $T$ is between $t$ and $t + w_P$, and the primary event time $P$ occurred sufficiently close to the end of the primary censor window that the secondary even occurred more than time $t$ after the end of the primary window. -Note that in ["Getting started"](primarycensoreddist.html#compute-the-primary-event-censored-cumulative-distribution-function-cdf-for-delays-with-pprimarycensoreddist) the target for numerical quadrature is the cumulative distribution function of the sum of the primary time within the primary censor window and the delay time. +Note that in ["Getting started"](primarycensored.html#compute-the-primary-event-censored-cumulative-distribution-function-cdf-for-delays-with-pprimarycensored) the target for numerical quadrature is the cumulative distribution function of the sum of the primary time within the primary censor window and the delay time. ### Probability of secondary event time within a secondary censoring window @@ -133,7 +133,7 @@ Which is a discrete probability mass function of the secondary event time relati # Connections to other approaches -In this section, we discuss how the approach taken in `primarycensoreddist` relates to some other approaches to the censored data problems in time to event analysis. +In this section, we discuss how the approach taken in `primarycensored` relates to some other approaches to the censored data problems in time to event analysis. ## Connection to Park et al 2014 @@ -193,6 +193,6 @@ In this derivation, we have used that $G_P(x|-w_P, 0)$ is the distribution funct # Learning more - For more mathematical background on the analytic solutions see the `vignette("analytic-solutions")`. -- For a more introductory explanation of the primary event censored distribution see the `vignette("primarycensoreddist")`. +- For a more introductory explanation of the primary event censored distribution see the `vignette("primarycensored")`. # References