import greenwood as gw
gw.logrank_power(hazard_ratio=0.5, n_events=60)0.7656462084964221
Power of the log-rank test given the number of observed events.
Usage
Computes the statistical power to detect a specified hazard ratio using the log-rank test, given a fixed number of observed events in a two-group survival study. This is the inverse calculation of logrank_n_events: instead of finding the events needed for a target power, this function finds the power achieved with a given number of events.
Power depends on three factors:
hazard_ratio): Larger effects (HR far from 1.0) → higher poweralpha): More stringent (smaller alpha) → lower powerUnder the proportional hazards assumption, power depends only on the total event count, not the follow-up duration, censoring rate, or sample size separately. This makes it a practical tool for updating power calculations as events accumulate during a trial.
hazard_ratio: floatThe hazard ratio to detect (group 2 versus group 1). Can be < 1 (group 2 has lower hazard/better survival) or > 1 (group 2 has higher hazard/worse survival). The result is symmetric: HR=0.5 and HR=2.0 give the same power.
n_events: floatTotal number of observed events. Must be positive. Power increases with more events; even small trials can have high power if many events occur.
alpha: float = 0.05Significance level (Type-I error rate, default 0.05). The probability of rejecting the null hypothesis when it’s true. Use alpha=0.05 for two-sided tests with p < 0.05 threshold.
allocation: float = 0.5Fraction of subjects in one group (default 0.5, a balanced design). For unbalanced designs (e.g., 0.3, 0.7), power decreases; balanced allocation minimizes the total sample size needed for a target power.
sides: int = 2 floatSchoenfeld’s formula: Under proportional hazards, the power of the log-rank test is
\[ \mathrm{Power} = \Phi\!\left(\sqrt{d \, p \, (1-p)} \; |\ln(\mathrm{HR})| - z_{1-\alpha/\mathrm{sides}}\right), \]
where \(d\) is the number of events, \(p\) is the allocation fraction, and \(\Phi\) is the cumulative normal distribution function. This formula is exact under proportional hazards and asymptotically valid for finite samples.
Practical use: During a running trial, as events accumulate, you can use this function to assess interim power. If interim power is low despite many events, the effect size may be smaller than anticipated.
A study expects to observe 60 events over its follow-up period. What power does it have to detect a hazard ratio of 0.5 (50% hazard reduction)?
This power (~0.9) is typical for a well-designed trial. Lower power suggests more events are needed, or the effect size is smaller than assumed. Compute power for different effect sizes to understand study sensitivity:
for hr in [0.5, 0.6, 0.7, 0.8]:
power = gw.logrank_power(hazard_ratio=hr, n_events=60)
print(f"HR {hr}: power = {power:.2%}")HR 0.5: power = 76.56%
HR 0.6: power = 50.74%
HR 0.7: power = 28.14%
HR 0.8: power = 13.66%
Use sides=1 for a one-sided test (higher power, but assumes direction is known):
Use unbalanced allocation if one group is larger. Power decreases with imbalance: