Power Analysis

Sample size and power calculations for clinical trial planning. Supports t-tests, proportions, log-rank, ANOVA, non-inferiority, equivalence, crossover bioequivalence, and cluster randomized trials.

Validates against R packages: pwr, TrialSize, gsDesign, PowerTOST, samplesize.

Sample size and power calculations for clinical trial planning.

Every clinical trial starts with “how many subjects do we need?” This module provides solve-for-any-one-parameter power functions for common trial designs.

Validates against: R packages pwr, TrialSize, gsDesign, PowerTOST, samplesize.

class pystatsbio.power.PowerResult(n, power, effect_size, alpha, alternative, method, note='')[source]

Bases: object

Result of a power/sample size calculation.

Exactly one of n, power, or effect_size will have been solved for (the parameter passed as None). The others are the user-supplied inputs.

Parameters:
n: int | None
power: float | None
effect_size: float | None
alpha: float
alternative: str
method: str
note: str = ''
summary()[source]

Human-readable summary, similar to R’s print.power.htest.

Return type:

str

pystatsbio.power.power_t_test(n=None, d=None, alpha=0.05, power=None, alternative='two.sided', type='two.sample')[source]

Power calculation for t-tests.

Exactly one of n, d, power must be None — that parameter is solved for given the others.

Parameters:
  • n (int or None) – Sample size per group (two-sample) or total (one-sample/paired).

  • d (float or None) – Cohen’s d effect size.

  • alpha (float) – Significance level (default 0.05).

  • power (float or None) – Desired statistical power (1 - beta).

  • alternative (str) – 'two.sided', 'less', or 'greater'.

  • type (str) – 'two.sample', 'one.sample', or 'paired'.

Return type:

PowerResult

Examples

>>> r = power_t_test(d=0.5, alpha=0.05, power=0.80)
>>> r.n
64
>>> r = power_t_test(n=50, d=0.5, alpha=0.05)
>>> round(r.power, 3)
0.697

Validates against: R pwr::pwr.t.test()

pystatsbio.power.power_paired_t_test(n=None, d=None, alpha=0.05, power=None, alternative='two.sided')[source]

Convenience wrapper: power_t_test with type='paired'.

Validates against: R pwr::pwr.t.test(type=’paired’)

Parameters:
Return type:

PowerResult

pystatsbio.power.power_prop_test(n=None, h=None, alpha=0.05, power=None, alternative='two.sided')[source]

Power calculation for two-proportion z-test (chi-squared test).

Exactly one of n, h, power must be None.

Parameters:
  • n (int or None) – Sample size per group.

  • h (float or None) – Cohen’s h effect size: h = 2 * (arcsin(sqrt(p1)) - arcsin(sqrt(p2))).

  • alpha (float) – Significance level (default 0.05).

  • power (float or None) – Desired power.

  • alternative (str) – 'two.sided', 'less', or 'greater'.

Return type:

PowerResult

Examples

>>> import math
>>> h = 2 * (math.asin(math.sqrt(0.5)) - math.asin(math.sqrt(0.3)))
>>> r = power_prop_test(h=h, alpha=0.05, power=0.80)
>>> r.n  # ~93
93

Validates against: R pwr::pwr.2p.test()

pystatsbio.power.power_fisher_test(n=None, p1=None, p2=None, alpha=0.05, power=None, alternative='two.sided')[source]

Power calculation for Fisher’s exact test (normal approximation).

Uses the arcsine (Cohen’s h) normal approximation. For exact power computation via hypergeometric enumeration, a future version will add method='exact'.

Exactly one of n, power must be None (p1 and p2 are always required).

Parameters:
  • n (int or None) – Sample size per group.

  • p1 (float) – Probability in group 1.

  • p2 (float) – Probability in group 2.

  • alpha (float) – Significance level.

  • power (float or None) – Desired power.

  • alternative (str) – 'two.sided', 'less', or 'greater'.

Returns:

  • PowerResult

  • Validates against (R pwr::pwr.2p.test() (via Cohen’s h))

Return type:

PowerResult

pystatsbio.power.power_logrank(n=None, hr=None, alpha=0.05, power=None, alternative='two.sided', p_event=1.0, alloc_ratio=1.0, method='schoenfeld')[source]

Power calculation for the log-rank test.

Exactly one of n, hr, power must be None.

Parameters:
  • n (int or None) – Total sample size (both groups combined).

  • hr (float or None) – Hazard ratio under the alternative hypothesis. Must be != 1.

  • alpha (float) – Significance level (default 0.05).

  • power (float or None) – Desired power.

  • alternative (str) – 'two.sided' or 'one.sided'.

  • p_event (float) – Probability of observing an event (1.0 = no censoring).

  • alloc_ratio (float) – Allocation ratio (n_treatment / n_control). Default 1:1.

  • method (str) – 'schoenfeld', 'freedman', or 'lachin_foulkes'.

Return type:

PowerResult

Examples

>>> r = power_logrank(hr=0.7, alpha=0.05, power=0.80)
>>> r.n  # total N for both groups
186

Validates against: R gsDesign::nSurv(), TrialSize

pystatsbio.power.power_anova_oneway(n=None, f=None, k=2, alpha=0.05, power=None)[source]

Power calculation for one-way ANOVA (balanced design).

Exactly one of n, f, power must be None.

Parameters:
  • n (int or None) – Sample size per group.

  • f (float or None) – Cohen’s f effect size.

  • k (int) – Number of groups (default 2).

  • alpha (float) – Significance level (default 0.05).

  • power (float or None) – Desired power.

Return type:

PowerResult

Examples

>>> r = power_anova_oneway(f=0.25, k=3, alpha=0.05, power=0.80)
>>> r.n  # per group
52

Validates against: R pwr::pwr.anova.test()

pystatsbio.power.power_anova_factorial(n=None, f=None, n_levels=(2, 2), alpha=0.05, power=None, effect='interaction')[source]

Power calculation for factorial ANOVA.

Exactly one of n, f, power must be None.

Parameters:
  • n (int or None) – Sample size per cell.

  • f (float or None) – Cohen’s f effect size for the target effect.

  • n_levels (tuple of int) – Number of levels for each factor, e.g. (2, 3) for a 2x3 design.

  • alpha (float) – Significance level (default 0.05).

  • power (float or None) – Desired power.

  • effect (str) – Which effect: 'interaction', 'main_A', 'main_B', etc.

Return type:

PowerResult

Examples

>>> r = power_anova_factorial(f=0.25, n_levels=(2, 3), alpha=0.05, power=0.80)
>>> r.n  # per cell
36

Validates against: R pwr::pwr.f2.test() (via df conversion)

pystatsbio.power.power_noninf_mean(n=None, delta=None, margin=0.0, sd=1.0, alpha=0.025, power=None, alternative='one.sided')[source]

Power for non-inferiority test of means.

Tests H0: treatment - control <= -margin (treatment is inferior) vs H1: treatment - control > -margin (treatment is non-inferior).

Exactly one of n, delta, power must be None.

Parameters:
  • n (int or None) – Sample size per group.

  • delta (float or None) – True difference in means (treatment - control).

  • margin (float) – Non-inferiority margin (>= 0).

  • sd (float) – Common standard deviation (> 0).

  • alpha (float) – One-sided significance level (default 0.025).

  • power (float or None) – Desired power.

  • alternative (str) – 'one.sided' (standard for NI trials).

Returns:

  • PowerResult

  • Validates against (R TrialSize::TwoSampleMean.NIS())

Return type:

PowerResult

pystatsbio.power.power_noninf_prop(n=None, p1=None, p2=None, margin=0.0, alpha=0.025, power=None)[source]

Power for non-inferiority test of proportions.

Exactly one of n, power must be None (p1 and p2 are always required).

