simBinomialSeasonalExact() currently requires all ve values to be strictly between 0 and 1:
if (!is.numeric(ve) || length(ve) < 1 || any(!is.finite(ve)) || any(ve <= 0) || any(ve >= 1)) { stop("ve must be a numeric vector with values strictly between 0 and 1", call. = FALSE)}
This is too restrictive for both superiority and non-inferiority studies.
For vaccine/prevention efficacy parameterized as:
VE = 1 - HR
the following values are meaningful:
ve = 0: equal event rates between experimental and control arms. This is the standard null hypothesis for a superiority study.
ve > 0: experimental arm has a lower event rate than control.
ve < 0: experimental arm has a higher event rate than control. This is needed for non-inferiority margins, where the null may allow some loss of efficacy or increased event risk.
ve < 1: required so that HR = 1 - ve remains positive.
For example, a superiority design might use:
ve0 <- 0 ve1 <- 0.40
A non-inferiority design might use something like:
ve0 <- -0.10 # non-inferiority margin, corresponding to HR = 1.10ve1 <- 0 # equal event rates, or possibly a beneficial alternative
Both are valid uses, but the current validation rejects the null/scenario values.
The current error is:
ve must be a numeric vector with values strictly between 0 and 1
Expected behavior:
simBinomialSeasonalExact() should allow any finite ve < 1, subject to the resulting experimental-arm event probability/rate being feasible. In particular, ve = 0 and ve < 0 should be allowed.
Suggested validation:
if (!is.numeric(ve) || length(ve) < 1 || any(!is.finite(ve)) || any(ve >= 1)) { stop("ve must be a numeric vector with finite values less than 1", call. = FALSE)}
If the simulation computes experimental event rates as something like:
experimental_event_rate <- control_event_rate * (1 - ve)
then an additional feasibility check should be applied after control_event_rate has been expanded to match ve:
experimental_event_rate <- control_event_rate * (1 - ve)if (any(experimental_event_rate < 0) || any(experimental_event_rate >= 1)) { stop("ve and control_event_rate imply experimental event rates outside [0, 1)", call. = FALSE)}
The exact check should match whether the helper treats control_event_rate as a probability, hazard, or seasonal cumulative event rate. The important point is that the lower bound should not be on ve itself. Negative ve values are meaningful when they imply a feasible experimental-arm event rate.
simBinomialSeasonalExact() should require something like ve1 > ve0. The function accepts a vector of simulation scenarios, not explicit null/alternative design parameters. Users may want to simulate scenarios below the null, at the null, above the null, or harmful scenarios for sensitivity analyses. A ve1 > ve0 check may make sense in a separate design-construction helper that explicitly takes ve0 and ve1, but it would be unnecessarily restrictive here.
When you are finished, we should bump the version number.
simBinomialSeasonalExact() currently requires all ve values to be strictly between 0 and 1:
if (!is.numeric(ve) || length(ve) < 1 || any(!is.finite(ve)) || any(ve <= 0) || any(ve >= 1)) { stop("ve must be a numeric vector with values strictly between 0 and 1", call. = FALSE)}
This is too restrictive for both superiority and non-inferiority studies.
For vaccine/prevention efficacy parameterized as:
VE = 1 - HR
the following values are meaningful:
ve = 0: equal event rates between experimental and control arms. This is the standard null hypothesis for a superiority study.
ve > 0: experimental arm has a lower event rate than control.
ve < 0: experimental arm has a higher event rate than control. This is needed for non-inferiority margins, where the null may allow some loss of efficacy or increased event risk.
ve < 1: required so that HR = 1 - ve remains positive.
For example, a superiority design might use:
ve0 <- 0 ve1 <- 0.40
A non-inferiority design might use something like:
ve0 <- -0.10 # non-inferiority margin, corresponding to HR = 1.10ve1 <- 0 # equal event rates, or possibly a beneficial alternative
Both are valid uses, but the current validation rejects the null/scenario values.
The current error is:
ve must be a numeric vector with values strictly between 0 and 1
Expected behavior:
simBinomialSeasonalExact() should allow any finite ve < 1, subject to the resulting experimental-arm event probability/rate being feasible. In particular, ve = 0 and ve < 0 should be allowed.
Suggested validation:
if (!is.numeric(ve) || length(ve) < 1 || any(!is.finite(ve)) || any(ve >= 1)) { stop("ve must be a numeric vector with finite values less than 1", call. = FALSE)}
If the simulation computes experimental event rates as something like:
experimental_event_rate <- control_event_rate * (1 - ve)
then an additional feasibility check should be applied after control_event_rate has been expanded to match ve:
experimental_event_rate <- control_event_rate * (1 - ve)if (any(experimental_event_rate < 0) || any(experimental_event_rate >= 1)) { stop("ve and control_event_rate imply experimental event rates outside [0, 1)", call. = FALSE)}
The exact check should match whether the helper treats control_event_rate as a probability, hazard, or seasonal cumulative event rate. The important point is that the lower bound should not be on ve itself. Negative ve values are meaningful when they imply a feasible experimental-arm event rate.
simBinomialSeasonalExact() should require something like ve1 > ve0. The function accepts a vector of simulation scenarios, not explicit null/alternative design parameters. Users may want to simulate scenarios below the null, at the null, above the null, or harmful scenarios for sensitivity analyses. A ve1 > ve0 check may make sense in a separate design-construction helper that explicitly takes ve0 and ve1, but it would be unnecessarily restrictive here.
When you are finished, we should bump the version number.