logrank_sample_size()

Total sample size needed for the log-rank test to reach a target power.

Usage

Source

logrank_sample_size(
    hazard_ratio,
    prob_event,
    *,
    power=0.8,
    alpha=0.05,
    allocation=0.5,
    sides=2
)

Computes the number of subjects required to observe enough events for a log-rank test to achieve a target power when detecting a specified hazard ratio. This function combines two calculations:

  1. First, it computes the required number of events using logrank_n_events (Schoenfeld’s formula under proportional hazards).
  2. Then, it converts events to subjects using the expected probability that a subject experiences the event during follow-up.

Workflow: Start here to plan study size. You provide the expected effect size (hazard ratio), the fraction of subjects expected to have the event (based on baseline hazard, accrual, and follow-up time), and your desired power. The result is the total enrollment needed.

Parameters

hazard_ratio: float

The hazard ratio to detect (group 2 versus group 1). Smaller HR (e.g., 0.5 = 50% hazard reduction) requires fewer subjects for a given power; larger HR (e.g., 0.8 = 20% hazard reduction) requires more.

prob_event: float

Probability (or fraction) that a subject experiences the event (death, hospitalization, etc.) during the study. Range: (0, 1]. Typical values depend on the condition and follow-up duration:

  • Rare disease (annual incidence 1%): 0.01-0.05 per year of follow-up
  • Common condition (annual incidence 20%): 0.2 per year
  • Study design: shorter follow-up → lower prob_event; longer follow-up → higher

This is usually estimated from historical data, Kaplan-Meier curves, or clinical judgment. Use sensitivity analysis (try 0.3, 0.4, 0.5) if uncertain.

power: float = 0.8

Target statistical power (default 0.8, i.e., 80%). Interpretation: the probability that the study detects the effect if it truly exists. Common choices:

  • 0.80 (80%): Conventional, implies 20% Type-II error rate
  • 0.90 (90%): Higher confidence, requires more subjects
  • 0.95 (95%): Stringent, requires many more subjects
alpha: float = 0.05

Significance level (Type-I error rate, default 0.05). Probability of rejecting the null hypothesis if it’s true. Use 0.05 for two-sided tests with p < 0.05 threshold; use 0.01 for stricter control or 0.10 for more exploratory studies.

allocation: float = 0.5

Fraction of subjects in one group (default 0.5, balanced design). For unbalanced allocation (e.g., control-to-treatment ratio 2:1), use allocation=0.33. Unbalanced allocation increases total sample size needed; use only if required by design or logistics.

sides: int = 2
1 (one-sided) or 2 (two-sided, default). One-sided tests have higher power and require fewer subjects but test directional hypotheses only. Two-sided tests are standard but require more enrollment.

Returns

int
Total number of subjects (enrollment) needed, rounded up. This is the total across all groups.

Details

Relationship between events and subjects:

n_subjects = ceil(n_events / prob_event)

More subjects are needed when:

  • prob_event is low (most subjects censored before event): e.g., 50% power, 50 events needed, but if only 25% get the event, you need 200 subjects.
  • The effect size is smaller: smaller HR requires more events
  • Power is higher: 90% power requires more events than 80%
  • Design is unbalanced: 3:1 allocation needs more subjects than 1:1

Estimating prob_event: Use Kaplan-Meier curves from historical data or prior studies, or calculate from baseline rates: \(\text{prob\_event} \approx 1 - \exp(-\lambda_0 \times t_{\text{follow-up}})\).

Sensitivity analysis: If prob_event is uncertain, compute sample size for a range of values (e.g., 0.3 to 0.5) to understand robustness.

Examples

A trial aims to detect a hazard ratio of 0.5 (50% hazard reduction) with 90% power. Based on historical data, about 40% of subjects are expected to have the event during follow-up. How many subjects must be enrolled?

import greenwood as gw

gw.logrank_sample_size(hazard_ratio=0.5, prob_event=0.4, power=0.9)
219

This sample size (~350) is much larger than the event count from logrank_n_events (~140) because most subjects will be censored before the event occurs.

Perform sensitivity analysis for uncertain event probability. How does sample size change if only 30% or 50% of subjects have events?

for prob in [0.3, 0.4, 0.5]:
    n = gw.logrank_sample_size(hazard_ratio=0.5, prob_event=prob, power=0.9)
    print(f"prob_event={prob}: n={n} subjects, {int(prob * n)} events")
prob_event=0.3: n=292 subjects, 87 events
prob_event=0.4: n=219 subjects, 87 events
prob_event=0.5: n=175 subjects, 87 events

Compare sample size for different effect sizes (smaller HR → fewer subjects):

for hr in [0.5, 0.6, 0.7]:
    n = gw.logrank_sample_size(hazard_ratio=hr, prob_event=0.4, power=0.9)
    print(f"HR {hr}: n={n} subjects")
HR 0.5: n=219 subjects
HR 0.6: n=403 subjects
HR 0.7: n=826 subjects

Use higher power (0.95) if you want to be very confident the effect is detected:

gw.logrank_sample_size(hazard_ratio=0.5, prob_event=0.4, power=0.95)
271

Use unbalanced allocation (e.g., 2:1 control:treatment) if logistics require it:

gw.logrank_sample_size(hazard_ratio=0.5, prob_event=0.4, power=0.9, allocation=1/3)
247