Parameters:
  • n (int or None) – Sample size per group.

  • p1 (float) – Expected proportion in treatment group.

  • p2 (float) – Expected proportion in control group.

  • margin (float) – Non-inferiority margin (>= 0).

  • alpha (float) – One-sided significance level (default 0.025).

  • power (float or None) – Desired power.

Returns:

  • PowerResult

  • Validates against (R TrialSize::TwoSampleProportion.NIS())

Return type:

PowerResult

pystatsbio.power.power_equiv_mean(n=None, delta=None, margin=0.0, sd=1.0, alpha=0.05, power=None)[source]

Power for equivalence test (TOST) of means.

Tests H01: delta <= -margin AND H02: delta >= +margin. Reject both -> equivalence.

Exactly one of n, delta, power must be None.

Parameters:
  • n (int or None) – Sample size per group.

  • delta (float or None) – True difference in means.

  • margin (float) – Equivalence margin (>= 0, symmetric bounds).

  • sd (float) – Common standard deviation (> 0).

  • alpha (float) – Significance level for each one-sided test (default 0.05).

  • power (float or None) – Desired power.

Returns:

  • PowerResult

  • Validates against (R PowerTOST::power.TOST(), TOSTER)

Return type:

PowerResult

pystatsbio.power.power_superiority_mean(n=None, delta=None, margin=0.0, sd=1.0, alpha=0.025, power=None)[source]

Power for superiority test of means.

Tests H0: treatment - control <= margin (no superiority) vs H1: treatment - control > margin (treatment is superior).

Exactly one of n, delta, power must be None.

Parameters:
  • n (int or None) – Sample size per group.

  • delta (float or None) – True difference in means.

  • margin (float) – Superiority margin (>= 0).

  • sd (float) – Common standard deviation (> 0).

  • alpha (float) – One-sided significance level (default 0.025).

  • power (float or None) – Desired power.

Returns:

  • PowerResult

  • Validates against (R TrialSize)

Return type:

PowerResult

pystatsbio.power.power_crossover_be(n=None, cv=None, theta1=0.8, theta2=1.25, theta0=0.95, alpha=0.05, power=None)[source]

Power for 2x2 crossover bioequivalence study (TOST on log-scale).

Standard average bioequivalence (ABE) design. Exactly one of n, power must be None.

Parameters:
  • n (int or None) – Total number of subjects (both sequences).

  • cv (float) – Within-subject coefficient of variation (e.g., 0.30 for 30% CV). Always required.

  • theta1 (float) – Lower bioequivalence limit (default 0.80).

  • theta2 (float) – Upper bioequivalence limit (default 1.25).

  • theta0 (float) – Assumed true ratio of geometric means (default 0.95).

  • alpha (float) – Significance level for TOST (default 0.05, i.e. two one-sided 0.025).

  • power (float or None) – Desired power.

Return type:

PowerResult

Examples

>>> r = power_crossover_be(cv=0.30, power=0.80)
>>> r.n  # total subjects
40

Validates against: R PowerTOST::sampleN.TOST(), PowerTOST::power.TOST()

pystatsbio.power.power_cluster(n_clusters=None, cluster_size=None, d=None, icc=0.05, alpha=0.05, power=None)[source]

Power calculation for cluster randomized trial (two-arm parallel design).

Adjusts individual-level sample size by the design effect: DEFF = 1 + (m - 1) * ICC where m = cluster_size.

Exactly one of n_clusters, d, power must be None.

Parameters:
  • n_clusters (int or None) – Number of clusters per arm.

  • cluster_size (int) – Average number of subjects per cluster. Always required.

  • d (float or None) – Cohen’s d effect size.

  • icc (float) – Intraclass correlation coefficient (default 0.05).

  • alpha (float) – Significance level (default 0.05).

  • power (float or None) – Desired power.

Return type:

PowerResult

Examples

>>> r = power_cluster(cluster_size=20, d=0.5, icc=0.05, alpha=0.05, power=0.80)
>>> r.n  # clusters per arm
8

Validates against: R clusterPower, CRTSize