spacr.figures.stats

Select a group-comparison test from the data, run it, and report the choice.

The test is selected by fixed rules:

groups variance distribution test 2 equal ~normal Student’s t (two-sided) 2 unequal ~normal Welch’s t 2 any not normal Mann-Whitney U >2 equal ~normal one-way ANOVA >2 unequal ~normal Welch’s ANOVA >2 any not normal Kruskal-Wallis

Two common errors in test selection return a plausible p-value instead of raising an error.

Assumption tests have their own power. With n = 3, Levene’s test has almost no power, so “p = 0.7” means the variances could not be compared, not that they are equal. Using that result to select Student’s t can report a difference that is not there. Below MIN_N_FOR_ASSUMPTIONS this module records both checks as uninformative, treats the data as not normal, and selects a rank test (Mann-Whitney U, Wilcoxon signed-rank when paired, or Kruskal-Wallis for more than two groups). This loses some power when the assumptions hold and avoids false positives when they do not.

Unit of replication. spaCR measures thousands of cells across a handful of wells. Testing across cells when the replicate is the well is pseudoreplication and can return p < 1e-10 on pure noise, because n is inflated about a thousandfold. Every result states what n counted, and compare() takes a unit so a caller can aggregate first.

A p-value alone is not reportable. Every result carries the test by name, n per group, an effect size, and the assumption checks with their own numbers.

This is the only module in spaCR that selects a test. spacr.sp_stats previously selected its own and disagreed with this one on three of five inputs, each time choosing the parametric branch where the checks lacked power. It is now a translation layer onto compare(), check_normality() and check_equal_variance() that keeps its older signatures and result keys. Change the choices here and both entry points move together; tests/test_one_engine_decides_which_test_applies.py fails if they ever come apart again.

Classes

Assumption

Result of one assumption check, including whether it was informative.

Comparison

Result of one statistical test, with the fields needed to report it.

Functions

check_equal_variance(→ Assumption)

Run Levene's test for equal variance, median-centred (Brown-Forsythe).

check_normality(→ Assumption)

Run Shapiro-Wilk per group; report the worst p, Bonferroni-corrected.

compare(→ Comparison)

Select a test from the normality and variance checks, then run it.

stars(→ str)

Return the asterisks for a p-value, or n.s..

table(comparisons, *[, correction])

Return all comparisons as one DataFrame, with p-values corrected across them.

Module Contents

class spacr.figures.stats.Assumption[source]

Result of one assumption check, including whether it was informative.

Parameters:
  • name – name of the assumption test.

  • statistic – test statistic, or nan when it could not be computed.

  • p_value – test p-value, or nan when it could not be computed.

  • informative – whether the check had enough usable data to interpret.

  • verdict – plain-language conclusion, including inconclusive cases.

  • passed – decision made by the check’s own rule; callers must not re-derive it from p_value.

class spacr.figures.stats.Comparison[source]

Result of one statistical test, with the fields needed to report it.

Variables:
  • test – name of the selected statistical test.

  • statistic – statistic returned by that test.

  • p_value – unadjusted p-value returned by that test.

  • groups – group labels in the order tested.

  • n – usable observation counts for those groups, in matching order.

  • unit – independent unit represented by one observation, such as a well, cell, or guide; this prevents reporting row count as replication.

  • effect_size – estimated magnitude of the group difference on the scale named by effect_name.

  • effect_name – statistic used for effect_size, such as Cohen’s d.

  • ci – lower and upper confidence bounds for the reported effect, or None when the selected method cannot provide them.

  • assumptions – diagnostic checks that selected or qualified this test.

  • reason – plain-language explanation of why this test was selected.

  • correction – multiple-testing method applied to obtain p_adjusted.

  • p_adjusted – corrected p-value, or nan when no correction applies.

sentence() → str[source]

Return the legend sentence: test, n, p, effect size and convention.

property marks: str[source]

The significance stars for this comparison.

Computed from the adjusted p-value when one exists, so a figure with many comparisons is not starred on unadjusted values; the raw p-value is used only when no adjustment was made.

Returns:

the stars, or an empty string.

spacr.figures.stats.check_equal_variance(groups: Sequence[numpy.ndarray]) → Assumption[source]

Run Levene’s test for equal variance, median-centred (Brown-Forsythe).

The median-centred Brown-Forsythe form is less sensitive to non-normal data than the mean-centred form. This function is called before the normality verdict is known.

Parameters:

groups – numeric sample array for each group being compared.

spacr.figures.stats.check_normality(groups: Sequence[numpy.ndarray]) → Assumption[source]

Run Shapiro-Wilk per group; report the worst p, Bonferroni-corrected.

Parameters:

groups – numeric sample array for each group being compared.

spacr.figures.stats.compare(groups: Mapping[str, Sequence], *, unit: str = 'observation', paired: bool = False, force: str | None = None) → Comparison[source]

Select a test from the normality and variance checks, then run it.

Parameters:
  • groups – {label: values}. Two or more.

  • unit – what one observation is – ‘well’, ‘cell’, ‘guide’. Stated in the result, because a test across cells when the replicate is the well is pseudoreplication and can return p < 1e-10 on noise.

  • paired – the groups are matched (the same wells before and after).

  • force – a test name to use instead of the chosen one.

Returns:

a Comparison.

Raises:

ValueError – with fewer than two groups, or a group too small to test. An error is raised rather than NaN returned, so a comparison that could not be made is not reported as one with an unknown result.

spacr.figures.stats.stars(p) → str[source]

Return the asterisks for a p-value, or n.s..

Non-significant comparisons are shown as n.s. rather than omitted, as in the published figures; a missing bracket would read as a comparison that was not made. Non-numeric and non-finite values also return n.s..

Parameters:

p – p-value to translate into the reporting convention.

spacr.figures.stats.table(comparisons: Sequence[Comparison], *, correction: str = 'fdr_bh')[source]

Return all comparisons as one DataFrame, with p-values corrected across them.

The correction is applied across the comparisons because, for example, six independent tests at 0.05 have a 26% chance of at least one false positive, which the individual p-values do not show.

Parameters:

comparisons – completed comparison results to tabulate and correct as one family.