| Title: | Primary Event Censored Distributions |
|---|---|
| Description: | Provides 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 (Charniga et al. (2024) <doi:10.48550/arXiv.2405.08841>). It also provides support for arbitrary delay distributions, a range of common primary distributions, and allows for truncation and secondary event censoring to be accounted for (Park et al. (2024) <doi:10.1101/2024.01.12.24301247>). A subset of common distributions also have analytical solutions implemented, allowing for faster computation. In addition, it provides multiple methods for fitting primary event censored distributions to data via optional dependencies. |
| Authors: | Sam Abbott [aut, cre, cph] (ORCID: <https://orcid.org/0000-0001-8057-8037>), Sam Brand [aut] (ORCID: <https://orcid.org/0000-0003-0645-5367>), Adam Howes [ctb] (ORCID: <https://orcid.org/0000-0003-2386-4031>), James Mba Azam [aut] (ORCID: <https://orcid.org/0000-0001-5782-7330>), Carl Pearson [aut] (ORCID: <https://orcid.org/0000-0003-0701-7860>), Sebastian Funk [aut] (ORCID: <https://orcid.org/0000-0002-2842-3406>), Kelly Charniga [aut] (ORCID: <https://orcid.org/0000-0002-7648-7041>) |
| Maintainer: | Sam Abbott <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.5.2 |
| Built: | 2026-10-11 15:17:04 UTC |
| Source: | https://github.com/epinowcast/primarycensored |
pprimarycensored() and related functions can identify which distributions
are provided via the pdist and dprimary arguments when those are base R
functions (e.g. punif, dexp) via the name attribute.
add_name_attribute(func, name)add_name_attribute(func, name)
func |
Function, for example the |
name |
Character string, starting with "p" or "d" indicating the underlying distribution. |
If you need to use a non-base R implementation, but know the distribution
name, you can use this helper function to set it in a way that will be
detected by pprimarycensored() and related functions.
This is useful as it enables the automatic use of analytical solutions for
distributions where they exist. You can check which analytical solutions are
available using methods(pcens_cdf) and check distribution names using
pcd_dist_name().
Function, with a "name" attribute added
Utility functions for working with distributions
pcd_dist_name(),
pcd_distributions,
pcd_primary_distributions
dist <- add_name_attribute(pnorm, "hello") attr(dist, "name")dist <- add_name_attribute(pnorm, "hello") attr(dist, "name")
This function tests whether a given function behaves like a valid PDF by checking if it integrates to approximately 1 over the specified range and if it takes the arguments min and max.
check_dprimary(dprimary, pwindow, dprimary_args = list(), tolerance = 0.001)check_dprimary(dprimary, pwindow, dprimary_args = list(), tolerance = 0.001)
dprimary |
Function to generate the probability density function
(PDF) of primary event times. This function should take a value |
pwindow |
Primary event window |
dprimary_args |
[Deprecated] Use |
tolerance |
The tolerance for the integral to be considered close to 1 |
NULL. The function will stop execution with an error message if dprimary is not a valid PDF.
Distribution checking functions
check_pdist(),
check_truncation()
check_dprimary(dunif, pwindow = 1)check_dprimary(dunif, pwindow = 1)
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.
check_pdist(pdist, D = Inf, ...)check_pdist(pdist, D = Inf, ...)
pdist |
Distribution function (CDF). The package can identify base R
distributions for potential analytical solutions. For non-base R functions,
users can apply |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
... |
Additional arguments to be passed to pdist |
NULL. The function will stop execution with an error message if pdist is not a valid CDF.
Distribution checking functions
check_dprimary(),
check_truncation()
check_pdist(pnorm, D = 10)check_pdist(pnorm, D = 10)
This function checks if the truncation time D is appropriate relative to the
maximum delay. If D is much larger than necessary, it suggests
considering setting it to Inf for better efficiency with minimal accuracy
cost.
check_truncation(delays, D, multiplier = 2)check_truncation(delays, D, multiplier = 2)
delays |
A numeric vector of delay times |
D |
The truncation time |
multiplier |
The multiplier for the maximum delay to compare with D. Default is 2. |
Invisible NULL. Prints a message if the condition is met.
Distribution checking functions
check_dprimary(),
check_pdist()
check_truncation(delays = c(1, 2, 3, 4), D = 10, multiplier = 2)check_truncation(delays = c(1, 2, 3, 4), D = 10, multiplier = 2)
Returns the probability mass for each value in x. Converts
hazards to a PMF via hazards_to_pmf() then delegates to
ddiscretestep().
ddiscretehazard(x, boundaries = NULL, hazards)ddiscretehazard(x, boundaries = NULL, hazards)
x |
Numeric vector of values at which to evaluate the PMF. |
boundaries |
Numeric vector of length |
hazards |
Numeric vector of length |
Outside fitting it is a deterministic wrapper around ddiscretestep().
It earns its keep as a fitting parameterisation in fitdistdoublecens()
because the random walk on the logit hazard smooths the recovered PMF.
Numeric vector of PMF values, the same length as x.
ddiscretestep(), hazards_to_pmf(), pmf_to_hazards(),
fitdistdoublecens()
Other pdiscretehazard:
discretehazard_start(),
pdiscretehazard(),
rdiscretehazard()
hazards <- c(0.3, 0.5, 1) ddiscretehazard(c(1, 2, 3), boundaries = 0:3, hazards = hazards)hazards <- c(0.3, 0.5, 1) ddiscretehazard(c(1, 2, 3), boundaries = 0:3, hazards = hazards)
Returns the probability mass for each value in x. Mass
pmf[i] is located at boundaries[i+1] (the right edge of
bin i); all other values return 0.
ddiscretestep(x, boundaries = NULL, pmf)ddiscretestep(x, boundaries = NULL, pmf)
x |
Numeric vector of values at which to evaluate the PMF. |
boundaries |
Numeric vector of length |
pmf |
Numeric vector of length |
Like pdiscretestep, this function applies a soft simplex
penalty: if pmf contains negative entries or fails to sum to 1
(within ), the function returns near-zero density
(.Machine$double.eps) rather than erroring. This makes it safe to
call from inside fitdistrplus::fitdist() closures driven by
fitdistdoublecens.
Numeric vector of PMF values, the same length as x.
Other pdiscretestep:
hazards_to_pmf(),
pdiscretestep(),
pmf_to_hazards(),
rdiscretestep()
ddiscretestep(c(0, 1, 2, 3), boundaries = 0:3, pmf = c(0.2, 0.5, 0.3))ddiscretestep(c(0, 1, 2, 3), boundaries = 0:3, pmf = c(0.2, 0.5, 0.3))
Builds a named list of starting values for fitdistdoublecens() with
distr = "discretehazard". The free parameters are the logit
intercept alpha, the log random-walk (or random-effect) scale
log_sigma, and the K - 1 innovations eps_1, ...,
eps_{K-1}. The final bin hazard is pinned to 1 inside the
parameterisation so the implied PMF sums to 1.
discretehazard_start(K, alpha = -2, log_sigma = log(1), eps = 0)discretehazard_start(K, alpha = -2, log_sigma = log(1), eps = 0)
K |
Integer, number of bins in the hazard parameterisation. |
alpha |
Numeric, start value for the logit intercept. |
log_sigma |
Numeric, start value for the log scale. |
eps |
Numeric, scalar or length- |
Named list suitable for the start argument of
fitdistdoublecens().
Other pdiscretehazard:
ddiscretehazard(),
pdiscretehazard(),
rdiscretehazard()
discretehazard_start(K = 5)discretehazard_start(K = 5)
This function computes the primary event censored probability mass function (PMF) for a given set of quantiles. It adjusts the PMF of the primary event distribution by accounting for the delay distribution and potential truncation at a maximum delay (D) and minimum delay (L). The function allows for custom primary event distributions and delay distributions.
dprimarycensored( x, pdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, log = FALSE, ..., check = TRUE ) dpcens( x, pdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, log = FALSE, ..., check = TRUE )dprimarycensored( x, pdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, log = FALSE, ..., check = TRUE ) dpcens( x, pdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, log = FALSE, ..., check = TRUE )
x |
Vector of quantiles |
pdist |
Distribution function (CDF). The package can identify base R
distributions for potential analytical solutions. For non-base R functions,
users can apply |
pwindow |
Primary event window |
swindow |
Secondary event window (default: 1) |
L |
Minimum delay (lower truncation point). Defaults to |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
dprimary |
Function to generate the probability density function
(PDF) of primary event times. This function should take a value |
primary_args |
List of additional arguments to be passed to
dprimary (and the matching primary CDF). For example, when using
|
pprimary |
Optional CDF for the primary event distribution. May be
a function or a character string naming a primary distribution in
|
dprimary_args |
[Deprecated] Use |
log |
Logical; if TRUE, probabilities p are given as log(p) |
... |
Additional arguments to be passed to the distribution function |
check |
Logical; if |
The primary event censored PMF is computed by taking the difference of the
primary event censored cumulative distribution function (CDF) at two points,
and . The primary event censored PMF,
, is given by:
where is the primary event censored CDF.
The function first computes the CDFs for all unique points (including both
and ) using pprimarycensored(). It then
creates a lookup table for these CDFs to efficiently calculate the PMF for
each input value. For delays less than L, the function returns 0.
When the secondary censoring interval extends past the upper truncation
point () but the lower endpoint satisfies
, the upper endpoint is internally clipped to before
evaluating the CDF. The likelihood for such an observation is
, which
equals the usual interval probability when .
This avoids erroring when an observation's secondary window straddles the
truncation point (relevant for non-parametric delays such as
pdiscretestep()).
Observations with are rejected with an error: under the
truncation , no event with latent value is
observable, and accepting such inputs would otherwise yield a 0/0
likelihood.
The PMF is normalised to ensure it sums to 1 over the range [L, D\). This normalization uses:
where is the normalized PMF. For the
explanation and mathematical details of the CDF, refer to the documentation
of pprimarycensored().
Vector of primary event censored PMFs, normalized over [L, D] if truncation is applied
Primary event censored distribution functions
pprimarycensored(),
qprimarycensored(),
rprimarycensored()
# Example: Weibull distribution with uniform primary events dprimarycensored(c(0.1, 0.5, 1), pweibull, shape = 1.5, scale = 2.0) # Example: Weibull distribution with exponential growth primary events dprimarycensored( c(0.1, 0.5, 1), pweibull, dprimary = dexpgrowth, primary_args = list(r = 0.2), shape = 1.5, scale = 2.0 ) # Example: Left-truncated distribution (e.g., for generation intervals) dprimarycensored(1:9, pweibull, L = 1, D = 10, shape = 1.5, scale = 2.0)# Example: Weibull distribution with uniform primary events dprimarycensored(c(0.1, 0.5, 1), pweibull, shape = 1.5, scale = 2.0) # Example: Weibull distribution with exponential growth primary events dprimarycensored( c(0.1, 0.5, 1), pweibull, dprimary = dexpgrowth, primary_args = list(r = 0.2), shape = 1.5, scale = 2.0 ) # Example: Left-truncated distribution (e.g., for generation intervals) dprimarycensored(1:9, pweibull, L = 1, D = 10, shape = 1.5, scale = 2.0)
Density, distribution function, and random generation for the exponential growth distribution.
dexpgrowth(x, min = 0, max = 1, r, log = FALSE) pexpgrowth(q, min = 0, max = 1, r, lower.tail = TRUE, log.p = FALSE) rexpgrowth(n, min = 0, max = 1, r)dexpgrowth(x, min = 0, max = 1, r, log = FALSE) pexpgrowth(q, min = 0, max = 1, r, lower.tail = TRUE, log.p = FALSE) rexpgrowth(n, min = 0, max = 1, r)
x, q
|
Vector of quantiles. |
min |
Minimum value of the distribution range. Default is 0. |
max |
Maximum value of the distribution range. Default is 1. |
r |
Rate parameter for the exponential growth. |
log, log.p
|
Logical; if TRUE, probabilities p are given as log(p). |
lower.tail |
Logical; if TRUE (default), probabilities are P[X <= x], otherwise, P[X > x]. |
n |
Number of observations. If |
The exponential growth distribution is defined on the interval [min, max] with rate parameter (r). Its probability density function (PDF) is:
The cumulative distribution function (CDF) is:
For random number generation, we use the inverse transform sampling method:
Generate
Set and solve for :
This method works because of the probability integral transform theorem,
which states that if is a continuous random variable with CDF
, then follows a
distribution. Conversely, if is a random
variable, then has the same distribution as , where
is the inverse of the CDF.
In our case, we generate from , then solve
for to get a sample from our exponential growth
distribution. The formula for is derived by algebraically solving
the equation:
When is very close to 0 (), the distribution
approximates a uniform distribution on [min, max], and we use a simpler
method to generate samples directly from this uniform distribution.
dexpgrowth gives the density, pexpgrowth gives the distribution
function, and rexpgrowth generates random deviates.
The length of the result is determined by n for rexpgrowth, and is the
maximum of the lengths of the numerical arguments for the other functions.
x <- seq(0, 1, by = 0.1) probs <- dexpgrowth(x, r = 0.2) cumprobs <- pexpgrowth(x, r = 0.2) samples <- rexpgrowth(100, r = 0.2)x <- seq(0, 1, by = 0.1) probs <- dexpgrowth(x, r = 0.2) cumprobs <- pexpgrowth(x, r = 0.2) samples <- rexpgrowth(100, r = 0.2)
This function wraps the custom approach for fitting distributions to doubly censored data using fitdistrplus and primarycensored. It handles primary censoring (when the primary event time is not known exactly), secondary censoring (when the secondary event time is interval-censored), and truncation (when events are only observed within a delay range [L, D]).
fitdistdoublecens( censdata, distr, left = "left", right = "right", pwindow = "pwindow", L = "L", D = "D", dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, truncation_check_multiplier = 2, prior = NULL, hazard_model = c("rw", "re"), check = TRUE, ... )fitdistdoublecens( censdata, distr, left = "left", right = "right", pwindow = "pwindow", L = "L", D = "D", dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, truncation_check_multiplier = 2, prior = NULL, hazard_model = c("rw", "re"), check = TRUE, ... )
censdata |
A data frame with columns 'left' and 'right' representing
the lower and upper bounds of the censored observations. Unlike
|
distr |
A character string naming the distribution to be fitted.
Special values |
left |
Column name for lower bound of observed values (default: "left"). |
right |
Column name for upper bound of observed values (default: "right"). |
pwindow |
Column name for primary window (default: "pwindow"). |
L |
Column name for minimum delay (lower truncation point). For any
finite L the distribution is left-truncated at L; use |
D |
Column name for maximum delay (upper truncation point). If finite,
the distribution is truncated at D. If set to Inf, no upper truncation is
applied. (default: "D"). Observations whose secondary censoring interval
straddles |
dprimary |
Function to generate the probability density function
(PDF) of primary event times. This function should take a value |
primary_args |
List of additional arguments to be passed to
dprimary (and the matching primary CDF). For example, when using
|
pprimary |
Optional CDF for the primary event distribution. May be
a function or a character string naming a primary distribution in
|
dprimary_args |
[Deprecated] Use |
truncation_check_multiplier |
Numeric multiplier to use for checking if the truncation time D is appropriate relative to the maximum delay. Set to NULL to skip the check. Default is 2. |
prior |
Optional list of prior settings used by the dist function's
|
hazard_model |
One of |
check |
Logical; if |
... |
Additional arguments to be passed to |
The distr argument names a distribution. The function looks up the
density and CDF functions by prepending d and p to the name (e.g.
distr = "gamma" resolves to dgamma() and pgamma()). Custom
distributions can be used as long as the corresponding d<distr>() and
p<distr>() functions are defined.
Two non-parametric distributions are supported. They share a common
fitting machinery: the dist function carries a vector_param attribute
("pmf" for pdiscretestep()/ddiscretestep(), "hazards" for
pdiscretehazard()/ddiscretehazard()) that drives this function to
build a closure mapping flat scalar parameters into the underlying
vector argument.
distr = "discretestep": free parameters p1, ..., p_{K-1} (in
[0, 1]); the last bin probability is 1 - sum(p1, ..., p_{K-1}).
See pdiscretestep() for parameterisation details and the soft
simplex penalty applied when probabilities are infeasible.
distr = "discretehazard": free parameters alpha, log_sigma,
eps_1, ..., eps_{K-1}. The hazard form parameterises the same
family of step distributions as "discretestep", but its free
parameters drive either a Gaussian random walk on the logit hazard
(hazard_model = "rw", the default,
logit(h_i) = alpha + sigma * cumsum(eps)) or an IID logit
random-effect transform (hazard_model = "re",
logit(h_i) = alpha + sigma * eps_i with eps_i ~ N(0, 1)). The
smoothing of the random walk regularises the recovered PMF against
over-fitting in sparse data and replaces the simplex constraint
with an unconstrained optimisation; the random-effect variant
models hazards as independent draws around alpha rather than a
smoothed trajectory. See pdiscretehazard() for full
parameterisation details and the MAP-equivalent prior penalty
applied during fitting; pass prior to override the default prior
settings.
For non-parametric distributions K is implied by length(start):
K = length(start) + 1 for "discretestep" and
K = length(start) - 1 for "discretehazard". start is therefore
required.
An object of class "fitdist" as returned by fitdistrplus::fitdist.
pdiscretestep() pdiscretehazard()
Modelling wrappers for external fitting packages
pcd_as_stan_data(),
pcd_cmdstan_model()
# Example with normal distribution set.seed(123) n <- 1000 true_mean <- 5 true_sd <- 2 pwindow <- 2 swindow <- 2 D <- 10 samples <- rprimarycensored( n, rnorm, mean = true_mean, sd = true_sd, pwindow = pwindow, swindow = swindow, D = D ) delay_data <- data.frame( left = samples, right = samples + swindow, pwindow = rep(pwindow, n), D = rep(D, n) ) fit_norm <- fitdistdoublecens( delay_data, distr = "norm", start = list(mean = 0, sd = 1) ) summary(fit_norm) # Example with discretestep (non-parametric PMF) distribution set.seed(42) true_pmf <- c(0.1, 0.3, 0.4, 0.15, 0.05) step_samples <- rprimarycensored( 500, rdiscretestep, boundaries = 0:5, pmf = true_pmf, pwindow = 1, swindow = 1, D = 6 ) step_data <- data.frame( left = step_samples, right = step_samples + 1, pwindow = rep(1, 500), D = rep(6, 500) ) fit_step <- fitdistdoublecens( step_data, distr = "discretestep", boundaries = 0:5, start = as.list(setNames(rep(0.2, 4), paste0("p", 1:4))) ) # Example with discretehazard (logit-hazard random walk) distribution fit_haz <- fitdistdoublecens( step_data, distr = "discretehazard", boundaries = 0:5, start = c( list(alpha = -2, log_sigma = log(0.5)), as.list(setNames(rep(0, 4), paste0("eps_", 1:4))) ) )# Example with normal distribution set.seed(123) n <- 1000 true_mean <- 5 true_sd <- 2 pwindow <- 2 swindow <- 2 D <- 10 samples <- rprimarycensored( n, rnorm, mean = true_mean, sd = true_sd, pwindow = pwindow, swindow = swindow, D = D ) delay_data <- data.frame( left = samples, right = samples + swindow, pwindow = rep(pwindow, n), D = rep(D, n) ) fit_norm <- fitdistdoublecens( delay_data, distr = "norm", start = list(mean = 0, sd = 1) ) summary(fit_norm) # Example with discretestep (non-parametric PMF) distribution set.seed(42) true_pmf <- c(0.1, 0.3, 0.4, 0.15, 0.05) step_samples <- rprimarycensored( 500, rdiscretestep, boundaries = 0:5, pmf = true_pmf, pwindow = 1, swindow = 1, D = 6 ) step_data <- data.frame( left = step_samples, right = step_samples + 1, pwindow = rep(1, 500), D = rep(6, 500) ) fit_step <- fitdistdoublecens( step_data, distr = "discretestep", boundaries = 0:5, start = as.list(setNames(rep(0.2, 4), paste0("p", 1:4))) ) # Example with discretehazard (logit-hazard random walk) distribution fit_haz <- fitdistdoublecens( step_data, distr = "discretehazard", boundaries = 0:5, start = c( list(alpha = -2, log_sigma = log(0.5)), as.list(setNames(rep(0, 4), paste0("eps_", 1:4))) ) )
Given a vector of discrete-time hazards , computes
the corresponding PMF:
hazards_to_pmf(hazards)hazards_to_pmf(hazards)
hazards |
Numeric vector of hazards in |
The last hazard must equal 1 (to ensure the PMF sums to 1). If a vector
of length is supplied (all hazards except the final exit
hazard), 1 is appended automatically.
Numeric vector of PMF values.
Other pdiscretestep:
ddiscretestep(),
pdiscretestep(),
pmf_to_hazards(),
rdiscretestep()
hazards_to_pmf(c(0.2, 0.3, 1))hazards_to_pmf(c(0.2, 0.3, 1))
S3 class for primary event censored distribution computation
new_pcens( pdist, dprimary, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ... )new_pcens( pdist, dprimary, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ... )
pdist |
Distribution function (CDF). The package can identify base R
distributions for potential analytical solutions. For non-base R functions,
users can apply |
dprimary |
Function to generate the probability density function
(PDF) of primary event times. This function should take a value |
primary_args |
List of additional arguments to be passed to
|
pprimary |
CDF of the primary event distribution. May be a function
or a character string naming a primary distribution in
|
dprimary_args |
[Deprecated] Use |
... |
Additional arguments to be passed to pdist |
An object with class hierarchy
c("pcens_{pdist_name}_{dprimary_name}", "pcens_{pdist_name}",
"pcens"). This contains the primary event distribution, the delay
distribution, the delay distribution arguments, the primary event CDF
(if available), and any additional arguments. It can be used with the
pcens_cdf() function to compute the primary event censored CDF.
Low level primary event censored distribution objects and methods
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
new_pcens( pdist = pgamma, dprimary = dunif, primary_args = list(min = 0, max = 1), shape = 1, scale = 1 )new_pcens( pdist = pgamma, dprimary = dunif, primary_args = list(min = 0, max = 1), shape = 1, scale = 1 )
This function takes in delay data and prepares it for use with the primarycensored Stan model.
pcd_as_stan_data( data, delay = "delay", delay_upper = "delay_upper", n = "n", pwindow = "pwindow", start_relative_obs_time = "start_relative_obs_time", relative_obs_time = "relative_obs_time", dist_id, primary_id, param_bounds, primary_param_bounds, priors, primary_priors, compute_log_lik = FALSE, use_reduce_sum = FALSE, truncation_check_multiplier = 2, dist_options = NULL )pcd_as_stan_data( data, delay = "delay", delay_upper = "delay_upper", n = "n", pwindow = "pwindow", start_relative_obs_time = "start_relative_obs_time", relative_obs_time = "relative_obs_time", dist_id, primary_id, param_bounds, primary_param_bounds, priors, primary_priors, compute_log_lik = FALSE, use_reduce_sum = FALSE, truncation_check_multiplier = 2, dist_options = NULL )
data |
A data frame containing the delay data. |
delay |
Column name for observed delays (default: "delay") |
delay_upper |
Column name for upper bound of delays (default: "delay_upper") |
n |
Column name for count of observations (default: "n") |
pwindow |
Column name for primary window (default: "pwindow") |
start_relative_obs_time |
Column name for start of relative observation
time, used as the lower truncation point L. Values may be any finite real
number (including negatives) or |
relative_obs_time |
Column name for relative observation time, used as
the upper truncation point D. Values may be any finite real number
(including negatives, paired with a smaller |
dist_id |
Integer identifying the delay distribution:
You can use |
primary_id |
Integer identifying the primary distribution:
You can use |
param_bounds |
A list with elements |
primary_param_bounds |
A list with elements |
priors |
A list with elements |
primary_priors |
A list with elements |
compute_log_lik |
Logical; compute log likelihood? (default: FALSE) |
use_reduce_sum |
Logical; use reduce_sum for performance? (default: FALSE) |
truncation_check_multiplier |
Numeric multiplier to use for checking if the truncation time D is appropriate relative to the maximum delay for each unique D value. Set to NULL to skip the check. Default is 2. |
dist_options |
Optional list carrying the shape of a
non-parametric delay. When
Priors and
|
A list containing the data formatted for use with
pcd_cmdstan_model()
Modelling wrappers for external fitting packages
fitdistdoublecens(),
pcd_cmdstan_model()
data <- data.frame( delay = c(1, 2, 3), delay_upper = c(2, 3, 4), n = c(10, 20, 15), pwindow = c(1, 1, 2), relative_obs_time = c(10, 10, 10) ) stan_data <- pcd_as_stan_data( data, dist_id = 1, primary_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)), primary_priors = list(location = numeric(0), scale = numeric(0)) )data <- data.frame( delay = c(1, 2, 3), delay_upper = c(2, 3, 4), n = c(10, 20, 15), pwindow = c(1, 1, 2), relative_obs_time = c(10, 10, 10) ) stan_data <- pcd_as_stan_data( data, dist_id = 1, primary_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)), primary_priors = list(location = numeric(0), scale = numeric(0)) )
This function creates a CmdStanModel object using the Stan model and functions from primarycensored and optionally includes additional user-specified Stan files.
pcd_cmdstan_model(include_paths = primarycensored::pcd_stan_path(), ...)pcd_cmdstan_model(include_paths = primarycensored::pcd_stan_path(), ...)
include_paths |
Character vector of paths to include for Stan
compilation. Defaults to the result of |
... |
Additional arguments passed to cmdstanr::cmdstan_model(). |
The underlying Stan model (pcens_model.stan) supports various features:
Multiple probability distributions for modeling delays
Primary and secondary censoring
Truncation
Optional use of reduce_sum for improved performance (via within chain parallelism).
Flexible prior specifications
Optional computation of log-likelihood for model comparison
A CmdStanModel object.
Modelling wrappers for external fitting packages
fitdistdoublecens(),
pcd_as_stan_data()
if (!is.null(cmdstanr::cmdstan_version(error_on_NA = FALSE))) { model <- pcd_cmdstan_model(compile = FALSE) model }if (!is.null(cmdstanr::cmdstan_version(error_on_NA = FALSE))) { model <- pcd_cmdstan_model(compile = FALSE) model }
Get distribution function cdf or pdf name
pcd_dist_name(name, type = c("delay", "primary"))pcd_dist_name(name, type = c("delay", "primary"))
name |
String. Distribution name or alias |
type |
String. "delay" or "primary" corresponding to the type of
distribution to use as the look up. If delay then |
String distribution function name or NA if no base R implementation
Utility functions for working with distributions
add_name_attribute(),
pcd_distributions,
pcd_primary_distributions
pcd_dist_name("lnorm") pcd_dist_name("lognormal") pcd_dist_name("gamma") pcd_dist_name("weibull") pcd_dist_name("exp") pcd_dist_name("unif", type = "primary") pcd_dist_name("expgrowth", type = "primary")pcd_dist_name("lnorm") pcd_dist_name("lognormal") pcd_dist_name("gamma") pcd_dist_name("weibull") pcd_dist_name("exp") pcd_dist_name("unif", type = "primary") pcd_dist_name("expgrowth", type = "primary")
A dataset containing information about the supported delay distributions in primarycensored. Includes both distributions with base R implementations and those only available in Stan. Distributions beyond these are not supported in the stan code but any user functions can be used in the R code.
pcd_distributionspcd_distributions
A data.frame with 28 rows and 4 columns:
Distribution name
R distribution function name (e.g. plnorm), NA if there is no base R implementation
Alternative names/identifiers
Stan distribution ID used in the stan code
Utility functions for working with distributions
add_name_attribute(),
pcd_dist_name(),
pcd_primary_distributions
Load Stan functions as a string
pcd_load_stan_functions( functions = NULL, stan_path = primarycensored::pcd_stan_path(), wrap_in_block = FALSE, write_to_file = FALSE, output_file = "pcd_functions.stan", dependencies = FALSE )pcd_load_stan_functions( functions = NULL, stan_path = primarycensored::pcd_stan_path(), wrap_in_block = FALSE, write_to_file = FALSE, output_file = "pcd_functions.stan", dependencies = FALSE )
functions |
Character vector of function names to load. Defaults to all functions. |
stan_path |
Character string, the path to the Stan code. Defaults to the path to the Stan code in the primarycensored package. |
wrap_in_block |
Logical, whether to wrap the functions in a
|
write_to_file |
Logical, whether to write the output to a file. Default is FALSE. |
output_file |
Character string, the path to write the output file if write_to_file is TRUE. Defaults to "pcd_functions.stan". |
dependencies |
Logical, whether to include all functions that the requested functions depend on. When TRUE, recursively finds and includes all dependencies in the correct order (dependencies before the functions that use them). Default is FALSE. |
A character string containing the requested Stan functions
Tools for working with package Stan functions
pcd_stan_dist_id(),
pcd_stan_files(),
pcd_stan_function_deps(),
pcd_stan_functions(),
pcd_stan_path()
A dataset containing information about the supported primary event distributions in primarycensored. Distributions beyond these are not supported in the stan code but any user functions can be used in the R code.
pcd_primary_distributionspcd_primary_distributions
A data.frame with 2 rows and 4 columns:
Distribution name
R density function name
Alternative names/identifiers
Stan distribution ID used in the stan code
Utility functions for working with distributions
add_name_attribute(),
pcd_dist_name(),
pcd_distributions
Get distribution stan ID by name
pcd_stan_dist_id(name, type = c("delay", "primary"))pcd_stan_dist_id(name, type = c("delay", "primary"))
name |
String. Distribution name or alias |
type |
String. "delay" or "primary" corresponding to the type of
distribution to use as the look up. If delay then |
Numeric distribution ID
Tools for working with package Stan functions
pcd_load_stan_functions(),
pcd_stan_files(),
pcd_stan_function_deps(),
pcd_stan_functions(),
pcd_stan_path()
pcd_stan_dist_id("lnorm") pcd_stan_dist_id("lognormal") pcd_stan_dist_id("gamma") pcd_stan_dist_id("weibull") pcd_stan_dist_id("exp") pcd_stan_dist_id("unif", type = "primary")pcd_stan_dist_id("lnorm") pcd_stan_dist_id("lognormal") pcd_stan_dist_id("gamma") pcd_stan_dist_id("weibull") pcd_stan_dist_id("exp") pcd_stan_dist_id("unif", type = "primary")
This function retrieves Stan files from a specified directory, optionally filtering for files that contain specific functions.
pcd_stan_files(functions = NULL, stan_path = primarycensored::pcd_stan_path())pcd_stan_files(functions = NULL, stan_path = primarycensored::pcd_stan_path())
functions |
Character vector of function names to search for. If NULL, all Stan files are returned. |
stan_path |
Character string specifying the path to the directory containing Stan files. Defaults to the Stan path of the primarycensored package. |
A character vector of file paths to Stan files.
Tools for working with package Stan functions
pcd_load_stan_functions(),
pcd_stan_dist_id(),
pcd_stan_function_deps(),
pcd_stan_functions(),
pcd_stan_path()
Returns all Stan functions that the specified function depends on, in topological order (dependencies before the functions that use them).
pcd_stan_function_deps( function_name, stan_path = primarycensored::pcd_stan_path() )pcd_stan_function_deps( function_name, stan_path = primarycensored::pcd_stan_path() )
function_name |
Character string, the name of the Stan function. |
stan_path |
Character string specifying the path to the directory containing Stan files. Defaults to the Stan path of the primarycensored package. |
A character vector of function names that the specified function depends on, ordered so that dependencies come before functions that use them. The requested function itself is included as the last element.
Tools for working with package Stan functions
pcd_load_stan_functions(),
pcd_stan_dist_id(),
pcd_stan_files(),
pcd_stan_functions(),
pcd_stan_path()
# See what primarycensored_lpmf depends on pcd_stan_function_deps("primarycensored_lpmf") # A function with no dependencies pcd_stan_function_deps("expgrowth_pdf")# See what primarycensored_lpmf depends on pcd_stan_function_deps("primarycensored_lpmf") # A function with no dependencies pcd_stan_function_deps("expgrowth_pdf")
This function reads all Stan files in the specified directory and extracts the names of all functions defined in those files.
pcd_stan_functions(stan_path = primarycensored::pcd_stan_path())pcd_stan_functions(stan_path = primarycensored::pcd_stan_path())
stan_path |
Character string specifying the path to the directory containing Stan files. Defaults to the Stan path of the primarycensored package. |
A character vector containing unique names of all functions found in the Stan files.
Tools for working with package Stan functions
pcd_load_stan_functions(),
pcd_stan_dist_id(),
pcd_stan_files(),
pcd_stan_function_deps(),
pcd_stan_path()
Get the path to the Stan code
pcd_stan_path()pcd_stan_path()
A character string with the path to the Stan code
Tools for working with package Stan functions
pcd_load_stan_functions(),
pcd_stan_dist_id(),
pcd_stan_files(),
pcd_stan_function_deps(),
pcd_stan_functions()
This function dispatches to either analytical solutions (if available) or
numerical integration via the default method. To see which combinations have
analytical solutions implemented, use methods(pcens_cdf). For example,
pcens_cdf.gamma_unif indicates an analytical solution exists for gamma
delay with uniform primary event distributions.
pcens_cdf(object, q, pwindow, use_numeric = FALSE)pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
This method serves as a fallback for combinations of delay and primary event distributions that don't have specific implementations. It uses a numeric integration method.
## Default S3 method: pcens_cdf(object, q, pwindow, use_numeric = FALSE)## Default S3 method: pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
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 pprimarycensored(), but
applies numerical integration instead of analytical solutions.
Vector of computed primary event censored CDFs
pprimarycensored() for the mathematical details of the
primary event censored CDF computation.
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
# Create a primarycensored object with gamma delay and uniform primary pcens_obj <- new_pcens( pdist = pgamma, dprimary = dunif, primary_args = list(min = 0, max = 1), shape = 3, scale = 2 ) # Compute CDF for a single value pcens_cdf(pcens_obj, q = 9, pwindow = 1) # Compute CDF for multiple values pcens_cdf(pcens_obj, q = c(4, 6, 8), pwindow = 1)# Create a primarycensored object with gamma delay and uniform primary pcens_obj <- new_pcens( pdist = pgamma, dprimary = dunif, primary_args = list(min = 0, max = 1), shape = 3, scale = 2 ) # Compute CDF for a single value pcens_cdf(pcens_obj, q = 9, pwindow = 1) # Compute CDF for multiple values pcens_cdf(pcens_obj, q = c(4, 6, 8), pwindow = 1)
Computes the analytic primary event censored CDF for a hazard-parameterised
piecewise-constant delay distribution. Converts hazards to a PMF via
hazards_to_pmf() then dispatches back through pcens_cdf() using a
freshly constructed step-distribution object. The same primary event
distribution and arguments are preserved.
## S3 method for class 'pcens_pdiscretehazard' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_pdiscretehazard' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
Computes the analytic primary event censored CDF for a piecewise-constant
(step) delay distribution and an arbitrary primary event distribution
whose CDF is available via object$pprimary.
## S3 method for class 'pcens_pdiscretestep' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_pdiscretestep' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
The observation CDF is
Because is piecewise constant, the integral reduces to
where is the constant value of on the
-th sub-interval of the primary event window induced by the
step-function knots.
The partition is exact for any bin widths, so bins may be wider or
narrower than pwindow, and for boundaries that start below zero.
Falls back to pcens_cdf.default when use_numeric = TRUE
or when no primary CDF is available on the object.
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
Method for Gamma delay with uniform primary
## S3 method for class 'pcens_pgamma_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_pgamma_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
Analytical solution for the generalised gamma distribution in the Prentice
parameterisation used by flexsurv::pgengamma(), with parameters mu,
sigma and Q.
For Q > 0 this is mapped to the Stacy parameterisation of
pcens_cdf.pcens_pgengamma.orig_dunif() via shape = Q / sigma,
scale = exp(mu) * Q^(2 * sigma / Q) and k = 1 / Q^2.
For Q <= 0 (the lognormal and reflected cases) the numerical
pcens_cdf.default() method is used.
## S3 method for class 'pcens_pgengamma_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_pgengamma_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
Analytical solution for the generalised gamma distribution in the Stacy
parameterisation used by flexsurv::pgengamma.orig(), with parameters
shape, scale and k.
The delay CDF is with the
regularised lower incomplete gamma function, the shape and
the scale.
The mean is and the partial
expectation distribution is ,
so the solution generalises the gamma (shape = 1) and Weibull (k = 1)
cases.
See vignette("analytic-solutions") for the derivation.
## S3 method for class 'pcens_pgengamma.orig_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_pgengamma.orig_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
pcens_obj <- new_pcens( pdist = flexsurv::pgengamma.orig, dprimary = dunif, dprimary_args = list(min = 0, max = 1), shape = 1.5, scale = 2, k = 0.8 ) pcens_cdf(pcens_obj, q = c(1, 4, 8), pwindow = 1)pcens_obj <- new_pcens( pdist = flexsurv::pgengamma.orig, dprimary = dunif, dprimary_args = list(min = 0, max = 1), shape = 1.5, scale = 2, k = 0.8 ) pcens_cdf(pcens_obj, q = c(1, 4, 8), pwindow = 1)
Method for Log-Normal delay with uniform primary
## S3 method for class 'pcens_plnorm_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_plnorm_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile(),
pcens_quantile.default()
Method for Weibull delay with uniform primary
## S3 method for class 'pcens_pweibull_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)## S3 method for class 'pcens_pweibull_dunif' pcens_cdf(object, q, pwindow, use_numeric = FALSE)
object |
A |
q |
Vector of quantiles |
pwindow |
Primary event window |
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. |
Vector of computed primary event censored CDFs
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_quantile(),
pcens_quantile.default()
This function inverts the primary event censored CDF to compute quantiles.
It uses numerical optimisation via optim to find the value q such that
pcens_cdf() is close to the specified probability. Currently, only the
default numerical inversion method is implemented. Future analytical
solutions may be added.
pcens_quantile(object, p, pwindow, L = -Inf, D = Inf, use_numeric = FALSE, ...)pcens_quantile(object, p, pwindow, L = -Inf, D = Inf, use_numeric = FALSE, ...)
object |
A |
p |
A vector of probabilities at which to compute the quantiles. |
pwindow |
Primary event window |
L |
Minimum delay (lower truncation point). Defaults to |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
use_numeric |
Logical; if TRUE forces the use of numeric inversion even if an analytical solution is available (not yet implemented). |
... |
Additional arguments to be passed to pdist |
Vector of primary event censored quantiles.
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile.default()
This method inverts the primary event censored CDF by root-finding via
stats::uniroot() with extendInt = "upX". The censored CDF is monotone
in q, so stats::uniroot() extends its starting bracket outward as
needed and handles infinite L or D without special casing.
## Default S3 method: pcens_quantile( object, p, pwindow, L = -Inf, D = Inf, use_numeric = FALSE, init = 5, tol = 1e-08, max_iter = 10000, ... )## Default S3 method: pcens_quantile( object, p, pwindow, L = -Inf, D = Inf, use_numeric = FALSE, init = 5, tol = 1e-08, max_iter = 10000, ... )
object |
A |
p |
A vector of probabilities at which to compute the quantiles. |
pwindow |
Primary event window |
L |
Minimum delay (lower truncation point). Defaults to |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
use_numeric |
Logical; if TRUE forces the use of numeric inversion even if an analytical solution is available (not yet implemented). |
init |
Half-width of the initial search interval used when one or
both truncation bounds are infinite. The starting interval is taken as
|
tol |
Numeric tolerance passed to |
max_iter |
Maximum number of |
... |
Additional arguments passed to underlying functions. |
A numeric vector containing the computed primary event censored quantiles.
Low level primary event censored distribution objects and methods
new_pcens(),
pcens_cdf(),
pcens_cdf.default(),
pcens_cdf.pcens_pdiscretehazard(),
pcens_cdf.pcens_pdiscretestep(),
pcens_cdf.pcens_pgamma_dunif(),
pcens_cdf.pcens_pgengamma.orig_dunif(),
pcens_cdf.pcens_pgengamma_dunif(),
pcens_cdf.pcens_plnorm_dunif(),
pcens_cdf.pcens_pweibull_dunif(),
pcens_quantile()
# Create a primarycensored object with gamma delay and uniform primary pcens_obj <- new_pcens( pdist = pgamma, dprimary = dunif, primary_args = list(min = 0, max = 1), shape = 3, scale = 2 ) # Compute quantile for a single probability pcens_quantile(pcens_obj, p = 0.8, pwindow = 1) # Compute quantiles for multiple probabilities pcens_quantile(pcens_obj, p = c(0.25, 0.5, 0.75), pwindow = 1) # Compute quantiles for multiple probabilities with truncation pcens_quantile(pcens_obj, p = c(0.25, 0.5, 0.75), pwindow = 1, D = 10) # Compute quantiles with left truncation pcens_quantile(pcens_obj, p = c(0.25, 0.5, 0.75), pwindow = 1, L = 1, D = 10)# Create a primarycensored object with gamma delay and uniform primary pcens_obj <- new_pcens( pdist = pgamma, dprimary = dunif, primary_args = list(min = 0, max = 1), shape = 3, scale = 2 ) # Compute quantile for a single probability pcens_quantile(pcens_obj, p = 0.8, pwindow = 1) # Compute quantiles for multiple probabilities pcens_quantile(pcens_obj, p = c(0.25, 0.5, 0.75), pwindow = 1) # Compute quantiles for multiple probabilities with truncation pcens_quantile(pcens_obj, p = c(0.25, 0.5, 0.75), pwindow = 1, D = 10) # Compute quantiles with left truncation pcens_quantile(pcens_obj, p = c(0.25, 0.5, 0.75), pwindow = 1, L = 1, D = 10)
Returns the CDF of a discrete distribution specified by its bin-wise
discrete-time hazards. Converts hazards to a PMF via
hazards_to_pmf() then delegates to pdiscretestep().
pdiscretehazard(q, boundaries = NULL, hazards)pdiscretehazard(q, boundaries = NULL, hazards)
q |
Numeric vector of quantiles. |
boundaries |
Numeric vector of length |
hazards |
Numeric vector of length |
Outside fitting it is a deterministic wrapper around pdiscretestep().
It earns its keep as a fitting parameterisation in fitdistdoublecens()
because the random walk on the logit hazard smooths the recovered PMF.
Numeric vector of CDF values, the same length as q.
pdiscretestep(), hazards_to_pmf(), pmf_to_hazards(),
fitdistdoublecens()
Other pdiscretehazard:
ddiscretehazard(),
discretehazard_start(),
rdiscretehazard()
hazards <- c(0.3, 0.5, 1) pdiscretehazard(c(0.5, 1, 2, 3), boundaries = 0:3, hazards = hazards)hazards <- c(0.3, 0.5, 1) pdiscretehazard(c(0.5, 1, 2, 3), boundaries = 0:3, hazards = hazards)
Returns the CDF of a discrete distribution whose mass is concentrated at
the right boundary of each bin. The CDF is right-continuous and piecewise
constant with jumps at boundaries[2], ..., boundaries[K+1].
pdiscretestep(q, boundaries = NULL, pmf)pdiscretestep(q, boundaries = NULL, pmf)
q |
Numeric vector of quantiles. |
boundaries |
Numeric vector of length |
pmf |
Numeric vector of length |
Below boundaries[1] the function returns 0. At
boundaries[i+1] (the right edge of bin i), F jumps by
pmf[i], so .
For q in , F equals
. At or above boundaries[K+1]
the function returns 1.
fitdistdoublecens()
This function carries the attribute vector_param = "pmf" so that
fitdistdoublecens can drive it from a flat list of scalar
parameters p1, ..., p_{K-1}. The free parameters are the first
bin probabilities; the last is set to
1 - sum(p1, ..., p_{K-1}). When the implied probabilities violate
the simplex (any negative entry, or sum departing from 1 by more than
), the function returns 0 (or near-zero density in
ddiscretestep) rather than erroring; this drives the
optimiser back to the feasible region.
Numeric vector of CDF values, the same length as q.
Other pdiscretestep:
ddiscretestep(),
hazards_to_pmf(),
pmf_to_hazards(),
rdiscretestep()
# Two-bin PMF: mass 0.3 at x=1, mass 0.7 at x=2 pdiscretestep(c(0.5, 1, 1.5, 2), boundaries = 0:2, pmf = c(0.3, 0.7))# Two-bin PMF: mass 0.3 at x=1, mass 0.7 at x=2 pdiscretestep(c(0.5, 1, 1.5, 2), boundaries = 0:2, pmf = c(0.3, 0.7))
Inverts hazards_to_pmf(): given a PMF, computes the discrete-time
conditional hazard at each time point.
pmf_to_hazards(pmf)pmf_to_hazards(pmf)
pmf |
Numeric vector of probabilities. Must be non-negative and sum to approximately 1. |
The returned vector has the same length as pmf, with the last
entry equal to 1.
Numeric vector of hazards in .
Other pdiscretestep:
ddiscretestep(),
hazards_to_pmf(),
pdiscretestep(),
rdiscretestep()
pmf_to_hazards(c(0.2, 0.3, 0.5))pmf_to_hazards(c(0.2, 0.3, 0.5))
This function computes the primary event censored cumulative distribution function (CDF) for a given set of quantiles. It adjusts the CDF of the primary event distribution by accounting for the delay distribution and potential truncation at a maximum delay (D) and minimum delay (L). The function allows for custom primary event distributions and delay distributions.
pprimarycensored( q, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE ) ppcens( q, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE )pprimarycensored( q, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE ) ppcens( q, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE )
q |
Vector of quantiles |
pdist |
Distribution function (CDF). The package can identify base R
distributions for potential analytical solutions. For non-base R functions,
users can apply |
pwindow |
Primary event window |
L |
Minimum delay (lower truncation point). Defaults to |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
dprimary |
Function to generate the probability density function
(PDF) of primary event times. This function should take a value |
primary_args |
List of additional arguments to be passed to
dprimary (and the matching primary CDF). For example, when using
|
pprimary |
Optional CDF for the primary event distribution. May be
a function or a character string naming a primary distribution in
|
dprimary_args |
[Deprecated] Use |
... |
Additional arguments to be passed to pdist |
check |
Logical; if |
The primary event censored CDF is computed by integrating the product of the delay distribution function (CDF) and the primary event distribution function (PDF) over the primary event window. The integration is adjusted for truncation if specified.
The primary event censored CDF, , is given by:
where is the CDF of the delay distribution,
is the PDF of the primary event times, and
is the primary event window.
If truncation is applied (finite D or finite L), the CDF is
normalized:
where is the normalized CDF. For values
, the function returns 0; for values , it
returns 1.
This function creates a primarycensored object using
new_pcens() and then computes the primary event
censored CDF using pcens_cdf(). This abstraction allows
for automatic use of analytical solutions when available, while
seamlessly falling back to numerical integration when necessary.
See methods(pcens_cdf) for which combinations have analytical
solutions implemented.
Vector of primary event censored CDFs, normalized over [L, D] if truncation is applied
Primary event censored distribution functions
dprimarycensored(),
qprimarycensored(),
rprimarycensored()
# Example: Lognormal distribution with uniform primary events pprimarycensored(c(0.1, 0.5, 1), plnorm, meanlog = 0, sdlog = 1) # Example: Lognormal distribution with exponential growth primary events pprimarycensored( c(0.1, 0.5, 1), plnorm, dprimary = dexpgrowth, primary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) # Example: Left-truncated distribution (e.g., for generation intervals) pprimarycensored( c(1, 2, 3), plnorm, L = 1, D = 10, meanlog = 0, sdlog = 1 )# Example: Lognormal distribution with uniform primary events pprimarycensored(c(0.1, 0.5, 1), plnorm, meanlog = 0, sdlog = 1) # Example: Lognormal distribution with exponential growth primary events pprimarycensored( c(0.1, 0.5, 1), plnorm, dprimary = dexpgrowth, primary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) # Example: Left-truncated distribution (e.g., for generation intervals) pprimarycensored( c(1, 2, 3), plnorm, L = 1, D = 10, meanlog = 0, sdlog = 1 )
This function computes the quantiles (delay values) that correspond to specified probabilities in the primary event censored distribution. For a given probability p, it computes the delay value q such that the cumulative probability up to q equals p in the primary event censored distribution. The distribution accounts for both the delay distribution and the primary event timing distribution.
qprimarycensored( p, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE ) qpcens( p, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE )qprimarycensored( p, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE ) qpcens( p, pdist, pwindow = 1, L = -Inf, D = Inf, dprimary = dunif, primary_args = NULL, pprimary = NULL, dprimary_args = NULL, ..., check = TRUE )
p |
Vector of probabilities between 0 and 1 for which to compute corresponding quantiles |
pdist |
Distribution function (CDF). The package can identify base R
distributions for potential analytical solutions. For non-base R functions,
users can apply |
pwindow |
Primary event window |
L |
Minimum delay (lower truncation point). Defaults to |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
dprimary |
Function to generate the probability density function
(PDF) of primary event times. This function should take a value |
primary_args |
List of additional arguments to be passed to
dprimary (and the matching primary CDF). For example, when using
|
pprimary |
Optional CDF for the primary event distribution. May be
a function or a character string naming a primary distribution in
|
dprimary_args |
[Deprecated] Use |
... |
Additional arguments to be passed to pdist |
check |
Logical; if |
For each probability, the function finds the delay value where that proportion of events have occurred by that time in the primary event censored distribution. This is done by inverting the cumulative distribution function.
The function creates a primarycensored object using new_pcens() and then
computes the quantiles using pcens_quantile(). This approach allows for
analytical solutions when available, falling back to numerical methods when
necessary.
For example, if p = 0.5, the function returns the median delay (truncated over [L, D] if specified) where 50% of censored events occur by this time and 50% occur after.
See methods(pcens_quantile) for which combinations have analytical
solutions implemented.
Vector of delay values (quantiles) corresponding to the input probabilities
new_pcens() and pcens_quantile()
Primary event censored distribution functions
dprimarycensored(),
pprimarycensored(),
rprimarycensored()
# Compute delays where 25%, 50%, and 75% of events occur by (quartiles) # Using lognormal delays with uniform primary events qprimarycensored(c(0.25, 0.5, 0.75), plnorm, meanlog = 0, sdlog = 1) # Same quartiles but with exponential growth in primary events qprimarycensored( c(0.25, 0.5, 0.75), plnorm, dprimary = dexpgrowth, primary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) # Same quartiles but with truncation at 10 qprimarycensored( c(0.25, 0.5, 0.75), plnorm, dprimary = dexpgrowth, primary_args = list(r = 0.2), meanlog = 0, sdlog = 1, D = 10 ) # Left-truncated distribution (e.g., for generation intervals) qprimarycensored( c(0.25, 0.5, 0.75), plnorm, L = 1, D = 10, meanlog = 0, sdlog = 1 )# Compute delays where 25%, 50%, and 75% of events occur by (quartiles) # Using lognormal delays with uniform primary events qprimarycensored(c(0.25, 0.5, 0.75), plnorm, meanlog = 0, sdlog = 1) # Same quartiles but with exponential growth in primary events qprimarycensored( c(0.25, 0.5, 0.75), plnorm, dprimary = dexpgrowth, primary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) # Same quartiles but with truncation at 10 qprimarycensored( c(0.25, 0.5, 0.75), plnorm, dprimary = dexpgrowth, primary_args = list(r = 0.2), meanlog = 0, sdlog = 1, D = 10 ) # Left-truncated distribution (e.g., for generation intervals) qprimarycensored( c(0.25, 0.5, 0.75), plnorm, L = 1, D = 10, meanlog = 0, sdlog = 1 )
Draws n independent samples from the discrete distribution defined
by hazards. Converts hazards to a PMF via
hazards_to_pmf() then delegates to rdiscretestep().
rdiscretehazard(n, boundaries = NULL, hazards)rdiscretehazard(n, boundaries = NULL, hazards)
n |
Integer. Number of samples to draw. |
boundaries |
Numeric vector of length |
hazards |
Numeric vector of length |
Outside fitting it is a deterministic wrapper around rdiscretestep().
It earns its keep as a fitting parameterisation in fitdistdoublecens()
because the random walk on the logit hazard smooths the recovered PMF.
Numeric vector of length n.
rdiscretestep(), hazards_to_pmf(), pmf_to_hazards(),
fitdistdoublecens()
Other pdiscretehazard:
ddiscretehazard(),
discretehazard_start(),
pdiscretehazard()
set.seed(42) rdiscretehazard(10, boundaries = 0:3, hazards = c(0.3, 0.5, 1))set.seed(42) rdiscretehazard(10, boundaries = 0:3, hazards = c(0.3, 0.5, 1))
Draws n independent samples from the discrete distribution with
probability mass pmf[i] at boundaries[i+1].
rdiscretestep(n, boundaries = NULL, pmf)rdiscretestep(n, boundaries = NULL, pmf)
n |
Integer. Number of samples to draw. |
boundaries |
Numeric vector of length |
pmf |
Numeric vector of length |
Numeric vector of length n.
Other pdiscretestep:
ddiscretestep(),
hazards_to_pmf(),
pdiscretestep(),
pmf_to_hazards()
set.seed(42) rdiscretestep(10, boundaries = 0:3, pmf = c(0.2, 0.5, 0.3))set.seed(42) rdiscretestep(10, boundaries = 0:3, pmf = c(0.2, 0.5, 0.3))
This function generates random samples from a primary event censored distribution. It adjusts the distribution by accounting for the primary event distribution and potential truncation at a maximum delay (D) and minimum delay (L). The function allows for custom primary event distributions and delay distributions.
rprimarycensored( n, rdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, rprimary = stats::runif, rprimary_args = list(), oversampling_factor = 1.2, ... ) rpcens( n, rdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, rprimary = stats::runif, rprimary_args = list(), oversampling_factor = 1.2, ... )rprimarycensored( n, rdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, rprimary = stats::runif, rprimary_args = list(), oversampling_factor = 1.2, ... ) rpcens( n, rdist, pwindow = 1, swindow = 1, L = -Inf, D = Inf, rprimary = stats::runif, rprimary_args = list(), oversampling_factor = 1.2, ... )
n |
Number of random samples to generate. |
rdist |
Function to generate random samples from the delay distribution
for example |
pwindow |
Primary event window |
swindow |
Integer specifying the window size for rounding the delay
(default is 1). If |
L |
Minimum delay (lower truncation point). Defaults to |
D |
Maximum delay (upper truncation point). If finite, the distribution is truncated at D. If set to Inf, no upper truncation is applied. Defaults to Inf. |
rprimary |
Function to generate random samples from the primary
distribution (default is |
rprimary_args |
List of additional arguments to be passed to rprimary. |
oversampling_factor |
Factor by which to oversample the number of samples to account for truncation (default is 1.2). |
... |
Additional arguments to be passed to the distribution function. |
The mathematical formulation for generating random samples from a primary event censored distribution is as follows:
Generate primary event times (p) from the specified primary event distribution (f_p) with parameters phi, defined between 0 and the primary event window (pwindow):
Generate delays (d) from the specified delay distribution (f_d) with parameters theta:
Calculate the total delays (t) by adding the primary event times and the delays:
Apply upper truncation to remove delays >= D:
Round the delays to the nearest secondary event window (swindow):
Apply lower truncation on the rounded values to ensure observed delays are >= L:
The function oversamples to account for potential truncation and generates additional samples if needed to reach the desired number of valid samples.
Vector of random samples from the primary event censored distribution censored by the secondary event window.
Primary event censored distribution functions
dprimarycensored(),
pprimarycensored(),
qprimarycensored()
# Example: Lognormal distribution with uniform primary events rprimarycensored(10, rlnorm, meanlog = 0, sdlog = 1) # Example: Lognormal distribution with exponential growth primary events rprimarycensored( 10, rlnorm, rprimary = rexpgrowth, rprimary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) # Example: Left-truncated distribution (e.g., for generation intervals) rprimarycensored(10, rlnorm, L = 1, D = 10, meanlog = 0, sdlog = 1)# Example: Lognormal distribution with uniform primary events rprimarycensored(10, rlnorm, meanlog = 0, sdlog = 1) # Example: Lognormal distribution with exponential growth primary events rprimarycensored( 10, rlnorm, rprimary = rexpgrowth, rprimary_args = list(r = 0.2), meanlog = 0, sdlog = 1 ) # Example: Left-truncated distribution (e.g., for generation intervals) rprimarycensored(10, rlnorm, L = 1, D = 10, meanlog = 0, sdlog = 1)