## ----echo = FALSE-------------------------------------------------------------
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = TRUE)

## ----setup--------------------------------------------------------------------
library(testflow)

## ----eval = FALSE-------------------------------------------------------------
# sample_size_continuous(
#   design = c("parallel", "paired", "repeated"),
#   objective = c("superiority", "noninferiority", "equivalence"),
#   delta = NULL, sd = NULL, sd_diff = NULL, expected_difference = 0,
#   margin = NULL, alpha = 0.05, power = 0.90, allocation = 1, dropout = 0,
#   n_time = 2, correlation = 0.5
# )

## -----------------------------------------------------------------------------
sample_size_continuous(
  design = "parallel", objective = "superiority",
  delta = 5, sd = 10, allocation = 1, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_continuous(
  design = "parallel", objective = "noninferiority",
  delta = 2, expected_difference = 0.5, sd = 10, alpha = 0.025, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_continuous(
  design = "parallel", objective = "equivalence",
  delta = 4, expected_difference = 1, sd = 10, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_continuous(
  design = "parallel", objective = "equivalence",
  delta = 4, expected_difference = 0, sd = 10, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_continuous(
  design = "paired", objective = "superiority",
  delta = 5, sd_diff = 10, alpha = 0.05, power = 0.90
)

sample_size_continuous(
  design = "paired", objective = "noninferiority",
  delta = 2, expected_difference = 0.5, sd_diff = 10, alpha = 0.025, power = 0.90
)

sample_size_continuous(
  design = "paired", objective = "equivalence",
  delta = 4, expected_difference = 0, sd_diff = 10, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_continuous(
  design = "repeated", n_time = 4, correlation = 0.5,
  objective = "superiority", delta = 5, sd_diff = 10, alpha = 0.05, power = 0.90
)

sample_size_continuous(
  design = "repeated", n_time = 4, correlation = 0.3,
  objective = "noninferiority", delta = 2, expected_difference = 0.5,
  sd_diff = 10, alpha = 0.025, power = 0.90
)

sample_size_continuous(
  design = "repeated", n_time = 4, correlation = 0.3,
  objective = "equivalence", delta = 4, expected_difference = 0,
  sd_diff = 10, alpha = 0.05, power = 0.90
)

## ----eval = FALSE-------------------------------------------------------------
# sample_size_binary(
#   design = c("parallel", "paired", "repeated"),
#   objective = c("superiority", "noninferiority", "equivalence"),
#   p1, p2, margin = NULL, method = c("pooled", "anticipated"),
#   discordant_or = NULL, discordance_rate = NULL, p10 = NULL, p01 = NULL,
#   alpha = 0.05, power = 0.90, allocation = 1, dropout = 0, n_time = 2
# )

## -----------------------------------------------------------------------------
sample_size_binary(
  design = "parallel", objective = "superiority",
  p1 = 0.4, p2 = 0.25, method = "pooled", alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_binary(
  design = "parallel", objective = "superiority",
  p1 = 0.4, p2 = 0.25, method = "anticipated", alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_binary(
  design = "parallel", objective = "noninferiority",
  p1 = 0.5, p2 = 0.45, margin = 0.1, alpha = 0.025, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_binary(
  design = "parallel", objective = "equivalence",
  p1 = 0.42, p2 = 0.4, margin = 0.15, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_binary(
  design = "parallel", objective = "equivalence",
  p1 = 0.3, p2 = 0.3, margin = 0.15, allocation = 2, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_binary(
  design = "paired", objective = "superiority",
  discordant_or = 2, discordance_rate = 0.3, alpha = 0.05, power = 0.90
)

sample_size_binary(
  design = "paired", objective = "superiority",
  p10 = 0.2, p01 = 0.1, alpha = 0.05, power = 0.90
)

sample_size_binary(
  design = "repeated", n_time = 2, objective = "superiority",
  p10 = 0.2, p01 = 0.1, alpha = 0.05, power = 0.90
)

## ----eval = FALSE-------------------------------------------------------------
# sample_size_survival(
#   design = c("parallel"),
#   objective = c("superiority", "noninferiority", "equivalence"),
#   hr, margin_hr = NULL, lower = NULL, upper = NULL,
#   survival_a = NULL, survival_b = NULL,
#   alpha = 0.05, power = 0.90, allocation = 1, dropout = 0,
#   method = c("exponential", "ph_only"),
#   accrual_duration = NULL, follow_up = NULL
# )

## -----------------------------------------------------------------------------
sample_size_survival(
  hr = 0.7, method = "exponential", alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_survival(
  hr = 0.7, method = "ph_only", alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_survival(
  hr = 0.7, survival_a = 0.8, survival_b = 0.7, alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_survival(
  hr = 0.7, survival_a = 0.8, survival_b = 0.7, alpha = 0.05, power = 0.90,
  accrual_duration = 12, follow_up = 24
)

## -----------------------------------------------------------------------------
sample_size_survival(
  hr = 0.85, objective = "noninferiority", margin_hr = 1.25,
  survival_a = 0.75, survival_b = 0.75, alpha = 0.025, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_survival(
  hr = 1.0, objective = "equivalence", lower = 0.8, upper = 1.25,
  survival_a = 0.75, survival_b = 0.75, alpha = 0.05, power = 0.90
)

## ----eval = FALSE-------------------------------------------------------------
# sample_size_ordinal(
#   design = c("parallel"), objective = c("superiority"),
#   p_superiority = NULL,
#   alpha = 0.05, power = 0.90, dropout = 0
# )

## -----------------------------------------------------------------------------
sample_size_ordinal(p_superiority = 0.65, alpha = 0.05, power = 0.90)

## ----eval = FALSE-------------------------------------------------------------
# sample_size_bioequivalence(
#   design = c("crossover", "parallel"), gmr = 1,
#   cv_within = NULL, cv_between = NULL,
#   lower = 0.80, upper = 1.25, alpha = 0.05, power = 0.90,
#   allocation = 1, dropout = 0,
#   method = c("iterative_tost", "normal_approx")
# )

## -----------------------------------------------------------------------------
sample_size_bioequivalence(
  design = "crossover", gmr = 0.95, cv_within = 0.30,
  alpha = 0.05, power = 0.90
)

sample_size_bioequivalence(
  design = "parallel", gmr = 0.95, cv_between = 0.35, allocation = 1.5,
  alpha = 0.05, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_bioequivalence(
  design = "crossover", gmr = 0.95, cv_within = 0.30,
  alpha = 0.05, power = 0.90, method = "normal_approx"
)

## ----eval = FALSE-------------------------------------------------------------
# sample_size_precision(
#   endpoint = c("continuous", "binary"),
#   design = c("one_sample", "two_sample", "odds_ratio"),
#   width, sd = NULL, p = NULL, p1 = NULL, p2 = NULL,
#   alpha = 0.05, allocation = 1, dropout = 0, conservative = FALSE,
#   method = c("wald", "wilson", "exact"),
#   criterion = c("expected", "worst_case"),
#   min_expected_events = 5, max_n = 1e7
# )

## -----------------------------------------------------------------------------
sample_size_precision(endpoint = "continuous", design = "one_sample", width = 2, sd = 10)
sample_size_precision(endpoint = "continuous", design = "two_sample", width = 2, sd = 10, allocation = 1.5)
sample_size_precision(endpoint = "binary", design = "one_sample", width = 0.05, p = 0.3)
sample_size_precision(endpoint = "binary", design = "one_sample", width = 0.05, conservative = TRUE)
sample_size_precision(endpoint = "binary", design = "two_sample", width = 0.08, p1 = 0.4, p2 = 0.3, allocation = 2)
sample_size_precision(endpoint = "binary", design = "odds_ratio", width = 0.3, p1 = 0.4, p2 = 0.3, allocation = 2)

## -----------------------------------------------------------------------------
# Wald (backward-compatible default)
sample_size_precision(endpoint = "binary", design = "one_sample", width = 0.02, p = 0.01)

# Wilson score, iterative search - generally a smaller, better-calibrated n
# for rare p than Wald
sample_size_precision(endpoint = "binary", design = "one_sample", width = 0.02, p = 0.01, method = "wilson")

# Exact Clopper-Pearson, requiring the precision target to hold over a
# prevalence-local band of event counts rather than just the anticipated one
x <- sample_size_precision(
  endpoint = "binary", design = "one_sample", width = 0.005,
  p = 0.001, method = "exact", criterion = "worst_case"
)
x$diagnostics

## ----eval = FALSE-------------------------------------------------------------
# sample_size_cluster_adjust(n_ind, m, rho, cv_m = NULL)

## -----------------------------------------------------------------------------
sample_size_cluster_adjust(100, m = 20, rho = 0.02)
sample_size_cluster_adjust(100, m = 20, rho = 0.02, cv_m = 0.3)

## -----------------------------------------------------------------------------
sample_size(
  endpoint = "binary", design = "parallel", objective = "noninferiority",
  p1 = 0.5, p2 = 0.45, margin = 0.1, alpha = 0.025, power = 0.90
)

## -----------------------------------------------------------------------------
sample_size_adjust_dropout(100, dropout = 0.15)

## -----------------------------------------------------------------------------
x <- sample_size_continuous(
  design = "paired", objective = "superiority",
  delta = 5, sd_diff = 10, alpha = 0.05, power = 0.90
)

x                       # print.sample_size(): formatted console report
summary(x)              # summary.sample_size(): compact summary list
report(x)               # report.sample_size(): report-ready sentence
as_tibble(x)            # as_tibble.sample_size(): one-row tidy summary
plot(x, type = "summary") # raw vs. dropout-adjusted n bar chart
plot(x, type = "curve")   # power curve, when curve data is available
plot(x, type = "both")    # both plots stacked (requires the patchwork package)

