The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
This vignette compares the Wald and score test implementations in
mutze_test() across a factorial grid of negative binomial
trial scenarios. It also gives practical recommendations for sample-size
calculation when the usual Zhu–Lakkis / Friede–Schmidli / Mutze Wald
formula is adequate, when score-test sizing is a useful diagnostic, and
when the score test itself is the more important change for Type I error
control.
The Wald sizing option in
sample_size_nbinom(test_type = "wald") uses the alternative
variance \(V_1\) for both the Type I
and power components. The score sizing option in
sample_size_nbinom(test_type = "score") uses the null
variance \(V_0\) for the Type I
component and the alternative variance \(V_1\) for the power component:
\[ n_1 = \frac{(z_{\alpha/s}\sqrt{V_0} + z_\beta\sqrt{V_1})^2} {(\theta - \theta_0)^2}. \]
This distinction matters most when the planned final analysis uses a score statistic evaluated under the null, or when finite-sample Type I error control is more important than preserving the historical Wald analysis convention. In the superiority scenarios below, the Wald and score sample sizes are close; the traditional Wald sample size paired with the score test often provides a useful practical margin for power while preserving the score test’s Type I error protection.
The full \(2 \times 2\) factorial comparison is:
| Wald-sized trial | Score-sized trial | |
|---|---|---|
| Wald test | Wald / Wald | Score / Wald |
| Score test | Wald / Score | Score / Score |
We assess:
Tables and figures are rendered from compact precomputed summaries so the CRAN package does not need to bundle the full trial-level simulation output or large interactive widget dependencies.
Results are pre-computed by
data-raw/generate_score_sweep.R, summarized for the CRAN
vignette cache, and loaded here.
summary_file <- system.file("extdata", "score_sweep_summary.rds",
package = "gsDesignNB")
if (summary_file == "" && file.exists("../inst/extdata/score_sweep_summary.rds")) {
summary_file <- "../inst/extdata/score_sweep_summary.rds"
}
raw_file <- system.file("extdata", "score_sweep_results.rds",
package = "gsDesignNB")
if (raw_file == "" && file.exists("../inst/extdata/score_sweep_results.rds")) {
raw_file <- "../inst/extdata/score_sweep_results.rds"
}
if (summary_file != "") {
res <- readRDS(summary_file)
using_summary_cache <- TRUE
} else if (raw_file != "") {
res <- readRDS(raw_file)
using_summary_cache <- FALSE
} else {
stop("Precomputed score sweep summary not found.")
}
config <- res$config
scenarios <- as.data.table(res$scenarios)
base_grid <- as.data.table(res$base_grid)cat(sprintf(
"Expanded scenarios: %d | Power sims: %s | Null sims: %s | RR: %.2f | alpha: %.3f\n",
nrow(scenarios),
format(config$n_sims_power, big.mark = ","),
format(config$n_sims_null, big.mark = ","),
config$rr_power,
config$alpha
))
#> Expanded scenarios: 54 | Power sims: 3,500 | Null sims: 20,000 | RR: 0.70 | alpha: 0.025
cat(sprintf(
"Cache: %s\n",
if (using_summary_cache) "compact summary" else "full raw simulation output"
))
#> Cache: compact summaryThe base scenario grid varies control event rate (\(\lambda_1\)), overdispersion (\(k\)), and minimum inter-event gap. For each base scenario, sample sizes are computed using both the Wald and score variance formulas. In this superiority grid the score-sized trials are equal to or slightly smaller than the Wald-sized trials; score sizing is therefore not a generic “add a few subjects” rule, and the operating characteristics still need to be checked under the planned analysis test.
base_display <- base_grid[, .(
`Control rate` = lambda1,
`Dispersion (k)` = k,
`Event gap (days)` = gap_days,
`N (Wald sizing)` = n_wald,
`N (Score sizing)` = n_score,
`Wald - Score` = n_wald - n_score
)]
knitr::kable(
base_display,
caption = "Base scenario grid with sample sizes by method",
digits = 2
)| Control rate | Dispersion (k) | Event gap (days) | N (Wald sizing) | N (Score sizing) | Wald - Score |
|---|---|---|---|---|---|
| 0.15 | 0.2 | 0 | 304 | 300 | 4 |
| 0.40 | 0.2 | 0 | 158 | 156 | 2 |
| 1.00 | 0.2 | 0 | 104 | 104 | 0 |
| 0.15 | 0.5 | 0 | 406 | 402 | 4 |
| 0.40 | 0.5 | 0 | 260 | 258 | 2 |
| 1.00 | 0.5 | 0 | 206 | 206 | 0 |
| 0.15 | 1.0 | 0 | 576 | 572 | 4 |
| 0.40 | 1.0 | 0 | 430 | 428 | 2 |
| 1.00 | 1.0 | 0 | 378 | 376 | 2 |
| 0.15 | 0.2 | 15 | 320 | 316 | 4 |
| 0.40 | 0.2 | 15 | 174 | 172 | 2 |
| 1.00 | 0.2 | 15 | 120 | 120 | 0 |
| 0.15 | 0.5 | 15 | 428 | 424 | 4 |
| 0.40 | 0.5 | 15 | 280 | 278 | 2 |
| 1.00 | 0.5 | 15 | 226 | 226 | 0 |
| 0.15 | 1.0 | 15 | 606 | 602 | 4 |
| 0.40 | 1.0 | 15 | 458 | 458 | 0 |
| 1.00 | 1.0 | 15 | 404 | 404 | 0 |
| 0.15 | 0.2 | 30 | 338 | 334 | 4 |
| 0.40 | 0.2 | 30 | 190 | 188 | 2 |
| 1.00 | 0.2 | 30 | 136 | 136 | 0 |
| 0.15 | 0.5 | 30 | 448 | 444 | 4 |
| 0.40 | 0.5 | 30 | 300 | 298 | 2 |
| 1.00 | 0.5 | 30 | 244 | 244 | 0 |
| 0.15 | 1.0 | 30 | 634 | 630 | 4 |
| 0.40 | 1.0 | 30 | 486 | 484 | 2 |
| 1.00 | 1.0 | 30 | 426 | 426 | 0 |
null_dt <- as.data.table(res$null_summary)
null_long <- melt(
null_dt,
id.vars = c("lambda1", "k", "gap_days", "n_total", "sizing"),
measure.vars = c("rate_wald", "rate_score"),
variable.name = "test",
value.name = "rejection_rate"
)
null_long[, test := fifelse(test == "rate_wald", "Wald", "Score")]
se_long <- melt(
null_dt,
id.vars = c("lambda1", "k", "gap_days", "sizing"),
measure.vars = c("se_wald", "se_score"),
variable.name = "test",
value.name = "se"
)
se_long[, test := fifelse(test == "se_wald", "Wald", "Score")]
null_long <- merge(null_long, se_long,
by = c("lambda1", "k", "gap_days", "sizing", "test"))
null_long[, combo := paste0(sizing, "-sized / ", test, " test")]
null_long[, `:=`(
above_nominal_95 = rejection_rate - 1.96 * se > config$alpha,
below_nominal_95 = rejection_rate + 1.96 * se < config$alpha
)]type1_summary <- null_long[, .(
`Scenarios` = .N,
`Minimum` = min(rejection_rate),
`Mean` = mean(rejection_rate),
`Maximum` = max(rejection_rate),
`Above nominal beyond MC error` = sum(above_nominal_95),
`Below nominal beyond MC error` = sum(below_nominal_95)
), by = .(`Sizing` = sizing, `Test` = test)]
knitr::kable(
type1_summary[order(Sizing, Test)],
caption = "Type I error synopsis across the scenario grid",
digits = 4
)| Sizing | Test | Scenarios | Minimum | Mean | Maximum | Above nominal beyond MC error | Below nominal beyond MC error |
|---|---|---|---|---|---|---|---|
| score | Score | 27 | 0.0200 | 0.0235 | 0.0264 | 0 | 7 |
| score | Wald | 27 | 0.0243 | 0.0274 | 0.0314 | 15 | 0 |
| wald | Score | 27 | 0.0200 | 0.0236 | 0.0257 | 0 | 9 |
| wald | Wald | 27 | 0.0244 | 0.0274 | 0.0316 | 13 | 0 |
null_display <- null_long[order(lambda1, k, gap_days, sizing, test),
.(
`Control rate` = lambda1,
Dispersion = k,
`Gap (days)` = gap_days,
Sizing = sizing,
N = n_total,
Test = test,
`Type I error` = round(rejection_rate, 4),
SE = round(se, 4)
)
]
knitr::kable(
null_display,
caption = sprintf(
"Type I error rate: nominal alpha = %.3f, %s null sims/scenario",
config$alpha,
format(config$n_sims_null, big.mark = ",")
)
)| Control rate | Dispersion | Gap (days) | Sizing | N | Test | Type I error | SE |
|---|---|---|---|---|---|---|---|
| 0.15 | 0.2 | 0 | score | 300 | Score | 0.0237 | 0.0011 |
| 0.15 | 0.2 | 0 | score | 300 | Wald | 0.0243 | 0.0011 |
| 0.15 | 0.2 | 0 | wald | 304 | Score | 0.0254 | 0.0011 |
| 0.15 | 0.2 | 0 | wald | 304 | Wald | 0.0259 | 0.0011 |
| 0.15 | 0.2 | 15 | score | 316 | Score | 0.0231 | 0.0011 |
| 0.15 | 0.2 | 15 | score | 316 | Wald | 0.0254 | 0.0011 |
| 0.15 | 0.2 | 15 | wald | 320 | Score | 0.0257 | 0.0011 |
| 0.15 | 0.2 | 15 | wald | 320 | Wald | 0.0276 | 0.0012 |
| 0.15 | 0.2 | 30 | score | 334 | Score | 0.0239 | 0.0011 |
| 0.15 | 0.2 | 30 | score | 334 | Wald | 0.0267 | 0.0011 |
| 0.15 | 0.2 | 30 | wald | 338 | Score | 0.0225 | 0.0010 |
| 0.15 | 0.2 | 30 | wald | 338 | Wald | 0.0249 | 0.0011 |
| 0.15 | 0.5 | 0 | score | 402 | Score | 0.0248 | 0.0011 |
| 0.15 | 0.5 | 0 | score | 402 | Wald | 0.0254 | 0.0011 |
| 0.15 | 0.5 | 0 | wald | 406 | Score | 0.0249 | 0.0011 |
| 0.15 | 0.5 | 0 | wald | 406 | Wald | 0.0257 | 0.0011 |
| 0.15 | 0.5 | 15 | score | 424 | Score | 0.0232 | 0.0011 |
| 0.15 | 0.5 | 15 | score | 424 | Wald | 0.0259 | 0.0011 |
| 0.15 | 0.5 | 15 | wald | 428 | Score | 0.0245 | 0.0011 |
| 0.15 | 0.5 | 15 | wald | 428 | Wald | 0.0271 | 0.0011 |
| 0.15 | 0.5 | 30 | score | 444 | Score | 0.0222 | 0.0010 |
| 0.15 | 0.5 | 30 | score | 444 | Wald | 0.0272 | 0.0011 |
| 0.15 | 0.5 | 30 | wald | 448 | Score | 0.0231 | 0.0011 |
| 0.15 | 0.5 | 30 | wald | 448 | Wald | 0.0276 | 0.0012 |
| 0.15 | 1.0 | 0 | score | 572 | Score | 0.0253 | 0.0011 |
| 0.15 | 1.0 | 0 | score | 572 | Wald | 0.0262 | 0.0011 |
| 0.15 | 1.0 | 0 | wald | 576 | Score | 0.0257 | 0.0011 |
| 0.15 | 1.0 | 0 | wald | 576 | Wald | 0.0267 | 0.0011 |
| 0.15 | 1.0 | 15 | score | 602 | Score | 0.0236 | 0.0011 |
| 0.15 | 1.0 | 15 | score | 602 | Wald | 0.0281 | 0.0012 |
| 0.15 | 1.0 | 15 | wald | 606 | Score | 0.0257 | 0.0011 |
| 0.15 | 1.0 | 15 | wald | 606 | Wald | 0.0295 | 0.0012 |
| 0.15 | 1.0 | 30 | score | 630 | Score | 0.0249 | 0.0011 |
| 0.15 | 1.0 | 30 | score | 630 | Wald | 0.0314 | 0.0012 |
| 0.15 | 1.0 | 30 | wald | 634 | Score | 0.0228 | 0.0011 |
| 0.15 | 1.0 | 30 | wald | 634 | Wald | 0.0296 | 0.0012 |
| 0.40 | 0.2 | 0 | score | 156 | Score | 0.0246 | 0.0011 |
| 0.40 | 0.2 | 0 | score | 156 | Wald | 0.0258 | 0.0011 |
| 0.40 | 0.2 | 0 | wald | 158 | Score | 0.0240 | 0.0011 |
| 0.40 | 0.2 | 0 | wald | 158 | Wald | 0.0261 | 0.0011 |
| 0.40 | 0.2 | 15 | score | 172 | Score | 0.0242 | 0.0011 |
| 0.40 | 0.2 | 15 | score | 172 | Wald | 0.0279 | 0.0012 |
| 0.40 | 0.2 | 15 | wald | 174 | Score | 0.0252 | 0.0011 |
| 0.40 | 0.2 | 15 | wald | 174 | Wald | 0.0278 | 0.0012 |
| 0.40 | 0.2 | 30 | score | 188 | Score | 0.0233 | 0.0011 |
| 0.40 | 0.2 | 30 | score | 188 | Wald | 0.0280 | 0.0012 |
| 0.40 | 0.2 | 30 | wald | 190 | Score | 0.0243 | 0.0011 |
| 0.40 | 0.2 | 30 | wald | 190 | Wald | 0.0289 | 0.0012 |
| 0.40 | 0.5 | 0 | score | 258 | Score | 0.0264 | 0.0011 |
| 0.40 | 0.5 | 0 | score | 258 | Wald | 0.0278 | 0.0012 |
| 0.40 | 0.5 | 0 | wald | 260 | Score | 0.0252 | 0.0011 |
| 0.40 | 0.5 | 0 | wald | 260 | Wald | 0.0265 | 0.0011 |
| 0.40 | 0.5 | 15 | score | 278 | Score | 0.0203 | 0.0010 |
| 0.40 | 0.5 | 15 | score | 278 | Wald | 0.0248 | 0.0011 |
| 0.40 | 0.5 | 15 | wald | 280 | Score | 0.0220 | 0.0010 |
| 0.40 | 0.5 | 15 | wald | 280 | Wald | 0.0252 | 0.0011 |
| 0.40 | 0.5 | 30 | score | 298 | Score | 0.0226 | 0.0011 |
| 0.40 | 0.5 | 30 | score | 298 | Wald | 0.0291 | 0.0012 |
| 0.40 | 0.5 | 30 | wald | 300 | Score | 0.0226 | 0.0010 |
| 0.40 | 0.5 | 30 | wald | 300 | Wald | 0.0296 | 0.0012 |
| 0.40 | 1.0 | 0 | score | 428 | Score | 0.0255 | 0.0011 |
| 0.40 | 1.0 | 0 | score | 428 | Wald | 0.0262 | 0.0011 |
| 0.40 | 1.0 | 0 | wald | 430 | Score | 0.0249 | 0.0011 |
| 0.40 | 1.0 | 0 | wald | 430 | Wald | 0.0261 | 0.0011 |
| 0.40 | 1.0 | 15 | score | 458 | Score | 0.0242 | 0.0011 |
| 0.40 | 1.0 | 15 | score | 458 | Wald | 0.0293 | 0.0012 |
| 0.40 | 1.0 | 15 | wald | 458 | Score | 0.0230 | 0.0011 |
| 0.40 | 1.0 | 15 | wald | 458 | Wald | 0.0274 | 0.0012 |
| 0.40 | 1.0 | 30 | score | 484 | Score | 0.0200 | 0.0010 |
| 0.40 | 1.0 | 30 | score | 484 | Wald | 0.0284 | 0.0012 |
| 0.40 | 1.0 | 30 | wald | 486 | Score | 0.0216 | 0.0010 |
| 0.40 | 1.0 | 30 | wald | 486 | Wald | 0.0301 | 0.0012 |
| 1.00 | 0.2 | 0 | score | 104 | Score | 0.0253 | 0.0011 |
| 1.00 | 0.2 | 0 | score | 104 | Wald | 0.0279 | 0.0012 |
| 1.00 | 0.2 | 0 | wald | 104 | Score | 0.0245 | 0.0011 |
| 1.00 | 0.2 | 0 | wald | 104 | Wald | 0.0271 | 0.0011 |
| 1.00 | 0.2 | 15 | score | 120 | Score | 0.0234 | 0.0011 |
| 1.00 | 0.2 | 15 | score | 120 | Wald | 0.0289 | 0.0012 |
| 1.00 | 0.2 | 15 | wald | 120 | Score | 0.0253 | 0.0011 |
| 1.00 | 0.2 | 15 | wald | 120 | Wald | 0.0305 | 0.0012 |
| 1.00 | 0.2 | 30 | score | 136 | Score | 0.0231 | 0.0011 |
| 1.00 | 0.2 | 30 | score | 136 | Wald | 0.0306 | 0.0012 |
| 1.00 | 0.2 | 30 | wald | 136 | Score | 0.0200 | 0.0010 |
| 1.00 | 0.2 | 30 | wald | 136 | Wald | 0.0263 | 0.0011 |
| 1.00 | 0.5 | 0 | score | 206 | Score | 0.0240 | 0.0011 |
| 1.00 | 0.5 | 0 | score | 206 | Wald | 0.0256 | 0.0011 |
| 1.00 | 0.5 | 0 | wald | 206 | Score | 0.0230 | 0.0011 |
| 1.00 | 0.5 | 0 | wald | 206 | Wald | 0.0244 | 0.0011 |
| 1.00 | 0.5 | 15 | score | 226 | Score | 0.0227 | 0.0011 |
| 1.00 | 0.5 | 15 | score | 226 | Wald | 0.0280 | 0.0012 |
| 1.00 | 0.5 | 15 | wald | 226 | Score | 0.0214 | 0.0010 |
| 1.00 | 0.5 | 15 | wald | 226 | Wald | 0.0267 | 0.0011 |
| 1.00 | 0.5 | 30 | score | 244 | Score | 0.0214 | 0.0010 |
| 1.00 | 0.5 | 30 | score | 244 | Wald | 0.0295 | 0.0012 |
| 1.00 | 0.5 | 30 | wald | 244 | Score | 0.0210 | 0.0010 |
| 1.00 | 0.5 | 30 | wald | 244 | Wald | 0.0277 | 0.0012 |
| 1.00 | 1.0 | 0 | score | 376 | Score | 0.0244 | 0.0011 |
| 1.00 | 1.0 | 0 | score | 376 | Wald | 0.0253 | 0.0011 |
| 1.00 | 1.0 | 0 | wald | 378 | Score | 0.0249 | 0.0011 |
| 1.00 | 1.0 | 0 | wald | 378 | Wald | 0.0260 | 0.0011 |
| 1.00 | 1.0 | 15 | score | 404 | Score | 0.0231 | 0.0011 |
| 1.00 | 1.0 | 15 | score | 404 | Wald | 0.0284 | 0.0012 |
| 1.00 | 1.0 | 15 | wald | 404 | Score | 0.0232 | 0.0011 |
| 1.00 | 1.0 | 15 | wald | 404 | Wald | 0.0285 | 0.0012 |
| 1.00 | 1.0 | 30 | score | 426 | Score | 0.0206 | 0.0010 |
| 1.00 | 1.0 | 30 | score | 426 | Wald | 0.0278 | 0.0012 |
| 1.00 | 1.0 | 30 | wald | 426 | Score | 0.0216 | 0.0010 |
| 1.00 | 1.0 | 30 | wald | 426 | Wald | 0.0316 | 0.0012 |
null_long[, scenario := paste0("λ₁=", lambda1, " k=", k)]
p_null <- ggplot(null_long,
aes(x = scenario, y = rejection_rate,
color = combo, shape = test)) +
geom_point(size = 2.5, position = position_dodge(width = 0.5)) +
geom_errorbar(aes(ymin = rejection_rate - 1.96 * se,
ymax = rejection_rate + 1.96 * se),
width = 0.2, position = position_dodge(width = 0.5)) +
geom_hline(yintercept = config$alpha, linetype = "dashed", color = "grey40") +
facet_wrap(~ paste0("Gap = ", gap_days, "d")) +
labs(
title = "Type I error: sizing method × test type",
x = NULL, y = "Rejection rate",
color = "Sizing / Test", shape = "Test"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
p_nullpower_dt <- as.data.table(res$power_summary)
power_long <- melt(
power_dt,
id.vars = c("lambda1", "k", "gap_days", "n_total", "sizing"),
measure.vars = c("rate_wald", "rate_score"),
variable.name = "test",
value.name = "power"
)
power_long[, test := fifelse(test == "rate_wald", "Wald", "Score")]
se_power <- melt(
power_dt,
id.vars = c("lambda1", "k", "gap_days", "sizing"),
measure.vars = c("se_wald", "se_score"),
variable.name = "test",
value.name = "se"
)
se_power[, test := fifelse(test == "se_wald", "Wald", "Score")]
power_long <- merge(power_long, se_power,
by = c("lambda1", "k", "gap_days", "sizing", "test"))
power_long[, combo := paste0(sizing, "-sized / ", test, " test")]power_summary <- power_long[, .(
`Scenarios` = .N,
`Minimum` = min(power),
`Mean` = mean(power),
`Maximum` = max(power),
`Below 90%` = sum(power < config$power_target)
), by = .(`Sizing` = sizing, `Test` = test)]
knitr::kable(
power_summary[order(Sizing, Test)],
caption = "Power synopsis across the scenario grid",
digits = 4
)| Sizing | Test | Scenarios | Minimum | Mean | Maximum | Below 90% |
|---|---|---|---|---|---|---|
| score | Score | 27 | 0.8771 | 0.8927 | 0.9060 | 21 |
| score | Wald | 27 | 0.8897 | 0.9037 | 0.9160 | 6 |
| wald | Score | 27 | 0.8743 | 0.8949 | 0.9129 | 19 |
| wald | Wald | 27 | 0.8943 | 0.9068 | 0.9183 | 3 |
power_display <- power_long[order(lambda1, k, gap_days, sizing, test),
.(
`Control rate` = lambda1,
Dispersion = k,
`Gap (days)` = gap_days,
Sizing = sizing,
N = n_total,
Test = test,
Power = round(power, 4),
SE = round(se, 4)
)
]
knitr::kable(
power_display,
caption = sprintf(
"Power: RR = %.2f, %s power sims/scenario",
config$rr_power,
format(config$n_sims_power, big.mark = ",")
)
)| Control rate | Dispersion | Gap (days) | Sizing | N | Test | Power | SE |
|---|---|---|---|---|---|---|---|
| 0.15 | 0.2 | 0 | score | 300 | Score | 0.9049 | 0.0050 |
| 0.15 | 0.2 | 0 | score | 300 | Wald | 0.9066 | 0.0049 |
| 0.15 | 0.2 | 0 | wald | 304 | Score | 0.8980 | 0.0051 |
| 0.15 | 0.2 | 0 | wald | 304 | Wald | 0.8989 | 0.0051 |
| 0.15 | 0.2 | 15 | score | 316 | Score | 0.8894 | 0.0053 |
| 0.15 | 0.2 | 15 | score | 316 | Wald | 0.8957 | 0.0052 |
| 0.15 | 0.2 | 15 | wald | 320 | Score | 0.9031 | 0.0050 |
| 0.15 | 0.2 | 15 | wald | 320 | Wald | 0.9077 | 0.0049 |
| 0.15 | 0.2 | 30 | score | 334 | Score | 0.8949 | 0.0052 |
| 0.15 | 0.2 | 30 | score | 334 | Wald | 0.9006 | 0.0051 |
| 0.15 | 0.2 | 30 | wald | 338 | Score | 0.8954 | 0.0052 |
| 0.15 | 0.2 | 30 | wald | 338 | Wald | 0.9046 | 0.0050 |
| 0.15 | 0.5 | 0 | score | 402 | Score | 0.9060 | 0.0049 |
| 0.15 | 0.5 | 0 | score | 402 | Wald | 0.9083 | 0.0049 |
| 0.15 | 0.5 | 0 | wald | 406 | Score | 0.9017 | 0.0050 |
| 0.15 | 0.5 | 0 | wald | 406 | Wald | 0.9049 | 0.0050 |
| 0.15 | 0.5 | 15 | score | 424 | Score | 0.8923 | 0.0052 |
| 0.15 | 0.5 | 15 | score | 424 | Wald | 0.9051 | 0.0050 |
| 0.15 | 0.5 | 15 | wald | 428 | Score | 0.9129 | 0.0048 |
| 0.15 | 0.5 | 15 | wald | 428 | Wald | 0.9183 | 0.0046 |
| 0.15 | 0.5 | 30 | score | 444 | Score | 0.8903 | 0.0053 |
| 0.15 | 0.5 | 30 | score | 444 | Wald | 0.9049 | 0.0050 |
| 0.15 | 0.5 | 30 | wald | 448 | Score | 0.8977 | 0.0051 |
| 0.15 | 0.5 | 30 | wald | 448 | Wald | 0.9091 | 0.0049 |
| 0.15 | 1.0 | 0 | score | 572 | Score | 0.8880 | 0.0053 |
| 0.15 | 1.0 | 0 | score | 572 | Wald | 0.8897 | 0.0053 |
| 0.15 | 1.0 | 0 | wald | 576 | Score | 0.8920 | 0.0052 |
| 0.15 | 1.0 | 0 | wald | 576 | Wald | 0.8943 | 0.0052 |
| 0.15 | 1.0 | 15 | score | 602 | Score | 0.8974 | 0.0051 |
| 0.15 | 1.0 | 15 | score | 602 | Wald | 0.9051 | 0.0050 |
| 0.15 | 1.0 | 15 | wald | 606 | Score | 0.8951 | 0.0052 |
| 0.15 | 1.0 | 15 | wald | 606 | Wald | 0.9046 | 0.0050 |
| 0.15 | 1.0 | 30 | score | 630 | Score | 0.8914 | 0.0053 |
| 0.15 | 1.0 | 30 | score | 630 | Wald | 0.9089 | 0.0049 |
| 0.15 | 1.0 | 30 | wald | 634 | Score | 0.8889 | 0.0053 |
| 0.15 | 1.0 | 30 | wald | 634 | Wald | 0.9126 | 0.0048 |
| 0.40 | 0.2 | 0 | score | 156 | Score | 0.8977 | 0.0051 |
| 0.40 | 0.2 | 0 | score | 156 | Wald | 0.9023 | 0.0050 |
| 0.40 | 0.2 | 0 | wald | 158 | Score | 0.8989 | 0.0051 |
| 0.40 | 0.2 | 0 | wald | 158 | Wald | 0.9046 | 0.0050 |
| 0.40 | 0.2 | 15 | score | 172 | Score | 0.8943 | 0.0052 |
| 0.40 | 0.2 | 15 | score | 172 | Wald | 0.9063 | 0.0049 |
| 0.40 | 0.2 | 15 | wald | 174 | Score | 0.9071 | 0.0049 |
| 0.40 | 0.2 | 15 | wald | 174 | Wald | 0.9183 | 0.0046 |
| 0.40 | 0.2 | 30 | score | 188 | Score | 0.8849 | 0.0054 |
| 0.40 | 0.2 | 30 | score | 188 | Wald | 0.8994 | 0.0051 |
| 0.40 | 0.2 | 30 | wald | 190 | Score | 0.8934 | 0.0052 |
| 0.40 | 0.2 | 30 | wald | 190 | Wald | 0.9106 | 0.0048 |
| 0.40 | 0.5 | 0 | score | 258 | Score | 0.9006 | 0.0051 |
| 0.40 | 0.5 | 0 | score | 258 | Wald | 0.9031 | 0.0050 |
| 0.40 | 0.5 | 0 | wald | 260 | Score | 0.9066 | 0.0049 |
| 0.40 | 0.5 | 0 | wald | 260 | Wald | 0.9117 | 0.0048 |
| 0.40 | 0.5 | 15 | score | 278 | Score | 0.8869 | 0.0054 |
| 0.40 | 0.5 | 15 | score | 278 | Wald | 0.9009 | 0.0051 |
| 0.40 | 0.5 | 15 | wald | 280 | Score | 0.8909 | 0.0053 |
| 0.40 | 0.5 | 15 | wald | 280 | Wald | 0.9034 | 0.0050 |
| 0.40 | 0.5 | 30 | score | 298 | Score | 0.8906 | 0.0053 |
| 0.40 | 0.5 | 30 | score | 298 | Wald | 0.9097 | 0.0048 |
| 0.40 | 0.5 | 30 | wald | 300 | Score | 0.8863 | 0.0054 |
| 0.40 | 0.5 | 30 | wald | 300 | Wald | 0.9074 | 0.0049 |
| 0.40 | 1.0 | 0 | score | 428 | Score | 0.8929 | 0.0052 |
| 0.40 | 1.0 | 0 | score | 428 | Wald | 0.8960 | 0.0052 |
| 0.40 | 1.0 | 0 | wald | 430 | Score | 0.9054 | 0.0049 |
| 0.40 | 1.0 | 0 | wald | 430 | Wald | 0.9083 | 0.0049 |
| 0.40 | 1.0 | 15 | score | 458 | Score | 0.8886 | 0.0053 |
| 0.40 | 1.0 | 15 | score | 458 | Wald | 0.9031 | 0.0050 |
| 0.40 | 1.0 | 15 | wald | 458 | Score | 0.8957 | 0.0052 |
| 0.40 | 1.0 | 15 | wald | 458 | Wald | 0.9074 | 0.0049 |
| 0.40 | 1.0 | 30 | score | 484 | Score | 0.8920 | 0.0052 |
| 0.40 | 1.0 | 30 | score | 484 | Wald | 0.9149 | 0.0047 |
| 0.40 | 1.0 | 30 | wald | 486 | Score | 0.8891 | 0.0053 |
| 0.40 | 1.0 | 30 | wald | 486 | Wald | 0.9160 | 0.0047 |
| 1.00 | 0.2 | 0 | score | 104 | Score | 0.8900 | 0.0053 |
| 1.00 | 0.2 | 0 | score | 104 | Wald | 0.8969 | 0.0051 |
| 1.00 | 0.2 | 0 | wald | 104 | Score | 0.9017 | 0.0050 |
| 1.00 | 0.2 | 0 | wald | 104 | Wald | 0.9097 | 0.0048 |
| 1.00 | 0.2 | 15 | score | 120 | Score | 0.8929 | 0.0052 |
| 1.00 | 0.2 | 15 | score | 120 | Wald | 0.9080 | 0.0049 |
| 1.00 | 0.2 | 15 | wald | 120 | Score | 0.8894 | 0.0053 |
| 1.00 | 0.2 | 15 | wald | 120 | Wald | 0.9029 | 0.0050 |
| 1.00 | 0.2 | 30 | score | 136 | Score | 0.8877 | 0.0053 |
| 1.00 | 0.2 | 30 | score | 136 | Wald | 0.9046 | 0.0050 |
| 1.00 | 0.2 | 30 | wald | 136 | Score | 0.8840 | 0.0054 |
| 1.00 | 0.2 | 30 | wald | 136 | Wald | 0.9051 | 0.0050 |
| 1.00 | 0.5 | 0 | score | 206 | Score | 0.9046 | 0.0050 |
| 1.00 | 0.5 | 0 | score | 206 | Wald | 0.9089 | 0.0049 |
| 1.00 | 0.5 | 0 | wald | 206 | Score | 0.8914 | 0.0053 |
| 1.00 | 0.5 | 0 | wald | 206 | Wald | 0.8960 | 0.0052 |
| 1.00 | 0.5 | 15 | score | 226 | Score | 0.8823 | 0.0054 |
| 1.00 | 0.5 | 15 | score | 226 | Wald | 0.8946 | 0.0052 |
| 1.00 | 0.5 | 15 | wald | 226 | Score | 0.8849 | 0.0054 |
| 1.00 | 0.5 | 15 | wald | 226 | Wald | 0.9000 | 0.0051 |
| 1.00 | 0.5 | 30 | score | 244 | Score | 0.8771 | 0.0055 |
| 1.00 | 0.5 | 30 | score | 244 | Wald | 0.9029 | 0.0050 |
| 1.00 | 0.5 | 30 | wald | 244 | Score | 0.8826 | 0.0054 |
| 1.00 | 0.5 | 30 | wald | 244 | Wald | 0.9086 | 0.0049 |
| 1.00 | 1.0 | 0 | score | 376 | Score | 0.9006 | 0.0051 |
| 1.00 | 1.0 | 0 | score | 376 | Wald | 0.9031 | 0.0050 |
| 1.00 | 1.0 | 0 | wald | 378 | Score | 0.9060 | 0.0049 |
| 1.00 | 1.0 | 0 | wald | 378 | Wald | 0.9086 | 0.0049 |
| 1.00 | 1.0 | 15 | score | 404 | Score | 0.9054 | 0.0049 |
| 1.00 | 1.0 | 15 | score | 404 | Wald | 0.9160 | 0.0047 |
| 1.00 | 1.0 | 15 | wald | 404 | Score | 0.8903 | 0.0053 |
| 1.00 | 1.0 | 15 | wald | 404 | Wald | 0.9086 | 0.0049 |
| 1.00 | 1.0 | 30 | score | 426 | Score | 0.8783 | 0.0055 |
| 1.00 | 1.0 | 30 | score | 426 | Wald | 0.9057 | 0.0049 |
| 1.00 | 1.0 | 30 | wald | 426 | Score | 0.8743 | 0.0056 |
| 1.00 | 1.0 | 30 | wald | 426 | Wald | 0.9014 | 0.0050 |
power_long[, scenario := paste0("λ₁=", lambda1, " k=", k)]
p_power <- ggplot(power_long,
aes(x = scenario, y = power,
color = combo, shape = test)) +
geom_point(size = 2.5, position = position_dodge(width = 0.5)) +
geom_errorbar(aes(ymin = power - 1.96 * se,
ymax = power + 1.96 * se),
width = 0.2, position = position_dodge(width = 0.5)) +
geom_hline(yintercept = config$power_target, linetype = "dashed", color = "grey40") +
facet_wrap(~ paste0("Gap = ", gap_days, "d")) +
labs(
title = "Power: sizing method × test type",
subtitle = sprintf("Target = %.0f%%, RR = %.2f",
100 * config$power_target, config$rr_power),
x = NULL, y = "Power",
color = "Sizing / Test", shape = "Test"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
p_powerUnder \(H_0\), the Z-statistics should follow \(N(0, 1)\) if the asymptotic approximation holds.
if (!is.null(res$z_density_null)) {
z_density_null <- as.data.table(res$z_density_null)
} else {
z_null <- as.data.table(res$z_sample_null)
sc_info <- data.table(
scenario_id = seq_len(nrow(scenarios)),
scenarios[, .(lambda1, k, gap_days, sizing)]
)
z_null <- merge(z_null, sc_info, by = "scenario_id")
z_null[, label := sprintf("l1=%.2f k=%.1f gap=%dd (%s)",
lambda1, k, gap_days, sizing)]
z_null_long <- melt(
z_null,
id.vars = c("scenario_id", "label", "sizing"),
measure.vars = c("z_wald", "z_score"),
variable.name = "test",
value.name = "z"
)
z_null_long[, test := fifelse(test == "z_wald", "Wald", "Score")]
z_null_long <- z_null_long[is.finite(z)]
z_density_null <- z_null_long[, {
dens <- stats::density(z, from = -4, to = 4, n = 128)
.(z = dens$x, density = dens$y)
}, by = .(scenario_id, label, sizing, test)]
}
normal_curve <- data.table(
z = seq(-4, 4, length.out = 128),
density = dnorm(seq(-4, 4, length.out = 128))
)
p_z <- ggplot(z_density_null, aes(x = z, y = density, color = test)) +
geom_line(linewidth = 0.6) +
geom_line(data = normal_curve, aes(x = z, y = density),
inherit.aes = FALSE, color = "black", linetype = "dashed",
linewidth = 0.4) +
facet_wrap(~ label, scales = "free_y") +
labs(
title = "Null Z-score densities: Wald vs Score",
subtitle = "Dashed line = N(0,1) reference",
x = "Z-statistic", y = "Density",
color = "Test"
) +
theme_minimal() +
coord_cartesian(xlim = c(-4, 4))
p_zWhen the negative binomial MLE fails to converge or yields
non-overdispersed estimates, mutze_test() falls back to
Poisson or method-of-moments estimation.
null_fb <- as.data.table(res$null_summary)
fb_display <- null_fb[, .(
`Control rate` = lambda1,
Dispersion = k,
`Gap (days)` = gap_days,
Sizing = sizing,
`Poisson (Wald)` = round(pct_fallback_poisson_wald, 1),
`MoM (Wald)` = round(pct_fallback_mom_wald, 1),
`Poisson (Score)` = round(pct_fallback_poisson_score, 1),
`MoM (Score)` = round(pct_fallback_mom_score, 1)
)]
knitr::kable(
fb_display,
caption = "Fallback method frequency (%, null sims)",
digits = 1
)| Control rate | Dispersion | Gap (days) | Sizing | Poisson (Wald) | MoM (Wald) | Poisson (Score) | MoM (Score) |
|---|---|---|---|---|---|---|---|
| 0.1 | 0.2 | 0 | wald | 0.2 | 0.0 | 0.2 | 0.0 |
| 0.4 | 0.2 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 1.0 | 0.2 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.5 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.4 | 0.5 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 1.0 | 0.5 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 1.0 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.4 | 1.0 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 1.0 | 1.0 | 0 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.2 | 15 | wald | 0.4 | 0.1 | 0.4 | 0.1 |
| 0.4 | 0.2 | 15 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.2 | 15 | wald | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.5 | 15 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.4 | 0.5 | 15 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.5 | 15 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 1.0 | 15 | wald | 0.0 | 0.2 | 0.0 | 0.2 |
| 0.4 | 1.0 | 15 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 1.0 | 15 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 0.2 | 30 | wald | 0.5 | 0.2 | 0.5 | 0.2 |
| 0.4 | 0.2 | 30 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.2 | 30 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 0.5 | 30 | wald | 0.0 | 0.2 | 0.0 | 0.2 |
| 0.4 | 0.5 | 30 | wald | 0.0 | 0.2 | 0.0 | 0.1 |
| 1.0 | 0.5 | 30 | wald | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 1.0 | 30 | wald | 0.0 | 0.2 | 0.0 | 0.2 |
| 0.4 | 1.0 | 30 | wald | 0.0 | 0.2 | 0.0 | 0.2 |
| 1.0 | 1.0 | 30 | wald | 0.0 | 0.2 | 0.0 | 0.2 |
| 0.1 | 0.2 | 0 | score | 0.2 | 0.0 | 0.2 | 0.0 |
| 0.4 | 0.2 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 1.0 | 0.2 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.5 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.4 | 0.5 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 1.0 | 0.5 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 1.0 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.4 | 1.0 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 1.0 | 1.0 | 0 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.2 | 15 | score | 0.4 | 0.1 | 0.3 | 0.1 |
| 0.4 | 0.2 | 15 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.2 | 15 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.5 | 15 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.4 | 0.5 | 15 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.5 | 15 | score | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 1.0 | 15 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.4 | 1.0 | 15 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 1.0 | 15 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 0.2 | 30 | score | 0.5 | 0.1 | 0.4 | 0.1 |
| 0.4 | 0.2 | 30 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.2 | 30 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 0.5 | 30 | score | 0.0 | 0.2 | 0.0 | 0.2 |
| 0.4 | 0.5 | 30 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 1.0 | 0.5 | 30 | score | 0.0 | 0.1 | 0.0 | 0.1 |
| 0.1 | 1.0 | 30 | score | 0.0 | 0.2 | 0.0 | 0.2 |
| 0.4 | 1.0 | 30 | score | 0.0 | 0.2 | 0.0 | 0.2 |
| 1.0 | 1.0 | 30 | score | 0.0 | 0.2 | 0.0 | 0.2 |
mutze_test(test_type = "score"),
sim_gs_nbinom(test_type = "score"), or
sim_ssr_nbinom(test_type = "score"); compare Wald and score
sizing rather than assuming the two-variance score formula will
automatically deliver nominal power.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.