calc-sample-size
Interactive sample size calculator for medical research. Decision-tree guided test selection, reproducible R/Python code, effect size interpretation, and IRB-ready justification text. Supports diagnostic accuracy, agreement, proportions, continuous outcomes, survival, ANOVA, logi
Install
npx skills add https://github.com/Aperivue/medsci-skills/tree/main/skills/calc-sample-size
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install aperivue-medsci-skills@llmmart
git clone https://github.com/Aperivue/medsci-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole aperivue/medsci-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Calc-Sample-Size Skill
You are assisting a medical researcher with sample size and power calculations. Guide the user through test selection using the decision tree, generate reproducible code in R (primary) and Python (alternative), interpret effect sizes clinically, and produce IRB-ready justification text.
Reference Files
- Formulas:
${CLAUDE_SKILL_DIR}/references/formulas.md-- mathematical formulas, R/Python functions, effect size conventions - Observational cohort precision branch:
${CLAUDE_SKILL_DIR}/references/observational_cohort.md - Prediction-model / medical-AI sample size (Riley):
${CLAUDE_SKILL_DIR}/references/prediction_model_sample_size.md-- the current TRIPOD+AI-aligned standard for a clinical prediction/classification model (development viapmsampsize, external validation viapmvalsampsize, net-benefit precision). Use this instead of EPV-10 whenever the goal is risk prediction for use rather than a single-predictor hypothesis test (Tests 12-13). - MRMC reader-study sample size (Obuchowski–Rockette):
${CLAUDE_SKILL_DIR}/references/mrmc_reader_study_sample_size.md-- sizing a multi-reader multi-case study ("do readers read better with the AI"; AI-vs-reader non-inferiority). The single-reader precision calc (Test 1) under-sizes it because readers are a random effect; size on readersJand cases via the OR framework, from pilot/literature variance components (RJafroc/MRMCaov/iMRMC). Use whenever a reader study is the design (Test 14). - Segmentation-metric precision (Dice / HD95 / NSD):
${CLAUDE_SKILL_DIR}/references/segmentation_metric_sample_size.md-- sizing a segmentation validation by the precision of the per-case overlap/boundary score (not a proportion):n ≈ (1.96·SD/δ)²from the pilot SD of per-case Dice, per structure (size on the worst), bootstrap-BCa CI, paired for a model comparison, and size the external cohort. Use whenever the outcome is Dice/HD95/NSD (Test 15). - Between-model comparison sample size:
${CLAUDE_SKILL_DIR}/references/multi_model_comparison_sample_size.md-- sizing a study whose claim is that one model beats others (several models head-to-head). Single-model precision under-sizes it: power the difference. Pair the design (same cases through all models) → size on the SD of the per-case difference; DeLong for a paired ΔAUC, bootstrap-paired for ΔDice; for >2 models pre-specify one primary contrast or pay the family-wise multiplicity; and for a ranking claim, seed for rank stability (Nadeau–Bengio variance, Demšar critical-difference). Use whenever the endpoint is "model A > B/C/…" (Test 16). - Segmentation usability sample size:
${CLAUDE_SKILL_DIR}/references/segmentation_acceptability_sample_size.md-- sizing a usability claim rather than a metric: the acceptability endpoint is a proportion (n ≈ (z/δ)²p(1−p), size on the pessimistic p, size per structure class); ratings by m readers are nested, so pooling n·m overstates precision by1+(m−1)ρ; bounding a catastrophic-failure rate needs the rule of three (≤1% ⇒ ~300 clean cases — a metric-precision study bounds nothing); edit time is a paired per-case difference sized per structure and per site. Use whenever the claim is "clinicians can use this" (Test 17). - Justification prose exemplars:
${CLAUDE_SKILL_DIR}/references/justification_examples.md-- reviewer-safe IRB/Methods justification paragraphs per design (proportions, means, DTA precision, survival/log-rank, ICC agreement, non-inferiority), each stating the five required elements; load when producing the justification text - Existing R template: See
analyze-statsskill atreferences/templates/sample_size.Rfor the 7 original tests
Read formulas.md before generating calculation code.
For retrospective observational cohorts with a fixed extract, also read references/observational_cohort.md and report event budget / confidence-interval precision instead of forcing a prospective recruitment-style power calculation.
Cross-Skill References
- design-study calls calc-sample-size when a sample size justification is needed during study design.
- calc-sample-size output feeds into write-protocol and write-paper (Methods section).
- Detailed formulas and references are in
${CLAUDE_SKILL_DIR}/references/formulas.md.
Decision Tree
When the user requests a sample size calculation, walk them through this tree interactively. Ask one question at a time. Do not assume answers.
What is your primary outcome?
|
+-- Binary (yes/no, positive/negative)
| |
| +-- Paired data (same subjects, two methods)?
| | +-- YES --> [5] McNemar test
| | +-- NO --> How many groups?
| | +-- 2 groups, superiority --> [4] Two-proportion comparison (chi-square)
| | +-- 2 groups, non-inferiority --> [10] Non-inferiority / equivalence
| | +-- Multivariable model --> single-predictor hypothesis test? --> [9] Logistic regression
| | --> clinical prediction / AI model for use?
| | +-- developing the model --> [12] Prediction-model development (Riley)
| | +-- externally validating --> [13] External-validation (Riley)
| |
+-- Continuous (measurement, score)
| |
| +-- How many groups?
| +-- 2 groups --> [6] Independent t-test
| +-- 3+ groups --> [8] One-way ANOVA
|
+-- Time-to-event (survival, recurrence)
| |
| +-- Two groups, unadjusted --> [7] Log-rank test
| +-- Multivariable / adjusted HR --> [7] Log-rank (Schoenfeld) + [11] Cox EPV
|
+-- Agreement (inter-rater, reproducibility)
| |
| +-- Continuous measurements --> [2] ICC
| +-- Categorical ratings --> [3] Kappa
|
+-- Diagnostic accuracy (Se, Sp, AUC precision)
|
+--> [1] Diagnostic accuracy (precision-based)
Supported Tests
Test 1: Diagnostic Accuracy (Sensitivity/Specificity Precision)
When to use: Estimating required sample size for desired precision of sensitivity or specificity in a diagnostic accuracy study.
Required parameters (ask the user):
| Parameter | Description | Default |
|---|---|---|
sensitivity_expected |
Expected sensitivity | 0.85 |
ci_half_width |
Desired half-width of 95% CI | 0.05 |
prevalence |
Disease prevalence in study population | 0.30 |
alpha |
Significance level | 0.05 |
attrition_rate |
Expected dropout/exclusion rate | 0.15 |
Effect size interpretation: The CI half-width determines precision. A half-width of 0.05 means the 95% CI for sensitivity will be within +/-5 percentage points. Narrower CIs require larger samples.
Test 2: ICC Agreement (Bonett 2002)
When to use: Inter-rater or intra-rater agreement for continuous measurements (e.g., tumor size, angle measurement).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
icc_expected |
Expected ICC value | 0.75 |
icc_null |
Null hypothesis ICC (lower bound) | 0.50 |
n_raters |
Number of raters | 2 |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.10 |
Effect size interpretation: ICC < 0.50 = poor, 0.50-0.75 = moderate, 0.75-0.90 = good, > 0.90 = excellent (Koo & Li, 2016).
Test 3: Kappa Agreement (Donner & Eliasziw 1992)
When to use: Inter-rater agreement for categorical ratings (e.g., BI-RADS category, lesion present/absent).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
kappa_expected |
Expected kappa value | 0.70 |
kappa_null |
Null hypothesis kappa | 0.40 |
po_expected |
Expected proportion of agreement | 0.75 |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.10 |
Effect size interpretation: Kappa < 0.20 = slight, 0.21-0.40 = fair, 0.41-0.60 = moderate, 0.61-0.80 = substantial, 0.81-1.00 = almost perfect (Landis & Koch, 1977).
Test 4: Two-Proportion Comparison (Chi-Square)
When to use: Comparing proportions between two independent groups (e.g., AI detection rate vs. conventional detection rate).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
p1 |
Proportion in group 1 | -- |
p2 |
Proportion in group 2 | -- |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.15 |
Effect size interpretation: Cohen's h = 2 * arcsin(sqrt(p1)) - 2 * arcsin(sqrt(p2)). Small = 0.20, medium = 0.50, large = 0.80.
Test 5: McNemar Test (Paired Proportions)
When to use: Paired binary outcomes (e.g., two readers reading same cases, before/after on same patients).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
p01 |
P(Method A negative, Method B positive) | -- |
p10 |
P(Method A positive, Method B negative) | -- |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.10 |
Effect size interpretation: The ratio p10/p01 (discordant ratio) drives the required sample size. Larger asymmetry in discordant pairs means fewer subjects needed. Only discordant pairs contribute information.
Test 6: Independent t-Test
When to use: Comparing means between two independent groups (e.g., lesion size in malignant vs. benign).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
mean_diff |
Expected mean difference | -- |
pooled_sd |
Pooled standard deviation (from literature/pilot) | -- |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.15 |
Effect size interpretation: Cohen's d = mean_diff / pooled_sd. Small = 0.20, medium = 0.50, large = 0.80. In clinical terms, d = 0.50 means the groups differ by half a standard deviation.
Test 7: Survival / Log-Rank Test (Schoenfeld 1981)
When to use: Comparing survival or time-to-event between two groups (e.g., treatment vs. control, RFA vs. surgery).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
hr |
Expected hazard ratio | -- |
median_ctrl |
Median survival in control arm (months) | -- |
accrual_time |
Accrual period (months) | 12 |
follow_up |
Follow-up after accrual (months) | 24 |
drop_rate |
Annual dropout rate | 0.05 |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
Effect size interpretation: HR < 1 favors treatment. HR = 0.50 means treatment halves the hazard (strong effect). HR = 0.80 is a modest 20% reduction. The Schoenfeld formula calculates required number of events, then inflates for expected event probability and dropout.
Test 8: One-Way ANOVA (NEW)
When to use: Comparing means across 3 or more independent groups (e.g., comparing AI model performance across 3 architectures, comparing measurement accuracy across multiple readers).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
k |
Number of groups | -- |
f |
Cohen's f effect size | -- |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.15 |
Help user estimate Cohen's f:
- If the user knows group means and pooled SD: f = sigma_means / pooled_SD
- If the user knows eta-squared: f = sqrt(eta_sq / (1 - eta_sq))
- Benchmarks: small = 0.10, medium = 0.25, large = 0.40
R function: pwr::pwr.anova.test(k, f, sig.level, power)
Python equivalent: statsmodels.stats.power.FTestAnovaPower().solve_power(effect_size, nobs, alpha, power, k_groups)
Effect size interpretation: Cohen's f = 0.25 (medium) means the group means span about half a pooled SD. In clinical terms, this is typically a meaningful difference across treatment arms or measurement methods.
Test 9: Logistic Regression (NEW)
When to use: Multivariable binary outcome models (e.g., predicting malignancy from multiple imaging features). Two approaches are provided.
Required parameters:
| Parameter | Description | Default |
|---|---|---|
n_predictors |
Number of predictor variables | -- |
event_rate |
Expected event rate (proportion with outcome) | -- |
or_interest |
Odds ratio of interest (for Hsieh formula) | -- |
r2_other |
R-squared of covariate with other predictors | 0.0 |
alpha |
Significance level | 0.05 |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.10 |
Approach A: Peduzzi Rule of Thumb (EPV >= 10)
- N_events = 10 * n_predictors
- N_total = N_events / event_rate
- Simple, widely cited, conservative. Use as a minimum baseline for a single-predictor hypothesis test only. For a clinical prediction / medical-AI model intended for use, EPV-10 is outdated and reviewer-vulnerable — use the Riley criteria in Test 12 (development) / Test 13 (validation) instead.
Approach B: Hsieh (1989) Formula
- Uses the OR of interest for the primary predictor to calculate a more precise sample size.
- Accounts for correlation with other predictors via R-squared adjustment.
Always report both approaches and recommend the larger N.
Effect size interpretation: OR = 1.5 is a small-to-moderate effect; OR = 2.0 is moderate; OR = 3.0+ is large. The Peduzzi rule ensures model stability; the Hsieh formula targets power for the primary predictor.
Test 10: Non-Inferiority / Equivalence (NEW)
When to use: Demonstrating that a new method is not worse than the standard by more than a pre-specified margin (non-inferiority) or that two methods are equivalent within a margin (equivalence / TOST).
Required parameters:
| Parameter | Description | Default |
|---|---|---|
design |
"non-inferiority" or "equivalence" | "non-inferiority" |
outcome_type |
"proportion" or "continuous" | -- |
p_reference |
Reference group proportion (if proportion) | -- |
margin |
Non-inferiority or equivalence margin (delta) | -- |
sd |
Standard deviation (if continuous) | -- |
alpha |
One-sided alpha for NI; two one-sided for equivalence | 0.025 (NI) / 0.05 (equiv) |
power |
Desired power | 0.80 |
attrition_rate |
Expected dropout rate | 0.15 |
Key guidance for margin selection:
- The margin must be clinically justified and smaller than the effect of the reference treatment vs. placebo.
- Common approach: margin = 50% of the established treatment effect (preservation of effect).
- For proportions: absolute difference margin (e.g., delta = 0.10 means new method can be at most 10 percentage points worse).
- For continuous: margin in the same unit as the outcome.
Non-inferiority (one-sided test):
- H0: new - reference <= -margin (new is inferior)
- H1: new - reference > -margin (new is non-inferior)
- Alpha is one-sided (typically 0.025).
Equivalence (TOST):
- H0: |new - reference| >= margin
- H1: |new - reference| < margin
- Two one-sided tests, each at alpha (typically 0.05 overall).
Effect size interpretation: The margin defines the largest clinically acceptable difference. A smaller margin requires a larger sample. Always justify the margin based on clinical reasoning and prior literature.
Test 11: Cox Regression EPV (Events Per Variable)
When to use: Multivariable Cox proportional hazards models — ensuring enough events for stable model estimates. Same EPV logic as logistic regression (Test 9), applied to time-to-event outcomes.
Required parameters:
| Parameter | Description | Default |
|---|---|---|
n_predictors |
Number of predictor variables in Cox model | -- |
event_rate |
Expected proportion of subjects experiencing the event | -- |
epv |
Events per variable target | 10 |
attrition_rate |
Expected dropout rate | 0.10 |
Formula:
N_events = EPV × n_predictors
N_total = N_events / event_rate
N_adj = N_total / (1 - attrition_rate)
EPV guidelines:
- EPV >= 10: minimum for stable estimates (Peduzzi et al., 1995)
- EPV >= 20: recommended for reliable CI coverage and type I error control
- EPV < 5: model likely unstable — reduce predictors or use penalized methods
Effect size interpretation: The EPV rule ensures model stability, not power for a specific HR. If the user also needs power for detecting a specific HR, combine with Test 7 (log-rank/Schoenfeld) and report the larger N.
Always report both approaches (EPV minimum + Schoenfeld power, if HR is available) and recommend the larger N.
Test 12: Prediction-Model Development (Riley)
When to use: developing a clinical prediction / classification model (including a medical-AI model evaluated as one) — the goal is risk prediction for use, not a single predictor's hypothesis test. EPV-10 (Tests 9/11) is outdated here.
Approach: the minimum N is the largest satisfying all four Riley criteria
simultaneously — global shrinkage ≥ 0.9, apparent–adjusted R² gap ≤ 0.05, precise overall
risk estimate, and (time-to-event) precise baseline survival. Implemented in R pmsampsize.
Required parameters: number of candidate predictor parameters (count dummy/non-linear terms), a conservative expected C-statistic or Cox-Snell R² (with its literature source), and outcome prevalence (binary) or event rate + mean follow-up (time-to-event).
Read ${CLAUDE_SKILL_DIR}/references/prediction_model_sample_size.md for the criteria, the
pmsampsize code, and the reporting requirements. Report N + required events + the binding
criterion + the assumed C/R² and its source.
Test 13: External-Validation Sample Size (Riley)
When to use: sizing an external validation of an existing prediction/AI model.
Approach: size to estimate the key validation metrics precisely enough to be
conclusive — target the CI width of the C-statistic, the calibration slope, the
calibration-in-the-large / O:E ratio, and (if a utility claim) net benefit.
Implemented in R pmvalsampsize. A floor of ≥ 100 events and ≥ 100 non-events applies, but
the precise target is usually larger.
Required parameters: expected prevalence, anticipated C-statistic, and the target CI widths.
Read ${CLAUDE_SKILL_DIR}/references/prediction_model_sample_size.md for the pmvalsampsize
code. Report the targeted CI widths and the resulting events / non-events.
Test 14: MRMC Reader Study (Obuchowski–Rockette)
When to use: sizing a multi-reader multi-case (MRMC) reader study — "do readers read better with the AI", or "is the AI non-inferior to readers". The single-reader AUC-precision calculation (Test 1) under-sizes this: readers as well as cases are random, so power must cover the reader-variance term, and a null from an under-sized reader study is inconclusive, not negative.
Approach: invert the OR variance formula over the number of readers J and the case counts
N⁺/N⁻; report the J × N power grid (past a modest case count, adding readers usually
buys more power than adding cases). Requires variance components from a pilot or literature —
the real bottleneck. Implemented in R RJafroc / MRMCaov / FDA iMRMC (integrate; do not
hand-roll the OR algebra).
Required parameters: the effect (ΔAUC, or the non-inferiority margin — an AI-vs-reader claim is usually NI), the expected AUC level, the variance components (pilot/literature), the design (fully-crossed vs crossover-with-washout), and power/α.
Read ${CLAUDE_SKILL_DIR}/references/mrmc_reader_study_sample_size.md for the framework, the
readers-vs-cases trade-off, software, and reporting. Reader-study design internals live in
design-study (reader_elicitation_design.md); an AI-vs-human-expert benchmark routes to
/design-ai-benchmarking.
Test 15: Segmentation-metric precision (Dice / HD95 / NSD)
When to use: sizing a segmentation validation — how many cases to estimate the segmentation metric (Dice / HD95 / NSD) precisely enough to be conclusive, or to separate two models. The proportion/events calcs (Tests 1, 12–13) do not apply: the outcome is a bounded, skewed per-case overlap/boundary score, not a proportion.
Approach: precision sizing n ≈ (1.96·SD/δ)² from the pilot/literature SD of per-case Dice
(per structure — size on the worst structure you must report, not the average); report the CI by
bootstrapping per-case values (BCa) — a t-interval is closed-form but Dice is bounded and
non-normal near the ceiling, so its coverage is not the coverage you asked for, and BCa must resample
whole patients, not structures. A model comparison on the same cases is paired (size on the SD of the per-case
difference, or an NI margin). Size the external cohort too — a precise external estimate is the
#1 acceptance lever.
Required parameters: the per-structure SD of per-case Dice (pilot/literature), the target precision δ or NI margin, and the metric.
Read ${CLAUDE_SKILL_DIR}/references/segmentation_metric_sample_size.md for the per-structure and
paired-comparison detail. The comparator/ablation the size serves lives in design-study
(combine_models_ablation_design.md); metric selection is /model-evaluation.
Test 16: Between-model comparison (is model A really better than B, C, …)
When to use: the claim is that one model outperforms others — several architectures / families compared head-to-head on the same task. Single-model precision (Test 1 AUC, Test 15 Dice) under-sizes it: two models can each have a tight CI and still overlap, so the difference must be powered.
Approach: run all models on the same cases (paired / within-case) and size on the SD of the
per-case difference — σ√(2(1−ρ)), below either marginal SD once ρ > 0.5, which shared easy/hard cases
usually clear. Use DeLong for a paired ΔAUC (or Obuchowski for the MRMC/clustered case) and a
bootstrap of the paired per-case differences for ΔDice; size so the delta CI excludes zero, or so its
lower bound clears the NI margin (the whole interval inside ±margin is equivalence, a stricter claim).
For >2 models, pre-specify one primary contrast (proposed vs a strong, fairly-tuned baseline) at
full α — or, if all pairwise are confirmatory, pay the family-wise correction (higher n per contrast).
For a ranking claim, a single-run leaderboard ranks by luck: train over multiple seeds
(Nadeau–Bengio corrected variance for repeated-CV differences) and leave models inside the Demšar
critical difference unranked — not separated by the test is not a demonstrated tie, and Demšar's N
counts independent datasets, not seeds.
Required parameters: the per-case-difference SD of the primary metric (pilot / prior head-to-head; per structure for segmentation), the metric + paired-CI method, the target δ or NI margin on the delta, the number of models + the primary contrast, and (for ranking) the seed-to-seed SD.
Read ${CLAUDE_SKILL_DIR}/references/multi_model_comparison_sample_size.md for the paired-difference,
multiplicity, and ranking-stability detail. The fair-comparison design the size serves lives in
design-study (multi_model_comparison_design.md); presenting it is make-figures
(exemplar_plots/model_comparison_leaderboard.md).
Test 17: Segmentation usability (acceptability rate, failure bound, edit time)
When to use: the claim is that a segmentation model is clinically usable — a share of cases a clinician accepts, a bounded catastrophic-failure rate, a time saving — not that its mean metric is high. Test 15 sizes a mean Dice to a precision and says nothing about any of these.
Approach: an acceptability endpoint is a proportion: n ≈ (z/δ)²·p(1−p) — ≈138 cases at
p = 0.90, δ = 0.05, but ≈384 at p = 0.50, so size on the pessimistic p unless a pilot in the same
anatomy says otherwise, and size per structure class (use-as-is rates for one pipeline have run
from ~40% for target volumes to ~89% for normal tissue). When m readers rate each case the ratings
are nested, not independent: pooling n·m overstates precision by DE ≈ 1 + (m−1)ρ (3 readers at
ρ = 0.5 halves it) — pre-specify either a case-level consensus rule or a mixed-effects/GEE analysis.
To bound a catastrophic-failure rate, zero events in n cases gives an upper bound of ≈ 3/n
(rule of three), so ≤1% needs ~300 clean cases; a 40–60-case study bounds nothing below ~5–8%.
For an edit-time claim, size the paired per-case time difference (as Test 16) per structure and
per site — pooled savings coexist with structures and centres showing none.
Required parameters: the acceptability scale and which level counts as accepted (use-as-is vs after minor edits are different endpoints), the expected p per structure class and target δ or threshold, the readers per case + analysis unit + assumed ρ, the catastrophic bound you must state, and (for work saving) the SD of the per-case time difference.
Read ${CLAUDE_SKILL_DIR}/references/segmentation_acceptability_sample_size.md for the proportion,
clustering, rule-of-three and edit-time detail. The usability design the size serves lives in
design-study (segmentation_failure_characterization_design.md); presenting it is make-figures
(exemplar_plots/segmentation_failure_panel.md).
Scope Limitations
Supported
The 11 tests listed above cover the vast majority of sample size calculations needed in medical imaging research, diagnostic accuracy studies, and clinical trials.
NOT Supported
The following designs require specialized software or biostatistician consultation:
- Adaptive trials (group-sequential, sample size re-estimation)
- Cluster-randomized trials (design effect, ICC-based inflation)
- Bayesian sample size determination
- Crossover designs
- Multi-endpoint correction (mention Bonferroni adjustment if asked, but do not compute corrected sample sizes)
If the user requests any of these, respond:
"This design requires specialized tools beyond this skill's scope. Consider using G*Power software (free, https://www.psychologie.hhu.de/gpower), PASS software, or consulting a biostatistician for [specific design]."
Workflow
Phase 1: Understand the Study
- Ask the user to describe their study briefly (design, primary outcome, groups).
- Walk through the decision tree to identify the appropriate test.
- Confirm the selected test with the user before proceeding.
Phase 2: Collect Parameters
- Present the parameter table for the selected test.
- For each parameter without a user-provided value, explain what it means and offer the default.
- Help the user estimate effect sizes from:
- Prior literature (ask for references)
- Pilot data
- Cohen's conventions (as a last resort, with a note that convention-based estimates are less precise)
Phase 2b: Retrospective Study — Experience-Based Sample Size Justification
For retrospective studies, formal power analysis is often impractical because the dataset already exists. In these cases, an experience-based justification is acceptable for IRB and many journals. Offer this path when the user describes a retrospective design.
Two approaches:
Approach A: Institution Volume-Based
Estimate N from the number of examinations performed at the institution during the study period.
Total exams in period × prevalence of target condition × (1 - exclusion rate) = Expected N
- Ask the user for: annual exam volume for the modality, study period length, estimated prevalence, and expected exclusion rate
- This gives a realistic upper bound for N
IRB justification template:
Based on approximately [X] [modality] examinations performed annually at [institution], and an estimated prevalence of [condition] of [Y]%, we anticipate identifying approximately [N] eligible patients over the [Z]-year study period. After accounting for an estimated [W]% exclusion rate (due to [reasons]), we expect a final sample of approximately [N_adj] patients for analysis.
Approach B: Prior Study-Based
Use sample sizes from published studies with similar designs as justification.
- Search for 3-5 comparable studies and report their sample sizes
- The user's N should be in the same range or larger
- Cite the specific studies in the IRB justification
IRB justification template:
Previous studies evaluating [similar topic] with [similar design] enrolled [N1] (Author1 et al., Year), [N2] (Author2 et al., Year), and [N3] (Author3 et al., Year) patients. Our anticipated sample of [N] patients is [comparable to / larger than] these prior studies.
When to Use Formal Calculation Instead
Even for retrospective studies, a formal sample size calculation is preferred when:
- The study is prospective or will prospectively enroll a subset
- The primary analysis involves hypothesis testing (not just estimation)
- The journal explicitly requires power analysis (check Instructions for Authors)
- The IRB requires it for approval
In these cases, proceed to Phase 3 with the appropriate test from the decision tree.
Phase 3: Calculate and Report
- Read
${CLAUDE_SKILL_DIR}/references/formulas.mdfor the exact formula. - Generate the R code (primary) and Python code (alternative).
- Run the R code via Bash to produce the actual result.
- Present results in the output format below.
Phase 4: Sensitivity Analysis (Optional)
If the user is uncertain about parameters, offer a sensitivity table showing N across a range of plausible values (e.g., varying effect size or power from 0.80 to 0.90).
Output Format
Always structure the final output as follows:
## Sample Size Calculation Report
### Study Design
[1-2 sentence summary of the design and test selected]
### Parameters
| Parameter | Value | Source |
|-----------|-------|--------|
| ... | ... | user / literature / convention |
### Result
- **Required sample size**: N = [value]
- **With [X]% attrition adjustment**: N_adj = [value]
### R Code (Reproducible)
```r
# [complete, self-contained R script]
# Dependencies: [list packages]
# Run: Rscript sample_size_calc.R
Python Code (Alternative)
# [complete, self-contained Python script]
# Dependencies: [list packages]
# Run: python sample_size_calc.py
IRB Justification Text
A sample of [N] participants is required to detect [effect description] with [power]% power at a [one/two]-sided significance level of [alpha], assuming [key assumptions]. Accounting for an estimated [X]% attrition rate, we plan to enroll [N_adj] participants. This calculation is based on [formula/method reference].
Effect Size Interpretation
[Cohen's benchmark classification + clinical meaning in the context of this study]
---
## IRB Justification Text Guidelines
The IRB text must:
1. State the required N clearly.
2. Name the statistical test and its formula source.
3. Specify all assumed parameters (effect size, alpha, power).
4. State the attrition adjustment and final enrollment target.
5. Cite the methodological reference (e.g., "Schoenfeld, 1981" for survival).
6. Use formal, third-person language suitable for an ethics board.
---
## Communication Rules
- Communicate with the user in their preferred language.
- Use English for all statistical terminology, effect size names, and test names.
- Be explicit about assumptions and their impact on the result.
- When the user provides vague effect size estimates, flag the uncertainty and suggest a sensitivity analysis.
- Never fabricate references. Cite only verified methodological sources from `formulas.md`.
## Anti-Hallucination
- **Never fabricate file paths, URLs, DOIs, or package names.** Verify existence before recommending.
- **Never invent journal metadata, impact factors, or submission policies** without verification at the journal's website.
- If a tool, package, or resource does not exist or you are unsure, say so explicitly rather than guessing.
Files (medsci-skills)
-
references
-
formulas.md 20 KB
# Sample Size Formulas Reference Mathematical formulas, R/Python implementations, and effect size conventions for all 10 supported tests. --- ## Test 1: Diagnostic Accuracy (Sensitivity/Specificity Precision) ### Formula For estimating a single proportion p with desired 95% CI half-width w: ``` n_positive = ceil( (z_{alpha/2} / w)^2 * p * (1 - p) ) n_total = ceil( n_positive / prevalence ) ``` Where: - `z_{alpha/2}` = 1.96 for alpha = 0.05 - `p` = expected sensitivity (or specificity) - `w` = desired CI half-width - `prevalence` = disease prevalence in the study population ### R Implementation ```r z <- qnorm(1 - alpha / 2) n_pos <- ceiling((z / ci_half_width)^2 * se_expected * (1 - se_expected)) n_total <- ceiling(n_pos / prevalence) n_adj <- ceiling(n_total / (1 - attrition_rate)) ``` ### Python Implementation ```python from scipy.stats import norm import math z = norm.ppf(1 - alpha / 2) n_pos = math.ceil((z / ci_half_width)**2 * se_expected * (1 - se_expected)) n_total = math.ceil(n_pos / prevalence) n_adj = math.ceil(n_total / (1 - attrition_rate)) ``` ### R Package Base R (no additional packages needed). ### Key Reference Buderer NMF. Statistical methodology: I. Incorporating the prevalence of disease into the sample size calculation for sensitivity and specificity. Acad Emerg Med. 1996;3(9):895-900. --- ## Test 2: ICC Agreement (Bonett 2002) ### Formula Fisher z-transformation approach: ``` z_1 = 0.5 * ln((1 + rho_1) / (1 - rho_1)) # expected ICC z_0 = 0.5 * ln((1 + rho_0) / (1 - rho_0)) # null ICC n = ceil( ((z_{alpha} + z_{beta}) / (z_1 - z_0))^2 + 3 ) ``` Where: - `rho_1` = expected ICC - `rho_0` = null hypothesis ICC - `z_{alpha}` = qnorm(1 - alpha) for one-sided, qnorm(1 - alpha/2) for two-sided - `z_{beta}` = qnorm(power) ### R Implementation ```r # Option A: MKpower package (preferred) library(MKpower) result <- sampleSize.ICC(rho0 = icc_null, rho1 = icc_expected, k = n_raters, alpha = alpha, power = power) n <- result$n # Option B: Manual Fisher z (if MKpower unavailable) z_exp <- 0.5 * log((1 + icc_expected) / (1 - icc_expected)) z_null <- 0.5 * log((1 + icc_null) / (1 - icc_null)) n <- ceiling(((qnorm(1 - alpha) + qnorm(power)) / (z_exp - z_null))^2 + 3) ``` ### Python Implementation ```python from scipy.stats import norm import math import numpy as np z_exp = 0.5 * np.log((1 + icc_expected) / (1 - icc_expected)) z_null = 0.5 * np.log((1 + icc_null) / (1 - icc_null)) z_alpha = norm.ppf(1 - alpha) z_beta = norm.ppf(power) n = math.ceil(((z_alpha + z_beta) / (z_exp - z_null))**2 + 3) ``` ### R Package `MKpower` (preferred), or base R for manual calculation. ### Key Reference Bonett DG. Sample size requirements for estimating intraclass correlations with desired precision. Stat Med. 2002;21(9):1331-1335. --- ## Test 3: Kappa Agreement (Donner & Eliasziw 1992) ### Formula Z-test approximation for testing kappa_1 vs kappa_0: ``` n = ceil( ((z_{alpha/2} + z_{beta})^2 * kappa_1 * (1 - kappa_1)) / (kappa_1 - kappa_0)^2 + 1 ) ``` Where: - `kappa_1` = expected kappa - `kappa_0` = null hypothesis kappa - `pe` = expected chance agreement = (po - kappa) / (1 - kappa) ### R Implementation ```r n_kappa <- ceiling( ((qnorm(1 - alpha / 2) + qnorm(power))^2 * kappa_expected * (1 - kappa_expected)) / (kappa_expected - kappa_null)^2 + 1 ) ``` ### Python Implementation ```python from scipy.stats import norm import math z_a = norm.ppf(1 - alpha / 2) z_b = norm.ppf(power) n = math.ceil(((z_a + z_b)**2 * kappa_exp * (1 - kappa_exp)) / (kappa_exp - kappa_null)**2 + 1) ``` ### R Package Base R. Also available via `kappaSize` package. ### Key Reference Donner A, Eliasziw M. A goodness-of-fit approach to inference procedures for the kappa statistic: confidence interval construction, significance-testing and sample size estimation. Stat Med. 1992;11(11):1511-1519. --- ## Test 4: Two-Proportion Comparison (Chi-Square) ### Formula Based on Cohen's h effect size (arcsine transformation): ``` h = 2 * arcsin(sqrt(p1)) - 2 * arcsin(sqrt(p2)) n_per_group = ceil( ((z_{alpha/2} + z_{beta}) / h)^2 ) ``` ### R Implementation ```r library(pwr) h <- ES.h(p1, p2) result <- pwr.2p.test(h = h, sig.level = alpha, power = power) n_per_group <- ceiling(result$n) n_total <- n_per_group * 2 ``` ### Python Implementation ```python from statsmodels.stats.power import NormalIndPower import numpy as np import math h = 2 * np.arcsin(np.sqrt(p1)) - 2 * np.arcsin(np.sqrt(p2)) analysis = NormalIndPower() n_per_group = math.ceil(analysis.solve_power(effect_size=h, alpha=alpha, power=power, ratio=1, alternative='two-sided')) n_total = n_per_group * 2 ``` ### R Package `pwr` ### Key Reference Cohen J. Statistical Power Analysis for the Behavioral Sciences. 2nd ed. Lawrence Erlbaum Associates; 1988. --- ## Test 5: McNemar Test (Paired Proportions) ### Formula ``` n = ceil( (z_{alpha/2} * sqrt(p01 + p10) + z_{beta} * sqrt(p01 + p10 - (p10 - p01)^2))^2 / (p10 - p01)^2 ) ``` Where: - `p01` = P(Method A negative, Method B positive) - `p10` = P(Method A positive, Method B negative) ### R Implementation ```r n_mc <- ceiling( (qnorm(1 - alpha / 2) * sqrt(p01 + p10) + qnorm(power) * sqrt(p01 + p10 - (p10 - p01)^2))^2 / (p10 - p01)^2 ) ``` ### Python Implementation ```python from scipy.stats import norm import math z_a = norm.ppf(1 - alpha / 2) z_b = norm.ppf(power) disc_sum = p01 + p10 disc_diff = p10 - p01 n = math.ceil((z_a * math.sqrt(disc_sum) + z_b * math.sqrt(disc_sum - disc_diff**2))**2 / disc_diff**2) ``` ### R Package Base R. Also available via `exact2x2` package. ### Key Reference Connor RJ. Sample size for testing differences in proportions for the paired-sample design. Biometrics. 1987;43(1):207-211. --- ## Test 6: Independent t-Test ### Formula ``` d = mean_diff / pooled_sd (Cohen's d) n_per_group = ceil( 2 * ((z_{alpha/2} + z_{beta}) / d)^2 ) ``` ### R Implementation ```r library(pwr) d <- mean_diff / pooled_sd result <- pwr.t.test(d = d, sig.level = alpha, power = power, type = "two.sample") n_per_group <- ceiling(result$n) n_total <- n_per_group * 2 ``` ### Python Implementation ```python from statsmodels.stats.power import TTestIndPower import math d = mean_diff / pooled_sd analysis = TTestIndPower() n_per_group = math.ceil(analysis.solve_power(effect_size=d, alpha=alpha, power=power, ratio=1, alternative='two-sided')) n_total = n_per_group * 2 ``` ### R Package `pwr` ### Key Reference Cohen J. Statistical Power Analysis for the Behavioral Sciences. 2nd ed. Lawrence Erlbaum Associates; 1988. --- ## Test 7: Survival / Log-Rank Test (Schoenfeld 1981) ### Formula Step 1 -- Required number of events: ``` d = ceil( ((z_{alpha/2} + z_{beta}) / ln(HR))^2 ) ``` Step 2 -- Total sample size: ``` lambda_ctrl = ln(2) / median_ctrl lambda_trt = lambda_ctrl * HR p_event_ctrl = 1 - exp(-lambda_ctrl * follow_up) p_event_trt = 1 - exp(-lambda_trt * follow_up) avg_p_event = (p_event_ctrl + p_event_trt) / 2 n_total = ceil( d / avg_p_event ) ``` ### R Implementation ```r n_events <- ceiling((qnorm(1 - alpha / 2) + qnorm(power))^2 / (log(hr))^2) lambda_ctrl <- log(2) / median_ctrl lambda_trt <- lambda_ctrl * hr p_event_ctrl <- 1 - exp(-lambda_ctrl * follow_up) p_event_trt <- 1 - exp(-lambda_trt * follow_up) avg_p_event <- (p_event_ctrl + p_event_trt) / 2 n_total <- ceiling(n_events / avg_p_event) n_adj <- ceiling(n_total / (1 - drop_rate)) ``` ### Python Implementation ```python from scipy.stats import norm import math import numpy as np z_a = norm.ppf(1 - alpha / 2) z_b = norm.ppf(power) n_events = math.ceil((z_a + z_b)**2 / np.log(hr)**2) lambda_ctrl = np.log(2) / median_ctrl lambda_trt = lambda_ctrl * hr p_event_ctrl = 1 - np.exp(-lambda_ctrl * follow_up) p_event_trt = 1 - np.exp(-lambda_trt * follow_up) avg_p_event = (p_event_ctrl + p_event_trt) / 2 n_total = math.ceil(n_events / avg_p_event) n_adj = math.ceil(n_total / (1 - drop_rate)) ``` ### R Package Base R. Also available via `gsDesign`, `survival` packages. ### Key Reference Schoenfeld DA. The asymptotic properties of nonparametric tests for comparing survival distributions. Biometrika. 1981;68(1):316-319. --- ## Test 8: One-Way ANOVA ### Formula Using Cohen's f effect size: ``` f = sigma_between / sigma_within ``` Where: - `sigma_between` = SD of group means - `sigma_within` = pooled within-group SD From eta-squared: `f = sqrt(eta_sq / (1 - eta_sq))` The sample size per group is obtained via the F-test power formula (implemented in `pwr`). ### R Implementation ```r library(pwr) result <- pwr.anova.test(k = k, f = f, sig.level = alpha, power = power) n_per_group <- ceiling(result$n) n_total <- n_per_group * k n_adj <- ceiling(n_total / (1 - attrition_rate)) ``` ### Python Implementation ```python from statsmodels.stats.power import FTestAnovaPower import math analysis = FTestAnovaPower() n_per_group = math.ceil(analysis.solve_power(effect_size=f, nobs=None, alpha=alpha, power=power, k_groups=k)) n_total = n_per_group * k n_adj = math.ceil(n_total / (1 - attrition_rate)) ``` ### R Package `pwr` ### Key Reference Cohen J. Statistical Power Analysis for the Behavioral Sciences. 2nd ed. Lawrence Erlbaum Associates; 1988. (Chapter 8: F tests for ANOVA) --- ## Test 9: Logistic Regression ### Approach A: Peduzzi Rule of Thumb (EPV >= 10) ``` N_events = 10 * p (where p = number of predictor variables) N_total = N_events / event_rate ``` This ensures at least 10 events per predictor variable (EPV), the widely accepted minimum for stable logistic regression estimates. ### Approach B: Hsieh (1989) Formula For detecting a specific odds ratio (OR) for a continuous or binary predictor: ``` # For a binary predictor (proportion B exposed): n_unadj = ((z_{alpha/2} + z_{beta})^2) / (B * (1-B) * ln(OR)^2) # Adjusted for correlation with other predictors: n_adj = n_unadj / (1 - R^2) ``` Where: - `OR` = odds ratio of interest - `B` = proportion of subjects exposed (for binary predictor) or use p*(1-p) for the outcome - `R^2` = multiple correlation of the predictor with other covariates For a continuous predictor, the formula uses the standard normal density. ### R Implementation ```r # Approach A: Peduzzi n_events_peduzzi <- 10 * n_predictors n_total_peduzzi <- ceiling(n_events_peduzzi / event_rate) # Approach B: Hsieh (binary predictor) z_a <- qnorm(1 - alpha / 2) z_b <- qnorm(power) n_hsieh <- ceiling((z_a + z_b)^2 / (event_rate * (1 - event_rate) * log(or_interest)^2)) n_hsieh_adj <- ceiling(n_hsieh / (1 - r2_other)) # Report the larger of the two n_final <- max(n_total_peduzzi, n_hsieh_adj) ``` ### Python Implementation ```python from scipy.stats import norm import math import numpy as np # Approach A: Peduzzi n_events_peduzzi = 10 * n_predictors n_total_peduzzi = math.ceil(n_events_peduzzi / event_rate) # Approach B: Hsieh (binary predictor) z_a = norm.ppf(1 - alpha / 2) z_b = norm.ppf(power) n_hsieh = math.ceil((z_a + z_b)**2 / (event_rate * (1 - event_rate) * np.log(or_interest)**2)) n_hsieh_adj = math.ceil(n_hsieh / (1 - r2_other)) n_final = max(n_total_peduzzi, n_hsieh_adj) ``` ### R Package Base R. Also see `powerMediation` package for Hsieh's formula. ### Key References - Peduzzi P, Concato J, Kemper E, Holford TR, Feinstein AR. A simulation study of the number of events per variable in logistic regression analysis. J Clin Epidemiol. 1996;49(12):1373-1379. - Hsieh FY. Sample size tables for logistic regression. Stat Med. 1989;8(7):795-802. --- ## Test 10: Non-Inferiority / Equivalence ### Non-Inferiority (Proportions) ``` n_per_group = ceil( ((z_{1-alpha} + z_{beta})^2 * (p_ref*(1-p_ref) + p_new*(1-p_new))) / (margin - |p_new - p_ref|)^2 ) ``` When assuming p_new = p_ref (no true difference): ``` n_per_group = ceil( ((z_{1-alpha} + z_{beta})^2 * 2 * p*(1-p)) / margin^2 ) ``` Note: alpha is one-sided (typically 0.025) for non-inferiority. ### Non-Inferiority (Continuous) ``` n_per_group = ceil( ((z_{1-alpha} + z_{beta})^2 * 2 * sd^2) / margin^2 ) ``` ### Equivalence / TOST (Proportions) ``` n_per_group = ceil( ((z_{1-alpha/2} + z_{beta})^2 * 2 * p*(1-p)) / margin^2 ) ``` Note: For TOST, each one-sided test uses alpha (e.g., alpha = 0.05 for overall 5% type I error). ### Equivalence / TOST (Continuous) ``` n_per_group = ceil( ((z_{1-alpha} + z_{beta})^2 * 2 * sd^2) / margin^2 ) ``` ### R Implementation ```r # Non-inferiority for proportions (assuming no true difference) z_a <- qnorm(1 - alpha) # one-sided, alpha = 0.025 z_b <- qnorm(power) p <- p_reference n_per_group <- ceiling(((z_a + z_b)^2 * 2 * p * (1 - p)) / margin^2) n_total <- n_per_group * 2 # Non-inferiority for continuous n_per_group <- ceiling(((z_a + z_b)^2 * 2 * sd^2) / margin^2) n_total <- n_per_group * 2 # Equivalence / TOST for continuous n_per_group <- ceiling(((z_a + z_b)^2 * 2 * sd^2) / margin^2) n_total <- n_per_group * 2 n_adj <- ceiling(n_total / (1 - attrition_rate)) ``` ### Python Implementation ```python from scipy.stats import norm import math # Non-inferiority for proportions (assuming no true difference) z_a = norm.ppf(1 - alpha) # one-sided, alpha = 0.025 z_b = norm.ppf(power) p = p_reference n_per_group = math.ceil(((z_a + z_b)**2 * 2 * p * (1 - p)) / margin**2) n_total = n_per_group * 2 # Non-inferiority for continuous n_per_group = math.ceil(((z_a + z_b)**2 * 2 * sd**2) / margin**2) n_total = n_per_group * 2 # Equivalence / TOST for continuous # Same formula; the difference is in the hypothesis and alpha interpretation n_per_group = math.ceil(((z_a + z_b)**2 * 2 * sd**2) / margin**2) n_total = n_per_group * 2 n_adj = math.ceil(n_total / (1 - attrition_rate)) ``` ### R Package Base R. Also see `TrialSize`, `PowerTOST` packages. ### Key References - Julious SA. Sample sizes for clinical trials with normal data. Stat Med. 2004;23(12):1921-1986. - Schuirmann DJ. A comparison of the two one-sided tests procedure and the power approach for assessing the equivalence of average bioavailability. J Pharmacokinet Biopharm. 1987;15(6):657-680. --- ## Test 11: Cox Regression EPV (Events Per Variable) ### Formula ``` N_events = EPV × k (where k = number of predictor variables) N_total = ceil( N_events / event_rate ) N_adj = ceil( N_total / (1 - attrition_rate) ) ``` Where: - `EPV` = events per variable (minimum 10, recommended 20) - `k` = number of predictors in the Cox model - `event_rate` = proportion of subjects experiencing the event ### R Implementation ```r n_events <- epv * n_predictors n_total <- ceiling(n_events / event_rate) n_adj <- ceiling(n_total / (1 - attrition_rate)) cat(sprintf("EPV = %d, Predictors = %d\n", epv, n_predictors)) cat(sprintf("Required events = %d\n", n_events)) cat(sprintf("Total N = %d (event rate = %.0f%%)\n", n_total, event_rate * 100)) cat(sprintf("Adjusted N = %d (attrition = %.0f%%)\n", n_adj, attrition_rate * 100)) ``` ### Python Implementation ```python import math n_events = epv * n_predictors n_total = math.ceil(n_events / event_rate) n_adj = math.ceil(n_total / (1 - attrition_rate)) ``` ### R Package Base R (no additional packages needed). ### Key References - Peduzzi P, Concato J, Feinstein AR, Holford TR. Importance of events per independent variable in proportional hazards regression analysis. II. Accuracy and precision of regression estimates. J Clin Epidemiol. 1995;48(12):1503-1510. - Vittinghoff E, McCulloch CE. Relaxing the rule of ten events per variable in logistic and Cox regression. Am J Epidemiol. 2007;165(6):710-718. --- ## Cohen's Effect Size Conventions | Measure | Small | Medium | Large | Context | |---------|-------|--------|-------|---------| | d (t-test) | 0.20 | 0.50 | 0.80 | Difference in means / pooled SD | | f (ANOVA) | 0.10 | 0.25 | 0.40 | SD of group means / within-group SD | | h (proportions) | 0.20 | 0.50 | 0.80 | Arcsine-transformed proportion difference | | w (chi-square) | 0.10 | 0.30 | 0.50 | Chi-square contingency effect | | OR (logistic) | 1.5 | 2.0 | 3.0+ | Odds ratio (approximate equivalence) | | HR (survival) | 0.80 | 0.65 | 0.50 | Hazard ratio (values < 1 favor treatment) | | ICC | 0.50-0.75 | 0.75-0.90 | > 0.90 | Poor/moderate/good/excellent | | Kappa | 0.21-0.40 | 0.41-0.60 | 0.61-0.80 | Fair/moderate/substantial | **Important**: Cohen's conventions are rules of thumb. Always prefer effect sizes estimated from prior literature or pilot data. When conventions are used, explicitly state this limitation in the IRB justification. --- ## Common Attrition Rates by Study Type | Study Type | Typical Attrition | Recommended Adjustment | |------------|-------------------|------------------------| | Randomized controlled trial (RCT) | 15-20% | 20% | | Prospective observational / cohort | 10-15% | 15% | | Cross-sectional / survey | 5-10% | 10% | | Retrospective chart review | 3-5% | 5% | | Diagnostic accuracy (imaging) | 5-10% | 10% | | Inter-rater agreement study | 5-10% | 10% | | Survival / long follow-up (> 2 yr) | 15-25% | 20% | **Note**: Attrition rates vary widely by disease, population, and follow-up duration. Use study-specific estimates when available. --- ## Key References 1. **Cohen J.** Statistical Power Analysis for the Behavioral Sciences. 2nd ed. Hillsdale, NJ: Lawrence Erlbaum Associates; 1988. - Foundation for effect size conventions (d, f, h, w) and power analysis methodology. 2. **Schoenfeld DA.** The asymptotic properties of nonparametric tests for comparing survival distributions. Biometrika. 1981;68(1):316-319. - Formula for required number of events in log-rank test. 3. **Bonett DG.** Sample size requirements for estimating intraclass correlations with desired precision. Stat Med. 2002;21(9):1331-1335. - ICC-based sample size using Fisher z-transformation. 4. **Hsieh FY.** Sample size tables for logistic regression. Stat Med. 1989;8(7):795-802. - Power-based sample size for detecting a specific odds ratio. 5. **Peduzzi P, Concato J, Kemper E, Holford TR, Feinstein AR.** A simulation study of the number of events per variable in logistic regression analysis. J Clin Epidemiol. 1996;49(12):1373-1379. - EPV >= 10 rule for logistic regression model stability. 6. **Donner A, Eliasziw M.** A goodness-of-fit approach to inference procedures for the kappa statistic: confidence interval construction, significance-testing and sample size estimation. Stat Med. 1992;11(11):1511-1519. - Sample size for testing kappa against a null value. 7. **Buderer NMF.** Statistical methodology: I. Incorporating the prevalence of disease into the sample size calculation for sensitivity and specificity. Acad Emerg Med. 1996;3(9):895-900. - Prevalence-adjusted sample size for diagnostic accuracy. 8. **Julious SA.** Sample sizes for clinical trials with normal data. Stat Med. 2004;23(12):1921-1986. - Comprehensive non-inferiority and equivalence sample size formulas. 9. **Schuirmann DJ.** A comparison of the two one-sided tests procedure and the power approach for assessing the equivalence of average bioavailability. J Pharmacokinet Biopharm. 1987;15(6):657-680. - TOST (two one-sided tests) procedure for equivalence testing. 10. **Koo TK, Li MY.** A guideline of selecting and reporting intraclass correlation coefficients for reliability research. J Chiropr Med. 2016;15(2):155-163. - ICC interpretation benchmarks. 11. **Landis JR, Koch GG.** The measurement of observer agreement for categorical data. Biometrics. 1977;33(1):159-174. - Kappa interpretation benchmarks. 12. **Connor RJ.** Sample size for testing differences in proportions for the paired-sample design. Biometrics. 1987;43(1):207-211. - McNemar test sample size formula. 13. **Peduzzi P, Concato J, Feinstein AR, Holford TR.** Importance of events per independent variable in proportional hazards regression analysis. II. Accuracy and precision of regression estimates. J Clin Epidemiol. 1995;48(12):1503-1510. - EPV >= 10 rule for Cox regression model stability. 14. **Vittinghoff E, McCulloch CE.** Relaxing the rule of ten events per variable in logistic and Cox regression. Am J Epidemiol. 2007;165(6):710-718. - Evidence that EPV 5-10 may be acceptable with careful validation. -
justification_examples.md 3.6 KB
# Sample-size justification — worked prose exemplars (IRB / Methods) Reviewer-safe **justification paragraphs** for the prospective designs this skill computes, complementing `formulas.md` (the math) and the retrospective/experience-based templates in SKILL.md Phase 2b. Each shows the same five elements a methods reviewer or IRB looks for; fill the `[brackets]` from the actual calculation — never invent the inputs. These are synthetic teaching models of *standard* justification structure, not copied text. ## The five elements (every justification states all five) 1. The **primary outcome** and its effect/precision target (with the **source** of the assumed value — prior study, pilot, or a minimal clinically important difference, cited). 2. **α** (and one- vs two-sided) and **power** (or the target CI half-width for a precision aim). 3. The **test/method** the calculation matches (it must match the planned primary analysis). 4. The resulting **n**, including any **inflation** for attrition/clustering/multiplicity. 5. The **software/approach** used (named, so it is reproducible). ## Exemplars by design **Two proportions (superiority).** "Assuming an event rate of `[p1]` in the control arm (from `[cited source]`) and a clinically meaningful absolute reduction to `[p2]`, a two-sided α = 0.05 and 80% power require `[n/arm]` per arm (two-proportion test). Allowing for `[d]%` attrition, we will enrol `[N]`." **Two means (superiority).** "To detect a between-group difference of `[Δ]` in `[outcome]` (SD `[s]`, from `[source]`; standardised effect `[d]`) with two-sided α = 0.05 and 90% power requires `[n/arm]` per arm (two-sample t-test)." **Diagnostic accuracy (precision aim).** "To estimate sensitivity with a 95% CI half-width of `[w]`, assuming sensitivity `[Se]` and disease prevalence `[π]`, `[N_total]` participants (`[N_diseased]` with the target condition) are needed; the **specificity** target is checked separately from the non-diseased count `[N_nondiseased]` and is satisfied at this n. The aim is **precision, not power** — no comparison hypothesis is tested." (Cite Hajian-Tilaki / Buderer.) **Survival (log-rank).** "To detect a hazard ratio of `[HR]` (median `[m1]` vs `[m2]`) with two-sided α = 0.05 and 80% power, `[E]` events are required (Schoenfeld); with an accrual of `[a]` over `[t]` and follow-up `[f]`, this needs `[N]` participants. The **event count**, not N, drives power." **Agreement / reliability (ICC).** "Assuming a true ICC of `[ρ]` with `[k]` raters per subject, `[n]` subjects give a 95% CI half-width of `[w]` (a **precision** aim, Bonett/Walter) — *or*, framed as **assurance**, `[n]` subjects so the 95% CI lower bound exceeds the minimally acceptable `[ρ0]`. State which of the two aims you used; report the CI target, not power." **Non-inferiority.** "With a non-inferiority margin of `[m]` (justified clinically and by `[regulatory/prior]` precedent), assuming true equivalence and a control rate `[p]`, one-sided α = 0.025 and 90% power require `[n/arm]` per arm. The margin and its rationale are pre-specified." ## Discipline - The calculation must match the **planned primary analysis** (do not power for a t-test and analyse with a mixed model); state any clustering (design effect) or multiplicity adjustment. - For a **precision** aim (DTA, agreement, single-arm), report the **CI half-width**, not power — do not invent a comparison hypothesis to manufacture a power statement. - Never reverse-engineer the effect size from an achievable n (post-hoc justification); the assumed effect comes from a cited source or an MCID. Post-hoc/observed power is uninformative. -
mrmc_reader_study_sample_size.md 5.7 KB
# MRMC reader-study sample size (multi-reader multi-case) For a **reader study** — the design that asks "do radiologists read better *with* the AI than without", or "is the AI non-inferior to radiologists" — the single-reader AUC-precision calculation (Test 1) **under-sizes the study**, often badly. This reference is the design-time sizing for that class of study. It is the sizing counterpart to the flagship "clearing move" in `design-study/references/venue_accept_recipe.md` (a reader study measuring clinical impact is what lifts a study to the flagship tier) — and an under-sized reader study cannot deliver it. ## Why a single-reader power calculation is the wrong tool A reader study generalizes to **radiologists in general**, not to the specific readers you hired. So **both the readers and the cases are random effects**, and the uncertainty of the reader-averaged AUC (or of the AI−reader ΔAUC) carries a **reader-variance** term the single-reader calculation omits entirely. Size on case variance alone and the study is powered to detect an effect *in your particular readers*, not in the population of readers — which is exactly the claim a reviewer reads the paper as making. The practical consequence: studies sized as if readers were fixed are routinely **under-powered**, and a null result from an under-sized reader study is **inconclusive, not negative**. ## The framework — Obuchowski–Rockette / Hillis (OR) The multi-reader multi-case (MRMC) analysis of variance treats the figure of merit (usually AUC, or a difference in AUC between modalities/AI-conditions) as an outcome with **reader**, **case**, and **reader×case** (plus modality) random components. Sizing inverts the OR variance formula: - You choose the **number of readers `J`** and the **case counts** (diseased `N⁺`, non-diseased `N⁻`), and the OR formula returns the power to detect the target effect. - Power depends on the **variance components** — the error variance and the between-reader / within-reader covariances (`Cov1`, `Cov2`, `Cov3` in the OR parameterization, or Hillis' equivalent `σ²` terms). **You cannot size an MRMC study without these**, and they are the real bottleneck: take them from a **pilot** (a handful of readers on a subset) or from **published component estimates** for a similar task/modality, and state the source. ## The inputs to pre-specify (before any data) 1. **The effect**: the ΔAUC to detect (superiority) *or* the non-inferiority margin (an AI-vs-reader claim is usually **non-inferiority**, so state the margin, not a difference). 2. **The expected AUC level** of the reference arm (variance of an AUC estimate depends on where it sits). 3. **The variance components** (pilot or literature — the hard part; §above). 4. **The design**: **fully-crossed** (every reader reads every case in every condition) is the default and the most efficient; a **crossover with washout** (readers read with and without AI, separated by a washout so the first read does not cue the second) is the standard AI-assistance design. 5. **Power and α** (commonly 80–90% at two-sided 0.05). ## Readers vs cases — where the power comes from Because the **reader-variance term usually dominates** the generalization uncertainty, past a modest case count **adding readers often buys more power than adding cases** — yet readers are the scarcer, costlier resource. Report the **`J × N` power grid**, not a single number, so the reader/case trade-off is an explicit, defensible design choice. A study with many cases but only 3–4 readers is a common, predictable under-powering. ## Compute it — integrate, do not reimplement - **`RJafroc`** (R; Chakraborty) — `SsPowerGivenJK` / sample-size functions for ROC & FROC MRMC. - **`MRMCaov`** (R) — OR analysis + power. - **`iMRMC`** (Gallas, FDA) — MRMC sizing/analysis, widely accepted by regulators. - **OR-DBM / DBM** procedures for the variance-component estimation from a pilot. Feed the pilot/literature variance components + the target effect into one of these; do not hand-roll the OR variance algebra. ## Grounding exemplars (accepted reader studies) Realistic `J × N` and design choices from accepted open-access papers: - **8-reader MRMC crossover, 500 cases** — PCN CT model, *npj Digital Medicine* 2025 (`10.1038/s41746-025-01970-y`): readers spanning residents→seniors, accuracy **and** reading-time endpoints. - **26 physicians × 150 cases × 3 conditions with ≥2-week washout** — pelvic-radiograph AI-support, *npj Digital Medicine* 2025 (`10.1038/s41746-025-01923-5`): a crossover across no-AI / alert / heatmap, specialty-stratified. These illustrate the crossover-with-washout design and the reader-count range a flagship reader study lands in; they are patterns, not templates. ## Reporting (what the Methods must state) The number of readers `J`, the case split `N⁺`/`N⁻`, the **design** (fully-crossed / crossover + washout), the **target effect** (ΔAUC or NI margin) and power/α, the **source of the variance components** (pilot vs literature), and the **software**. Analysis of the completed study uses the matching OR/DBM procedure (see `analyze-stats` `reader_study` table-type + `diagnostic_accuracy` guide); the reader-study *design internals* (rubric, blinding, washout, experience mix) are in `design-study/references/reader_elicitation_design.md`, and an AI-vs-human-expert benchmark routes to `/design-ai-benchmarking`. ## References (methodology — cite, do not copy) - Obuchowski NA, Rockette HE. *Commun Stat Simul Comput* 1995 (the OR method). - Hillis SL, Berbaum KS, Metz CE. *Acad Radiol* 2008 (OR/DBM equivalence, sizing). - Hillis SL. *Stat Med* 2007 (degrees of freedom for MRMC). - Chakraborty DP. *Observer Performance Methods for Diagnostic Imaging* (RJafroc). -
multi_model_comparison_sample_size.md 6.1 KB
# Between-model comparison sample size (is model A really better than B, C, …) For a study whose claim is that **one model outperforms others** — several architectures / families compared head-to-head on the same task — the sizing question is not single-model precision (Test 15 for Dice, Test 1 for AUC) but **how many cases separate the models**. A study powered only to estimate each model's metric can still be too small to tell whether the ranking is real. This is the **size** counterpart to the fair-comparison **design** in `design-study/references/multi_model_comparison_design.md`; decide it before data collection. ## Why single-model precision under-sizes a comparison Sizing each arm to a tight marginal CI does **not** guarantee the *difference* is distinguishable from zero — two models can each have a narrow CI and still overlap. The comparison is powered by the **difference**, and its precision depends on the **SD of the per-case difference**, which the marginal SDs do not give you. ## Pair the design — it shrinks the required n Run **all models on the same cases** (a paired / within-case design) and size on the **SD of the per-case difference**. With equal marginal SDs σ and between-model correlation ρ, `SD_Δ = σ·√(2(1−ρ))` — **smaller than either marginal SD only once ρ > 0.5**, a bar that models scored on the *same* cases usually clear by a wide margin (easy cases are easy for every model, hard cases are hard for every model). Whatever ρ turns out to be, the paired design also **collects fewer cases** than two independent arms at equal power, because one case serves every model — and it is the only design that supports the paired statistics below. ## Metric-specific paired sizing - **Classification / detection — paired ΔAUC:** use the **DeLong** (1988) variance of the *difference* of two correlated AUCs (or Obuchowski for the MRMC / clustered case); size so the **ΔAUC CI excludes zero** (superiority) or so its **lower bound clears −δ**, the non-inferiority margin — requiring the *whole* interval inside ±δ is the stricter **equivalence** claim, so do not size one and call it the other. Sizing on each AUC's marginal CI is the wrong tool — the covariance between the two ROC curves is exactly what a paired calc uses. - **Segmentation — paired ΔDice / ΔHD95 / ΔNSD:** size on the SD of the **per-case metric difference** and report the delta CI by **bootstrapping the paired per-case differences (BCa)** — a t-interval on the mean per-case difference is closed-form, but it leans on a normality that a bounded metric bunched near ceiling does not deliver, and BCa resamples whole *patients* rather than lesions or structures. This extends the A-vs-B section of `segmentation_metric_sample_size.md` beyond a single contrast; **size on the worst structure** you must report. - Take the **per-case-difference SD from a pilot** (or a prior head-to-head), never from a marginal-SD formula that assumes independence. ## More than two models — multiplicity across contrasts Comparing **k models** creates up to k(k−1)/2 pairwise contrasts. Decide the estimand **before** the data: - **Primary-contrast design (preferred):** pre-specify **one** primary comparison — the proposed model vs the **strong, fairly-tuned reference baseline** (e.g., nnU-Net) — sized at full α; everything else is secondary / exploratory and labelled so. This avoids sizing for a multiplicity you do not need. - **All-pairs confirmatory:** if every pairwise claim is confirmatory, a **family-wise correction** (Bonferroni / Tukey-analog) lowers the per-contrast α, which **inflates the required n per contrast** — budget for it. Running k(k−1)/2 unplanned tests and headlining the one that clears p < 0.05 is the rejected pattern (`analyze-stats` `analysis_guides/multiplicity.md`). ## Ranking stability — the trap a difference calc still misses A **single-run** leaderboard ranks models by *true skill + run-to-run noise* (random seed, data order, augmentation draw). Near-tied models can swap rank between seeds, so "our model ranked first" from one run is not evidence. Two additions: - **Report run-to-run variance:** train each model over **multiple seeds** and report the metric's seed SD; for the paired difference of repeated cross-validation runs use the **Nadeau–Bengio corrected-resampled variance** (a naïve paired t over overlapping CV folds is anticonservative). - **Comparing many models across independent datasets:** the **Demšar (2006)** framework — Friedman test + Nemenyi **critical-difference** — tells you which rank gaps are real. Its sampling unit is the **independent dataset**, so its N is the *number of datasets*: extra seeds and overlapping CV folds do not raise it (those buy you the run-to-run spread above), and per-structure scores from one cohort are correlated blocks, not substitutes for datasets. Models inside the critical difference are **not separated by the test** — leave them unranked, and do not upgrade that to a demonstrated tie (failure to reject is not evidence of equality; an equivalence claim needs its own margin). ## Required parameters The **per-case-difference SD** of the primary metric (pilot / prior head-to-head; per structure for segmentation), the **metric** and its paired-CI method (DeLong for AUC, bootstrap for Dice), the target **δ or NI margin on the delta**, the **number of models + which single contrast is primary**, and (for a ranking claim) the **seed-to-seed SD**. Report N, the difference-SD source, the primary contrast, and the multiplicity handling. ## Cross-links The fair-comparison design the size serves → `design-study/references/multi_model_comparison_design.md`; the single-metric precision + one A-vs-B Dice contrast → `segmentation_metric_sample_size.md`; reader-in-the-loop (AI-vs-reader) sizing → `mrmc_reader_study_sample_size.md` (Test 14); presenting the result → `make-figures` `exemplar_plots/model_comparison_leaderboard.md` + `analyze-stats` `table-standards/table-types/model_comparison.md`; the multiplicity discipline → `analyze-stats` `analysis_guides/multiplicity.md`. -
observational_cohort.md 2.1 KB
# Observational Cohort Sample Size: Precision Branch Use this reference when a cohort study is extraction-constrained or when the goal is precision rather than formal power. ## When To Use - Retrospective hospital-based cohort with all eligible records included. - National database cohort where the sample is fixed by release permissions. - Sparse-event outcome where the real question is whether confidence intervals are narrow enough to support a claim. ## Core Checks 1. Primary estimand: risk difference, odds ratio, hazard ratio, incidence rate, or mean difference. 2. Event count: total events and events per modeled parameter. 3. Precision target: acceptable confidence interval half-width or maximum acceptable upper bound. 4. Model complexity: covariate count relative to events. 5. Fragility: subgroup and sensitivity analyses with smaller denominators. ## Rule-of-Thumb Gates | Situation | Minimum check | |---|---| | Logistic or Cox model | Events per parameter and shrinkage/penalization consideration | | Sparse binary outcome | Exact or profile-likelihood confidence intervals | | Incidence rate | Poisson exact CI around event rate | | Null association claim | Upper CI bound must exclude clinically meaningful effect | | Subgroup analysis | Interaction test plus event count per subgroup | ## Manuscript Phrase "The study size was determined by all eligible participants in the released cohort. We therefore evaluated statistical informativeness by the number of outcome events, events per modeled parameter, and the width of the 95% confidence intervals around the primary estimate rather than by a conventional a priori recruitment target." ## Minimal R Sketch ```r events <- 130 parameters <- 8 epv <- events / parameters rate <- 130 / 250000 poisson.test(130, T = 250000)$conf.int ``` ## Reviewer-Safe Interpretation - If events are sparse, do not write "no association" without discussing the upper confidence bound. - If EPV is below 10, state that estimates are exploratory or use penalized/sparse models. - If a subgroup has few events, report it descriptively even when the p-value looks attractive. -
prediction_model_sample_size.md 5 KB
# Prediction-model sample size (Riley) — development & external validation For a **clinical prediction model** (or a medical-AI model evaluated as one), the events-per-variable rule of thumb (EPV ≥ 10) is **outdated and reviewer-vulnerable**. EPV does not target the things that determine whether a developed model is trustworthy (overfitting, precise risk estimates) or whether a validation is conclusive (precise discrimination and calibration). Use the **Riley criteria** instead — they are the current TRIPOD+AI-aligned standard, and they are implemented in the R packages `pmsampsize` (development) and `pmvalsampsize` (external validation). Apply this whenever the goal is **risk prediction / classification for use**, not a single predictor's hypothesis test. (For a single-predictor association test, the Hsieh/logistic power calculation in Test 9 is appropriate.) ## Development sample size — `pmsampsize` (Riley et al.) The minimum development sample size is the largest N satisfying four criteria simultaneously: 1. **Small overfitting** — global shrinkage factor ≥ 0.9. 2. **Small optimism in apparent fit** — absolute difference between apparent and adjusted Nagelkerke R² ≤ 0.05. 3. **Precise estimate of overall risk** — margin of error of the mean predicted outcome (the intercept) ≤ 0.05. 4. **(time-to-event)** precise estimate of the baseline survival at a key time point. Inputs you must specify (and justify from prior literature, not guess): - number of **candidate predictor parameters** (count dummy variables and non-linear terms, not just variables); - the anticipated model performance — a conservative **Cox-Snell R²** (derivable from an expected **C-statistic** + outcome prevalence) or expected R²; - the **outcome prevalence** (binary) or **event rate + mean follow-up** (time-to-event), or outcome mean/SD (continuous). ```r library(pmsampsize) # Binary outcome: prevalence 0.20, 30 candidate parameters, expected C ≈ 0.78 # (convert C to a conservative Cox-Snell R²; pmsampsize accepts csrsquared or cstatistic) pmsampsize(type = "b", cstatistic = 0.78, parameters = 30, prevalence = 0.20) # Time-to-event: rate per person-year, mean follow-up, timepoint of interest pmsampsize(type = "s", csrsquared = 0.05, parameters = 30, rate = 0.08, timepoint = 5, meanfup = 4.2) ``` Report the **minimum N and the required number of events**, the assumed C-statistic / R² and its source, and the binding criterion. A development set below this is a standard high-impact-journal rejection. ## External-validation sample size — `pmvalsampsize` (Riley et al.) Size the validation set to estimate the key performance metrics **precisely enough to be conclusive** — target the confidence-interval width of each: - **discrimination** — C-statistic (target CI width, e.g. ±0.05); - **calibration slope** (target SE / CI width); - **calibration-in-the-large / O:E ratio**; - **(if reporting clinical utility)** the standardized **net benefit** at the decision threshold. ```r library(pmvalsampsize) # Validate a model with expected prevalence 0.20, anticipated C ≈ 0.78, # targeting a C-statistic CI half-width of 0.05 and a precise calibration slope pmvalsampsize(type = "b", prevalence = 0.20, cstatistic = 0.78, cslope = 1, oe = 1, lpnormal = c(-0.5, 0.5), cstatci = 0.10) # target CI *width* for the C-statistic ``` A common **floor** is ≥ 100 events and ≥ 100 non-events (Vergouwe; Collins), but `pmvalsampsize` gives the precise target for your metrics and usually requires more. ## Sample size for net benefit / decision-curve If the model's value claim rests on **net benefit** (decision-curve analysis), size the study to estimate net benefit at the relevant threshold with adequate precision — `pmvalsampsize` supports a net-benefit target, and the development criteria should be met so the model is not overfit before its utility is judged. Do not claim clinical utility from a decision curve estimated on an underpowered validation set. ## Reporting - State that sizing followed the **Riley criteria** (cite the originals) — not EPV-10. - Report the assumed C-statistic / R² / prevalence and **where they came from**. - For development, report N + events + the binding criterion; for validation, report the targeted CI widths and the resulting N (events and non-events). ## References (cite the originals) - Riley RD, Snell KIE, Ensor J, et al. Minimum sample size for developing a multivariable prediction model: PART II — binary and time-to-event outcomes. *Stat Med* 2019. - Riley RD, Ensor J, Snell KIE, et al. Calculating the sample size required for developing a clinical prediction model. *BMJ* 2020. - Riley RD, Debray TPA, Collins GS, et al. Minimum sample size for external validation of a clinical prediction model with a binary outcome. *Stat Med* 2021. - Collins GS, Ogundimu EO, Altman DG. Sample size considerations for the external validation of a multivariable prognostic model. *Stat Med* 2016. -
segmentation_acceptability_sample_size.md 5.7 KB
# Sizing a segmentation *usability* claim (acceptability rate, failure bound, edit time) For a study whose claim is that a segmentation model is **clinically usable** — a share of cases a clinician accepts, a bounded catastrophic-failure rate, a time saving — the endpoint is **not the mean of a per-case metric**. Test 15 sizes a mean Dice to a target precision; that calculation says nothing about how many cases you need to state an acceptability *rate*, and a study sized for metric precision is routinely far too small to bound a failure rate. This is the **size** counterpart to the fair-usability **design** in `design-study/references/segmentation_failure_characterization_design.md`; decide it before data collection. ## The endpoint is a proportion, not a mean An acceptability endpoint (*use-as-is*, *acceptable after minor edits*, *clinically acceptable*) is a **binomial proportion**. Size it to a target CI half-width δ: ``` n ≈ (z/δ)² · p(1−p) z = 1.96 for 95% ``` At p = 0.90 and δ = 0.05 that is ≈ **138 cases**; at p = 0.50 (the worst case, and the value to use when the pilot is thin) it is ≈ **384**. Two consequences follow immediately. A proportion near the ceiling is cheap and one near 50% is expensive — and **you do not know which you have until you measure**, so size on the pessimistic p unless a pilot in the same anatomy justifies otherwise. And the rate is **per structure class**: acceptability is not one number (accepted use-as-is rates for a single pipeline have ranged from ~40% for target volumes to ~89% for normal tissue), so size on the **structure whose acceptability you must claim**, not on the pooled average. If the claim is against a threshold ("≥80% of cases acceptable"), size the **one-sided** comparison of the observed proportion to that threshold, and state the threshold and its justification before the data — a threshold chosen after seeing the rate is not a threshold. ## Ratings are nested in cases — a rate judged by k readers is not a simple binomial When m readers rate each of n cases, the total **is not** n·m independent observations. Ratings of the same case are correlated (an easy case is easy for every reader) and ratings by the same reader are correlated (a lenient reader is lenient throughout). Pooling them as independent overstates precision by the **design effect**: ``` DE ≈ 1 + (m − 1)·ρ n_effective ≈ n·m / DE ``` With 3 readers per case and ρ = 0.5, DE = 2 — half the apparent sample. Either analyse at the **case level** (a pre-specified consensus or majority rule across readers, then a plain binomial on n cases) or model the clustering (mixed-effects / GEE with case and reader as random effects) and size with the inflation. Pick one at design time; the choice changes n by a factor of two or more. ## Bounding a catastrophic-failure rate — the rule of three A usability claim usually carries an implicit safety claim: *catastrophic failures are rare*. Rarity has to be sized for, and it is expensive. If **zero** events are observed in n cases, the one-sided 95% upper bound on the rate is approximately ``` upper bound ≈ 3 / n ``` So bounding a catastrophic-failure rate at **≤ 1% requires ~300 clean cases**; at ≤ 0.5%, ~600. This is the number that most often breaks a usability claim retrospectively: a study sized to estimate mean Dice on 40–60 cases can observe zero catastrophic failures and still only bound the rate at ~5–8%, which is not a safety statement. If the design cannot reach n, say what the observed data can actually bound rather than reporting "no failures occurred" as though it settled the question. ## Edit time / correction effort — paired, per structure If the claim is that the model saves work, the endpoint is a **paired per-case time difference** (edit the auto-contour vs contour from scratch, same cases): size on the **SD of the per-case difference**, exactly as in Test 16, not on the SDs of the two marginal times. Two design points the published record insists on: - **Size per structure, not on the pooled saving.** A multi-centre evaluation reporting an overall 46% saving simultaneously found **no significant saving** for five lymph-node levels, and some centres were **slower editing than contouring manually**. A study powered only on the pooled contrast cannot support or refute any per-structure claim. - **Site is a second grouping factor.** If the claim is multi-centre, the per-centre effects differ in sign, so size for the centres you intend to claim over (or restrict the claim). ## Required parameters The **acceptability definition and scale** and which level counts as "accepted" (*use-as-is* and *acceptable-after-minor-edits* are different endpoints with different n); the **expected rate p** per structure class (pilot, else 0.5) and the target **δ or threshold**; the **number of readers per case** and the analysis unit (consensus vs mixed-effects) with the assumed ρ; the **catastrophic-rate bound** you must be able to state; and, for a work-saving claim, the **SD of the per-case time difference** per structure. Report n, the assumed p and ρ, the analysis unit, and what failure rate the design can bound. ## Cross-links The usability design this size serves → `design-study` `references/segmentation_failure_characterization_design.md`; the single-metric precision (mean Dice per structure) → `segmentation_metric_sample_size.md` (Test 15); the paired between-model delta → `multi_model_comparison_sample_size.md` (Test 16); reader-in-the-loop diagnostic sizing → `mrmc_reader_study_sample_size.md` (Test 14); presenting the result → `make-figures` `exemplar_plots/segmentation_failure_panel.md`; abstention and risk–coverage instead of a fixed acceptability rate → `/uncertainty-imaging`. -
segmentation_metric_sample_size.md 3.9 KB
# Segmentation-metric sample size (Dice / HD95 / NSD precision) For a **segmentation** validation, the sizing question is not "how many events" but **how many cases to estimate the segmentation metric precisely enough to be conclusive** — and, for a comparison, precisely enough to separate the models. The diagnostic-accuracy calc (Test 1) and the Riley prediction-model calc (Tests 12–13) do not apply: the outcome is a per-case **overlap / boundary** score (Dice, HD95, NSD), bounded and often skewed, not a proportion or a risk. This is the **design-time** case count for a segmentation study — including the external cohort a genuine generalization claim needs (see `design-study/references/combine_models_ablation_design.md` and `venue_accept_recipe.md`). ## Why a proportion/events calculation is the wrong tool Per-case **Dice is bounded [0,1] and heteroscedastic**: near-ceiling and low-variance for large, easy organs, but low and high-variance for **small or hard structures**. Precision therefore depends on the **SD of per-case Dice**, which you must take from a **pilot or literature** — not from a formula that assumes a proportion. **HD95 / NSD** are even more skewed (a few outlier cases dominate), so their precision is worse at the same n. ## Precision sizing (estimate a mean metric within ±δ) To estimate the mean metric with a two-sided 95% CI half-width **δ**: n ≈ ( 1.96 · SD / δ )² where **SD** is the pilot/literature SD of the **per-case** metric. Because Dice is bounded and non-normal, **report the CI by bootstrapping the per-case values (BCa)**, not a naïve normal CI — the formula sizes the study, the bootstrap reports it. For near-ceiling Dice consider a variance- stabilizing view or report the full distribution, since a symmetric ±δ misleads at the ceiling. ## Comparison sizing (model A vs B, or internal vs external, or an ablation contrast) A model comparison on the **same cases** is **paired**: size on the **SD of the per-case *difference*** (usually much smaller than the marginal SD, because easy cases are easy for both) or, for an "as good as" claim, a **non-inferiority margin** on Dice. This is the calculation behind the ablation contrasts in `combine_models_ablation_design.md` (un-adapted base, best single component, direct-train-vs-transfer) — each needs enough cases to make its ΔDice CI exclude zero (or the margin). ## Size on the worst structure, and size the external cohort - **Per-structure, not the average.** Small/hard structures dominate the variance; size on the **worst structure you must report**, or the study is under-powered exactly where it matters (the batch's honest failures: orbital-lymphoma T1c, medulloblastoma cystic subregions). - **The external cohort needs its own n.** The #1 acceptance lever is a *precise* external estimate with an honest drop; a 30-case external set gives a wide Dice CI. Size it to the precision the generalization claim requires (the G72 batch's external cohorts — AMOS, a 33-patient 3-centre set, a 72-CT set — motivate the range). ## Required parameters + compute - Pilot/literature **SD of the per-case metric** (per structure), the target **precision δ** or the **NI margin**, the metric itself. A t-interval on mean per-case Dice is closed-form, but the metric is **bounded and skewed near the ceiling**, so its nominal coverage is not the real one → **bootstrap per-case values** (BCa, resampling whole patients rather than structures); use the pilot for SD. Report N, the per-structure SD source, and δ / margin. ## Cross-links Metric **selection** (Dice + a boundary/agreement metric, per-structure) → `/model-evaluation`; validation design + the split-leakage gate → `/model-validation`; the comparator/ablation the size serves → `design-study/references/combine_models_ablation_design.md`; presenting the across-cohort result → `make-figures` `exemplar_plots/external_validation_comparison.md`.
-
-
SKILL.md 32.7 KB
--- name: calc-sample-size description: > Interactive sample size calculator for medical research. Decision-tree guided test selection, reproducible R/Python code, effect size interpretation, and IRB-ready justification text. Supports diagnostic accuracy, agreement, proportions, continuous outcomes, survival, ANOVA, logistic regression, and non-inferiority/equivalence designs. triggers: sample size, power analysis, power calculation, how many patients, how many subjects, IRB sample size tools: Read, Write, Edit, Bash, Grep, Glob model: inherit --- # Calc-Sample-Size Skill You are assisting a medical researcher with sample size and power calculations. Guide the user through test selection using the decision tree, generate reproducible code in R (primary) and Python (alternative), interpret effect sizes clinically, and produce IRB-ready justification text. ## Reference Files - **Formulas**: `${CLAUDE_SKILL_DIR}/references/formulas.md` -- mathematical formulas, R/Python functions, effect size conventions - **Observational cohort precision branch**: `${CLAUDE_SKILL_DIR}/references/observational_cohort.md` - **Prediction-model / medical-AI sample size (Riley)**: `${CLAUDE_SKILL_DIR}/references/prediction_model_sample_size.md` -- the current TRIPOD+AI-aligned standard for a clinical prediction/classification model (development via `pmsampsize`, external validation via `pmvalsampsize`, net-benefit precision). Use this instead of EPV-10 whenever the goal is risk prediction for use rather than a single-predictor hypothesis test (Tests 12-13). - **MRMC reader-study sample size (Obuchowski–Rockette)**: `${CLAUDE_SKILL_DIR}/references/mrmc_reader_study_sample_size.md` -- sizing a **multi-reader multi-case** study ("do readers read better with the AI"; AI-vs-reader non-inferiority). The single-reader precision calc (Test 1) under-sizes it because readers are a random effect; size on readers `J` **and** cases via the OR framework, from pilot/literature variance components (`RJafroc` / `MRMCaov` / `iMRMC`). Use whenever a reader study is the design (Test 14). - **Segmentation-metric precision (Dice / HD95 / NSD)**: `${CLAUDE_SKILL_DIR}/references/segmentation_metric_sample_size.md` -- sizing a segmentation validation by the precision of the per-case overlap/boundary score (not a proportion): `n ≈ (1.96·SD/δ)²` from the pilot SD of per-case Dice, per structure (size on the worst), bootstrap-BCa CI, paired for a model comparison, and size the external cohort. Use whenever the outcome is Dice/HD95/NSD (Test 15). - **Between-model comparison sample size**: `${CLAUDE_SKILL_DIR}/references/multi_model_comparison_sample_size.md` -- sizing a study whose claim is that **one model beats others** (several models head-to-head). Single-model precision under-sizes it: power the **difference**. Pair the design (same cases through all models) → size on the **SD of the per-case difference**; **DeLong** for a paired ΔAUC, bootstrap-paired for ΔDice; for **>2 models** pre-specify one primary contrast or pay the family-wise multiplicity; and for a ranking claim, seed for **rank stability** (Nadeau–Bengio variance, Demšar critical-difference). Use whenever the endpoint is "model A > B/C/…" (Test 16). - **Segmentation usability sample size**: `${CLAUDE_SKILL_DIR}/references/segmentation_acceptability_sample_size.md` -- sizing a **usability** claim rather than a metric: the acceptability endpoint is a **proportion** (`n ≈ (z/δ)²p(1−p)`, size on the pessimistic p, size **per structure class**); ratings by m readers are **nested**, so pooling n·m overstates precision by `1+(m−1)ρ`; bounding a **catastrophic-failure rate** needs the **rule of three** (≤1% ⇒ ~300 clean cases — a metric-precision study bounds nothing); **edit time** is a paired per-case difference sized per structure and per site. Use whenever the claim is "clinicians can use this" (Test 17). - **Justification prose exemplars**: `${CLAUDE_SKILL_DIR}/references/justification_examples.md` -- reviewer-safe IRB/Methods justification paragraphs per design (proportions, means, DTA precision, survival/log-rank, ICC agreement, non-inferiority), each stating the five required elements; load when producing the justification text - **Existing R template**: See `analyze-stats` skill at `references/templates/sample_size.R` for the 7 original tests Read `formulas.md` before generating calculation code. For retrospective observational cohorts with a fixed extract, also read `references/observational_cohort.md` and report event budget / confidence-interval precision instead of forcing a prospective recruitment-style power calculation. ## Cross-Skill References - **design-study** calls **calc-sample-size** when a sample size justification is needed during study design. - **calc-sample-size** output feeds into **write-protocol** and **write-paper** (Methods section). - Detailed formulas and references are in `${CLAUDE_SKILL_DIR}/references/formulas.md`. --- ## Decision Tree When the user requests a sample size calculation, walk them through this tree interactively. Ask one question at a time. Do not assume answers. ``` What is your primary outcome? | +-- Binary (yes/no, positive/negative) | | | +-- Paired data (same subjects, two methods)? | | +-- YES --> [5] McNemar test | | +-- NO --> How many groups? | | +-- 2 groups, superiority --> [4] Two-proportion comparison (chi-square) | | +-- 2 groups, non-inferiority --> [10] Non-inferiority / equivalence | | +-- Multivariable model --> single-predictor hypothesis test? --> [9] Logistic regression | | --> clinical prediction / AI model for use? | | +-- developing the model --> [12] Prediction-model development (Riley) | | +-- externally validating --> [13] External-validation (Riley) | | +-- Continuous (measurement, score) | | | +-- How many groups? | +-- 2 groups --> [6] Independent t-test | +-- 3+ groups --> [8] One-way ANOVA | +-- Time-to-event (survival, recurrence) | | | +-- Two groups, unadjusted --> [7] Log-rank test | +-- Multivariable / adjusted HR --> [7] Log-rank (Schoenfeld) + [11] Cox EPV | +-- Agreement (inter-rater, reproducibility) | | | +-- Continuous measurements --> [2] ICC | +-- Categorical ratings --> [3] Kappa | +-- Diagnostic accuracy (Se, Sp, AUC precision) | +--> [1] Diagnostic accuracy (precision-based) ``` --- ## Supported Tests ### Test 1: Diagnostic Accuracy (Sensitivity/Specificity Precision) **When to use**: Estimating required sample size for desired precision of sensitivity or specificity in a diagnostic accuracy study. **Required parameters** (ask the user): | Parameter | Description | Default | |-----------|-------------|---------| | `sensitivity_expected` | Expected sensitivity | 0.85 | | `ci_half_width` | Desired half-width of 95% CI | 0.05 | | `prevalence` | Disease prevalence in study population | 0.30 | | `alpha` | Significance level | 0.05 | | `attrition_rate` | Expected dropout/exclusion rate | 0.15 | **Effect size interpretation**: The CI half-width determines precision. A half-width of 0.05 means the 95% CI for sensitivity will be within +/-5 percentage points. Narrower CIs require larger samples. --- ### Test 2: ICC Agreement (Bonett 2002) **When to use**: Inter-rater or intra-rater agreement for continuous measurements (e.g., tumor size, angle measurement). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `icc_expected` | Expected ICC value | 0.75 | | `icc_null` | Null hypothesis ICC (lower bound) | 0.50 | | `n_raters` | Number of raters | 2 | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.10 | **Effect size interpretation**: ICC < 0.50 = poor, 0.50-0.75 = moderate, 0.75-0.90 = good, > 0.90 = excellent (Koo & Li, 2016). --- ### Test 3: Kappa Agreement (Donner & Eliasziw 1992) **When to use**: Inter-rater agreement for categorical ratings (e.g., BI-RADS category, lesion present/absent). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `kappa_expected` | Expected kappa value | 0.70 | | `kappa_null` | Null hypothesis kappa | 0.40 | | `po_expected` | Expected proportion of agreement | 0.75 | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.10 | **Effect size interpretation**: Kappa < 0.20 = slight, 0.21-0.40 = fair, 0.41-0.60 = moderate, 0.61-0.80 = substantial, 0.81-1.00 = almost perfect (Landis & Koch, 1977). --- ### Test 4: Two-Proportion Comparison (Chi-Square) **When to use**: Comparing proportions between two independent groups (e.g., AI detection rate vs. conventional detection rate). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `p1` | Proportion in group 1 | -- | | `p2` | Proportion in group 2 | -- | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.15 | **Effect size interpretation**: Cohen's h = 2 * arcsin(sqrt(p1)) - 2 * arcsin(sqrt(p2)). Small = 0.20, medium = 0.50, large = 0.80. --- ### Test 5: McNemar Test (Paired Proportions) **When to use**: Paired binary outcomes (e.g., two readers reading same cases, before/after on same patients). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `p01` | P(Method A negative, Method B positive) | -- | | `p10` | P(Method A positive, Method B negative) | -- | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.10 | **Effect size interpretation**: The ratio p10/p01 (discordant ratio) drives the required sample size. Larger asymmetry in discordant pairs means fewer subjects needed. Only discordant pairs contribute information. --- ### Test 6: Independent t-Test **When to use**: Comparing means between two independent groups (e.g., lesion size in malignant vs. benign). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `mean_diff` | Expected mean difference | -- | | `pooled_sd` | Pooled standard deviation (from literature/pilot) | -- | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.15 | **Effect size interpretation**: Cohen's d = mean_diff / pooled_sd. Small = 0.20, medium = 0.50, large = 0.80. In clinical terms, d = 0.50 means the groups differ by half a standard deviation. --- ### Test 7: Survival / Log-Rank Test (Schoenfeld 1981) **When to use**: Comparing survival or time-to-event between two groups (e.g., treatment vs. control, RFA vs. surgery). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `hr` | Expected hazard ratio | -- | | `median_ctrl` | Median survival in control arm (months) | -- | | `accrual_time` | Accrual period (months) | 12 | | `follow_up` | Follow-up after accrual (months) | 24 | | `drop_rate` | Annual dropout rate | 0.05 | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | **Effect size interpretation**: HR < 1 favors treatment. HR = 0.50 means treatment halves the hazard (strong effect). HR = 0.80 is a modest 20% reduction. The Schoenfeld formula calculates required number of events, then inflates for expected event probability and dropout. --- ### Test 8: One-Way ANOVA (NEW) **When to use**: Comparing means across 3 or more independent groups (e.g., comparing AI model performance across 3 architectures, comparing measurement accuracy across multiple readers). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `k` | Number of groups | -- | | `f` | Cohen's f effect size | -- | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.15 | **Help user estimate Cohen's f**: - If the user knows group means and pooled SD: f = sigma_means / pooled_SD - If the user knows eta-squared: f = sqrt(eta_sq / (1 - eta_sq)) - Benchmarks: small = 0.10, medium = 0.25, large = 0.40 **R function**: `pwr::pwr.anova.test(k, f, sig.level, power)` **Python equivalent**: `statsmodels.stats.power.FTestAnovaPower().solve_power(effect_size, nobs, alpha, power, k_groups)` **Effect size interpretation**: Cohen's f = 0.25 (medium) means the group means span about half a pooled SD. In clinical terms, this is typically a meaningful difference across treatment arms or measurement methods. --- ### Test 9: Logistic Regression (NEW) **When to use**: Multivariable binary outcome models (e.g., predicting malignancy from multiple imaging features). Two approaches are provided. **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `n_predictors` | Number of predictor variables | -- | | `event_rate` | Expected event rate (proportion with outcome) | -- | | `or_interest` | Odds ratio of interest (for Hsieh formula) | -- | | `r2_other` | R-squared of covariate with other predictors | 0.0 | | `alpha` | Significance level | 0.05 | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.10 | **Approach A: Peduzzi Rule of Thumb (EPV >= 10)** - N_events = 10 * n_predictors - N_total = N_events / event_rate - Simple, widely cited, conservative. Use as a minimum baseline **for a single-predictor hypothesis test only**. For a **clinical prediction / medical-AI model intended for use**, EPV-10 is outdated and reviewer-vulnerable — use the Riley criteria in Test 12 (development) / Test 13 (validation) instead. **Approach B: Hsieh (1989) Formula** - Uses the OR of interest for the primary predictor to calculate a more precise sample size. - Accounts for correlation with other predictors via R-squared adjustment. **Always report both approaches** and recommend the larger N. **Effect size interpretation**: OR = 1.5 is a small-to-moderate effect; OR = 2.0 is moderate; OR = 3.0+ is large. The Peduzzi rule ensures model stability; the Hsieh formula targets power for the primary predictor. --- ### Test 10: Non-Inferiority / Equivalence (NEW) **When to use**: Demonstrating that a new method is not worse than the standard by more than a pre-specified margin (non-inferiority) or that two methods are equivalent within a margin (equivalence / TOST). **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `design` | "non-inferiority" or "equivalence" | "non-inferiority" | | `outcome_type` | "proportion" or "continuous" | -- | | `p_reference` | Reference group proportion (if proportion) | -- | | `margin` | Non-inferiority or equivalence margin (delta) | -- | | `sd` | Standard deviation (if continuous) | -- | | `alpha` | One-sided alpha for NI; two one-sided for equivalence | 0.025 (NI) / 0.05 (equiv) | | `power` | Desired power | 0.80 | | `attrition_rate` | Expected dropout rate | 0.15 | **Key guidance for margin selection**: - The margin must be clinically justified and smaller than the effect of the reference treatment vs. placebo. - Common approach: margin = 50% of the established treatment effect (preservation of effect). - For proportions: absolute difference margin (e.g., delta = 0.10 means new method can be at most 10 percentage points worse). - For continuous: margin in the same unit as the outcome. **Non-inferiority (one-sided test)**: - H0: new - reference <= -margin (new is inferior) - H1: new - reference > -margin (new is non-inferior) - Alpha is one-sided (typically 0.025). **Equivalence (TOST)**: - H0: |new - reference| >= margin - H1: |new - reference| < margin - Two one-sided tests, each at alpha (typically 0.05 overall). **Effect size interpretation**: The margin defines the largest clinically acceptable difference. A smaller margin requires a larger sample. Always justify the margin based on clinical reasoning and prior literature. --- ### Test 11: Cox Regression EPV (Events Per Variable) **When to use**: Multivariable Cox proportional hazards models — ensuring enough events for stable model estimates. Same EPV logic as logistic regression (Test 9), applied to time-to-event outcomes. **Required parameters**: | Parameter | Description | Default | |-----------|-------------|---------| | `n_predictors` | Number of predictor variables in Cox model | -- | | `event_rate` | Expected proportion of subjects experiencing the event | -- | | `epv` | Events per variable target | 10 | | `attrition_rate` | Expected dropout rate | 0.10 | **Formula**: ``` N_events = EPV × n_predictors N_total = N_events / event_rate N_adj = N_total / (1 - attrition_rate) ``` **EPV guidelines**: - EPV >= 10: minimum for stable estimates (Peduzzi et al., 1995) - EPV >= 20: recommended for reliable CI coverage and type I error control - EPV < 5: model likely unstable — reduce predictors or use penalized methods **Effect size interpretation**: The EPV rule ensures model stability, not power for a specific HR. If the user also needs power for detecting a specific HR, combine with Test 7 (log-rank/Schoenfeld) and report the larger N. **Always report both approaches** (EPV minimum + Schoenfeld power, if HR is available) and recommend the larger N. --- ### Test 12: Prediction-Model Development (Riley) **When to use**: developing a clinical prediction / classification model (including a medical-AI model evaluated as one) — the goal is risk prediction *for use*, not a single predictor's hypothesis test. EPV-10 (Tests 9/11) is outdated here. **Approach**: the minimum N is the largest satisfying all four Riley criteria simultaneously — global shrinkage ≥ 0.9, apparent–adjusted R² gap ≤ 0.05, precise overall risk estimate, and (time-to-event) precise baseline survival. Implemented in R `pmsampsize`. **Required parameters**: number of **candidate predictor parameters** (count dummy/non-linear terms), a conservative expected **C-statistic or Cox-Snell R²** (with its literature source), and outcome **prevalence** (binary) or **event rate + mean follow-up** (time-to-event). Read `${CLAUDE_SKILL_DIR}/references/prediction_model_sample_size.md` for the criteria, the `pmsampsize` code, and the reporting requirements. Report N + required events + the binding criterion + the assumed C/R² and its source. --- ### Test 13: External-Validation Sample Size (Riley) **When to use**: sizing an **external validation** of an existing prediction/AI model. **Approach**: size to estimate the key validation metrics *precisely enough to be conclusive* — target the CI width of the **C-statistic**, the **calibration slope**, the **calibration-in-the-large / O:E ratio**, and (if a utility claim) **net benefit**. Implemented in R `pmvalsampsize`. A floor of ≥ 100 events and ≥ 100 non-events applies, but the precise target is usually larger. **Required parameters**: expected **prevalence**, anticipated **C-statistic**, and the target CI widths. Read `${CLAUDE_SKILL_DIR}/references/prediction_model_sample_size.md` for the `pmvalsampsize` code. Report the targeted CI widths and the resulting events / non-events. --- ### Test 14: MRMC Reader Study (Obuchowski–Rockette) **When to use**: sizing a **multi-reader multi-case (MRMC) reader study** — "do readers read better *with* the AI", or "is the AI non-inferior to readers". The single-reader AUC-precision calculation (Test 1) **under-sizes** this: readers as well as cases are random, so power must cover the **reader-variance** term, and a null from an under-sized reader study is *inconclusive, not negative*. **Approach**: invert the OR variance formula over the number of readers `J` and the case counts `N⁺`/`N⁻`; report the **`J × N` power grid** (past a modest case count, adding readers usually buys more power than adding cases). Requires **variance components** from a pilot or literature — the real bottleneck. Implemented in R `RJafroc` / `MRMCaov` / FDA `iMRMC` (integrate; do not hand-roll the OR algebra). **Required parameters**: the **effect** (ΔAUC, or the **non-inferiority margin** — an AI-vs-reader claim is usually NI), the expected AUC level, the **variance components** (pilot/literature), the **design** (fully-crossed vs crossover-with-washout), and power/α. Read `${CLAUDE_SKILL_DIR}/references/mrmc_reader_study_sample_size.md` for the framework, the readers-vs-cases trade-off, software, and reporting. Reader-study *design internals* live in `design-study` (`reader_elicitation_design.md`); an AI-vs-human-expert benchmark routes to `/design-ai-benchmarking`. --- ### Test 15: Segmentation-metric precision (Dice / HD95 / NSD) **When to use**: sizing a **segmentation** validation — how many cases to estimate the segmentation metric (Dice / HD95 / NSD) precisely enough to be conclusive, or to separate two models. The proportion/events calcs (Tests 1, 12–13) do not apply: the outcome is a bounded, skewed per-case overlap/boundary score, not a proportion. **Approach**: precision sizing `n ≈ (1.96·SD/δ)²` from the **pilot/literature SD of per-case Dice** (per structure — size on the **worst** structure you must report, not the average); report the CI by **bootstrapping per-case values (BCa)** — a t-interval is closed-form but Dice is bounded and non-normal near the ceiling, so its coverage is not the coverage you asked for, and BCa must resample whole **patients**, not structures. A model comparison on the same cases is **paired** (size on the SD of the per-case *difference*, or an NI margin). **Size the external cohort too** — a precise external estimate is the #1 acceptance lever. **Required parameters**: the **per-structure SD of per-case Dice** (pilot/literature), the target **precision δ** or **NI margin**, and the metric. Read `${CLAUDE_SKILL_DIR}/references/segmentation_metric_sample_size.md` for the per-structure and paired-comparison detail. The comparator/ablation the size serves lives in `design-study` (`combine_models_ablation_design.md`); metric selection is `/model-evaluation`. --- ### Test 16: Between-model comparison (is model A really better than B, C, …) **When to use**: the claim is that **one model outperforms others** — several architectures / families compared head-to-head on the same task. Single-model precision (Test 1 AUC, Test 15 Dice) under-sizes it: two models can each have a tight CI and still overlap, so the **difference** must be powered. **Approach**: run all models on the **same cases** (paired / within-case) and size on the **SD of the per-case difference** — `σ√(2(1−ρ))`, below either marginal SD once ρ > 0.5, which shared easy/hard cases usually clear. Use **DeLong** for a paired ΔAUC (or Obuchowski for the MRMC/clustered case) and a **bootstrap of the paired per-case differences** for ΔDice; size so the delta CI excludes zero, or so its lower bound clears the NI margin (the whole interval inside ±margin is *equivalence*, a stricter claim). For **>2 models**, pre-specify **one primary contrast** (proposed vs a strong, fairly-tuned baseline) at full α — or, if all pairwise are confirmatory, pay the **family-wise** correction (higher n per contrast). For a **ranking** claim, a single-run leaderboard ranks by luck: train over **multiple seeds** (Nadeau–Bengio corrected variance for repeated-CV differences) and leave models inside the **Demšar critical difference** unranked — not separated by the test is not a demonstrated tie, and Demšar's N counts independent datasets, not seeds. **Required parameters**: the **per-case-difference SD** of the primary metric (pilot / prior head-to-head; per structure for segmentation), the metric + paired-CI method, the target **δ or NI margin on the delta**, the **number of models + the primary contrast**, and (for ranking) the **seed-to-seed SD**. Read `${CLAUDE_SKILL_DIR}/references/multi_model_comparison_sample_size.md` for the paired-difference, multiplicity, and ranking-stability detail. The fair-comparison design the size serves lives in `design-study` (`multi_model_comparison_design.md`); presenting it is `make-figures` (`exemplar_plots/model_comparison_leaderboard.md`). --- ### Test 17: Segmentation usability (acceptability rate, failure bound, edit time) **When to use**: the claim is that a segmentation model is **clinically usable** — a share of cases a clinician accepts, a bounded catastrophic-failure rate, a time saving — not that its mean metric is high. Test 15 sizes a mean Dice to a precision and says nothing about any of these. **Approach**: an acceptability endpoint is a **proportion**: `n ≈ (z/δ)²·p(1−p)` — ≈138 cases at p = 0.90, δ = 0.05, but ≈384 at p = 0.50, so size on the pessimistic p unless a pilot in the same anatomy says otherwise, and size **per structure class** (use-as-is rates for one pipeline have run from ~40% for target volumes to ~89% for normal tissue). When m readers rate each case the ratings are **nested**, not independent: pooling n·m overstates precision by `DE ≈ 1 + (m−1)ρ` (3 readers at ρ = 0.5 halves it) — pre-specify either a case-level consensus rule or a mixed-effects/GEE analysis. To bound a **catastrophic-failure rate**, zero events in n cases gives an upper bound of ≈ `3/n` (**rule of three**), so ≤1% needs ~300 clean cases; a 40–60-case study bounds nothing below ~5–8%. For an **edit-time** claim, size the paired per-case time difference (as Test 16) **per structure and per site** — pooled savings coexist with structures and centres showing none. **Required parameters**: the acceptability scale and which level counts as accepted (*use-as-is* vs *after minor edits* are different endpoints), the expected **p** per structure class and target **δ or threshold**, the **readers per case** + analysis unit + assumed **ρ**, the **catastrophic bound** you must state, and (for work saving) the **SD of the per-case time difference**. Read `${CLAUDE_SKILL_DIR}/references/segmentation_acceptability_sample_size.md` for the proportion, clustering, rule-of-three and edit-time detail. The usability design the size serves lives in `design-study` (`segmentation_failure_characterization_design.md`); presenting it is `make-figures` (`exemplar_plots/segmentation_failure_panel.md`). --- ## Scope Limitations ### Supported The 11 tests listed above cover the vast majority of sample size calculations needed in medical imaging research, diagnostic accuracy studies, and clinical trials. ### NOT Supported The following designs require specialized software or biostatistician consultation: - **Adaptive trials** (group-sequential, sample size re-estimation) - **Cluster-randomized trials** (design effect, ICC-based inflation) - **Bayesian sample size determination** - **Crossover designs** - **Multi-endpoint correction** (mention Bonferroni adjustment if asked, but do not compute corrected sample sizes) If the user requests any of these, respond: > "This design requires specialized tools beyond this skill's scope. Consider using G*Power software (free, https://www.psychologie.hhu.de/gpower), PASS software, or consulting a biostatistician for [specific design]." --- ## Workflow ### Phase 1: Understand the Study 1. Ask the user to describe their study briefly (design, primary outcome, groups). 2. Walk through the decision tree to identify the appropriate test. 3. Confirm the selected test with the user before proceeding. ### Phase 2: Collect Parameters 1. Present the parameter table for the selected test. 2. For each parameter without a user-provided value, explain what it means and offer the default. 3. Help the user estimate effect sizes from: - Prior literature (ask for references) - Pilot data - Cohen's conventions (as a last resort, with a note that convention-based estimates are less precise) ### Phase 2b: Retrospective Study — Experience-Based Sample Size Justification For retrospective studies, formal power analysis is often impractical because the dataset already exists. In these cases, an experience-based justification is acceptable for IRB and many journals. Offer this path when the user describes a retrospective design. **Two approaches**: #### Approach A: Institution Volume-Based Estimate N from the number of examinations performed at the institution during the study period. ``` Total exams in period × prevalence of target condition × (1 - exclusion rate) = Expected N ``` - Ask the user for: annual exam volume for the modality, study period length, estimated prevalence, and expected exclusion rate - This gives a realistic upper bound for N **IRB justification template**: > Based on approximately [X] [modality] examinations performed annually at [institution], > and an estimated prevalence of [condition] of [Y]%, we anticipate identifying approximately > [N] eligible patients over the [Z]-year study period. After accounting for an estimated > [W]% exclusion rate (due to [reasons]), we expect a final sample of approximately [N_adj] > patients for analysis. #### Approach B: Prior Study-Based Use sample sizes from published studies with similar designs as justification. - Search for 3-5 comparable studies and report their sample sizes - The user's N should be in the same range or larger - Cite the specific studies in the IRB justification **IRB justification template**: > Previous studies evaluating [similar topic] with [similar design] enrolled [N1] (Author1 > et al., Year), [N2] (Author2 et al., Year), and [N3] (Author3 et al., Year) patients. > Our anticipated sample of [N] patients is [comparable to / larger than] these prior studies. #### When to Use Formal Calculation Instead Even for retrospective studies, a formal sample size calculation is preferred when: - The study is prospective or will prospectively enroll a subset - The primary analysis involves hypothesis testing (not just estimation) - The journal explicitly requires power analysis (check Instructions for Authors) - The IRB requires it for approval In these cases, proceed to Phase 3 with the appropriate test from the decision tree. --- ### Phase 3: Calculate and Report 1. Read `${CLAUDE_SKILL_DIR}/references/formulas.md` for the exact formula. 2. Generate the R code (primary) and Python code (alternative). 3. Run the R code via Bash to produce the actual result. 4. Present results in the output format below. ### Phase 4: Sensitivity Analysis (Optional) If the user is uncertain about parameters, offer a sensitivity table showing N across a range of plausible values (e.g., varying effect size or power from 0.80 to 0.90). --- ## Output Format Always structure the final output as follows: ```markdown ## Sample Size Calculation Report ### Study Design [1-2 sentence summary of the design and test selected] ### Parameters | Parameter | Value | Source | |-----------|-------|--------| | ... | ... | user / literature / convention | ### Result - **Required sample size**: N = [value] - **With [X]% attrition adjustment**: N_adj = [value] ### R Code (Reproducible) ```r # [complete, self-contained R script] # Dependencies: [list packages] # Run: Rscript sample_size_calc.R ``` ### Python Code (Alternative) ```python # [complete, self-contained Python script] # Dependencies: [list packages] # Run: python sample_size_calc.py ``` ### IRB Justification Text > A sample of [N] participants is required to detect [effect description] with [power]% power > at a [one/two]-sided significance level of [alpha], assuming [key assumptions]. > Accounting for an estimated [X]% attrition rate, we plan to enroll [N_adj] participants. > This calculation is based on [formula/method reference]. ### Effect Size Interpretation [Cohen's benchmark classification + clinical meaning in the context of this study] ``` --- ## IRB Justification Text Guidelines The IRB text must: 1. State the required N clearly. 2. Name the statistical test and its formula source. 3. Specify all assumed parameters (effect size, alpha, power). 4. State the attrition adjustment and final enrollment target. 5. Cite the methodological reference (e.g., "Schoenfeld, 1981" for survival). 6. Use formal, third-person language suitable for an ethics board. --- ## Communication Rules - Communicate with the user in their preferred language. - Use English for all statistical terminology, effect size names, and test names. - Be explicit about assumptions and their impact on the result. - When the user provides vague effect size estimates, flag the uncertainty and suggest a sensitivity analysis. - Never fabricate references. Cite only verified methodological sources from `formulas.md`. ## Anti-Hallucination - **Never fabricate file paths, URLs, DOIs, or package names.** Verify existence before recommending. - **Never invent journal metadata, impact factors, or submission policies** without verification at the journal's website. - If a tool, package, or resource does not exist or you are unsure, say so explicitly rather than guessing. -
skill.yml 2.9 KB
schema_version: 2 name: calc-sample-size layer: A owner_domain: study_design maturity: official when_to_use: - User asks for a sample size, power calculation, or "how many patients/subjects do I need" - Drafting an IRB sample size justification before /write-protocol Methods - Re-deriving N when a reviewer challenges the original power assumption - Estimating events-per-variable (EPV) for survival or logistic regression when_NOT_to_use: - Statistical analysis of collected data (use /analyze-stats) - Choosing the test itself rather than its N (use /design-study) - Replicating a prior study's reported N without recomputation (still re-derive) inputs: - study_design (proportions, continuous, agreement, survival, ANOVA, logistic, NI/equivalence, diagnostic accuracy, repeated measures, Cox EPV) - parameters (effect size, alpha, power, attrition rate, etc.) outputs: - protocol/sample_size_justification.md # IRB-ready prose, Output Format §"IRB Justification Text" - protocol/sample_size_calc.R # reproducible R script - protocol/sample_size_calc.py # alternative reproducible Python script deterministic_scripts: - inline R/Python code blocks (skill-emitted, not packaged) side_effects: - none # no external API calls; pure computation + literature anchoring downstream_consumers: - write-protocol # embeds Output §"IRB Justification Text" verbatim into Methods §Sample Size - write-paper # embeds same text into Methods (post-IRB) - design-study # cross-reference for analysis-unit / cohort-logic alignment ssot_boundary: - protocol/sample_size_justification.md is the canonical sample size text. write-protocol and write-paper EMBED VERBATIM; do not rephrase numbers. quality_gates: - parameters_documented: every parameter has a Source column entry (user / literature / convention) - effect_size_interpretation: Cohen's benchmark classification present - methodological_reference: cited (e.g., "Schoenfeld, 1981" for survival) - reproducible_code: both R and Python emitted (skill default), runnable standalone forbidden_actions: - fabricate_effect_size_from_unverified_assumption - omit_attrition_or_loss_to_followup - silent_protocol_modification # changes to N must update both justification.md and protocol Methods # v2.1 quality card purpose: "Compute sample size / power with decision-tree test selection and reproducible R/Python code plus IRB-ready justification." safety_boundaries: - "Effect-size assumptions are justified and sourced, not fabricated; attrition/loss is accounted for." - "Any change to N updates both the justification and the protocol Methods (no silent change)." known_limitations: - "Emits inline R/Python, not a packaged script; the user runs it." - "Output is only as valid as the assumed effect size and design." validation_commands: - "re-run the emitted power code and confirm N matches the justification" evidence_surface: manual_workflow
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.