Skip to main content

WADE — Wasserstein Area Differential Expression

A two-group differential-expression test for RNA-seq counts that answers two questions instead of one:

  1. Is there a difference? — the ordinary question, which any DE method answers.
  2. What kind of difference is it? — a shift affecting every sample, or a pronounced change confined to a small subset of one group.

The second question is the point. A gene altered in 5% of cases and a gene shifted 2× in all of them can produce the same mean difference, and a first-moment test cannot tell them apart. WADE separates them, and never asks you to declare in advance which you are looking for: there is no percentile cutoff, no window width, no tuning parameter describing the shape of the effect.

For each gene it compares the two groups' whole quantile functions. Stage 1 tests the mean shift; stage 2 tests whether a global fold change is an adequate explanation, against a null built by binomial thinning of the raw counts; three threshold-free descriptors then say how much of the group differs, which way, and by how many folds. Inference is by label permutation with a tail refinement and BH-FDR. docs/method.md is the full account.

Scope: raw counts. WADE takes raw counts, not TPM or CPM, and is for discrete count data: the tie-breaking jitter and the thinning null both need counts.

Install

pip install wade-rnaseq              # NumPy only; compiled kernel included
pip install 'wade-rnaseq[all]'       # + polars (results out), plotly and matplotlib (figures), SciPy (saddlepoint)

The distribution is wade-rnaseq (the name wade on PyPI belongs to an unrelated project); the import name is wade. Wheels cover Linux (x86-64, ARM64), macOS (Apple silicon, Intel) and Windows (x64) for Python 3.10+. On any other platform pip builds from source, which needs a Rust toolchain (rustup); WADE still runs without the compiled kernel, about 80× slower on the subset test. To build from a clone see CONTRIBUTING.md.

Not on PyPI yet. Until the first upload: pip install git+https://github.com/mkiyer/wade (needs Rust).

Use it

import polars as pl, wade

counts  = pl.read_csv("counts.tsv", separator="\t")   # gene id + one column per sample, RAW counts
samples = pl.read_csv("samples.tsv", separator="\t")  # sample_id, condition, ...

cond = wade.condition(samples, key="sample_id", column="condition",
                      case="tumor", control="normal")

res = wade.wade(counts, normalizer=1.0, cond=cond, nperms=2000, seed=1)
wade.write_results(res, "results.tsv")               # + results.manifest.json

counts may be a NumPy array, a polars or pandas DataFrame, a sparse matrix, or a wade.Counts; WADE reads no files. normalizer is a per-gene vector (gene length gives TPM-like values), a matrix, a scalar (1.0 gives CPM), or the name of a column carried alongside the counts. The alignment of samples to the condition is strict and names the offenders.

column question it answers
p_mean_shift, padj_mean_shift stage 1: is average expression different?
p_subset, padj_subset stage 2: is a global shift an inadequate explanation?
affected_fraction what fraction of samples differ? 1.0 = all of them
direction +1 all up, -1 all down, 0 two-sided
subset_log2_fc by how many folds does that fraction differ?
log2_fc, mean_shift the global fold change and the signed quantile area
z_mean_shift, z_subset permutation z-scores, for ranking once p-values hit the floor

Four patterns, read off the two p-values:

p_mean_shift p_subset what you are looking at
significant a global shift; an ordinary DE method finds this too
significant significant a subset, strong enough to move the mean
significant a distributional change with no net mean shift: a balanced subset, or a variance change
not differential

There is deliberately no categorical label: turning continuous statistics into classes needs thresholds, which is what this design exists to avoid.

from wade import plot_gene, plot_volcano, plot_stages, plot_drivers   # needs wade-rnaseq[plot]

plot_gene(res, gene="MYC")                     # what does this gene's difference look like?
plot_volcano(res, stage="both", label=8)       # which genes?
plot_stages(res)                               # what kind of difference?
plot_drivers(res, "MYC", counts)               # should I believe this one?

plot_gene: a global 2× gene, a 15% subset at 8×, and a 5% subset at 8×

The first two genes have the same log₂ fold change. The mean-shift test cannot tell them apart; the curve, p_subset and affected_fraction (0.98 against 0.15) can. A flat curve is a global fold change; a curve that sits at zero and then climbs is a subset.

Before you run it

Two things are arithmetic on your design, and no amount of data or permutations moves them (docs/method.md §10).

  • Resolution. The grid has min(n_case, n_ctrl) points. affected_fraction is quantitative above roughly 100 per group and only qualitative below 50.
  • Detectability. If k samples carry a signal, no permutation test can resolve much below C(n1, k) / C(n1 + n0, k). It is driven by imbalance: balancing the groups helps far more than adding cases. wade.detectability_floor(n_case, n_ctrl, k) computes it.

And one honest caveat: stage 2's p-values are conservative by a measured 4–80× where they are safe, and can be anti-conservative in another regime. Ranking survives; calling with an FDR loses real subset genes. Stage 1 has an exact alternative (stage1="saddlepoint"); stage 2 is the open problem (docs/pvalue-review.md, ISSUES.md).

Documentation

  • docs/manual.mdstart here: install, run, read the output, the options that matter, what to check before trusting a result.
  • docs/method.md — what WADE computes and why, with every measurement, and what it cannot do.
  • docs/pvalue-review.md — the p-value estimators and the open problem, written for a statistician.
  • notebooks/demo.qmd — the demo on synthetic data with planted ground truth, the source of the figures above; notebooks/benchmark.qmd — head to head against COPA, OS, ORT, MOST, LSOSS, the t-test, Wilcoxon and waddR.
  • CONTRIBUTING.md and ISSUES.md — for developers.

Status

The statistic, both stages, the descriptors with bootstrap intervals, permutation inference with tail refinement and BH, Rust kernels for both permutation loops (bitwise against the NumPy path), the figures, and the data-in / results-out boundary are implemented and tested: 854 tests in about 20 s. At 20,000 genes, 100 v 100 and 2,000 permutations a full run takes about 17 s on a 16-core laptop; a 30,000-gene × 80,000-sample cohort completes in 30 minutes at a 56 GB peak. Every fixture value is re-derived from NumPy, SciPy and the closed forms by a test that is forbidden from importing WADE.

Provenance and license

Extracted from the MCTP cfRNA analysis codebase, where it began as a set of functions called HITLIB. No patient-derived data is included. GPL-3; see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wade_rnaseq-0.1.0.tar.gz (2.4 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

wade_rnaseq-0.1.0-cp310-abi3-win_amd64.whl (344.2 kB view details)

Uploaded CPython 3.10+Windows x86-64

wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (466.6 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (456.6 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

wade_rnaseq-0.1.0-cp310-abi3-macosx_11_0_arm64.whl (424.5 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

wade_rnaseq-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl (439.3 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file wade_rnaseq-0.1.0.tar.gz.

File metadata

  • Download URL: wade_rnaseq-0.1.0.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wade_rnaseq-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3c3015420605d44542755e462a2d9c46f092697cbce5bcdc3a00d74d1a361903
MD5 1685da5afe162c31d276a51a6a9166a2
BLAKE2b-256 456e40dd386ad9d29e4965abe26c657cfdf071eccfb5fae0ccd7160f81c2949d

See more details on using hashes here.

Provenance

The following attestation bundles were made for wade_rnaseq-0.1.0.tar.gz:

Publisher: ci.yml on mkiyer/wade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wade_rnaseq-0.1.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: wade_rnaseq-0.1.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 344.2 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wade_rnaseq-0.1.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c0c2bce2bea55715f38fb51ed17848b52244c2810f5188b0569edbcf622f4438
MD5 342ec4278517f0ddb005595da9b48bf5
BLAKE2b-256 6722444660a77c5b7181771b019375ba2b6e8d60fad65ff087a4ba246a60dc1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for wade_rnaseq-0.1.0-cp310-abi3-win_amd64.whl:

Publisher: ci.yml on mkiyer/wade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a58cb4da29b9936b2c68f3116821f9faf2dc502022aad78fb6459e373e759b6c
MD5 1d289fc75f3e909926b229c8d3cc4e0b
BLAKE2b-256 278581e833df406317783ecf7d4b1ae4b8309a28b8eb20155af73befee08f051

See more details on using hashes here.

Provenance

The following attestation bundles were made for wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on mkiyer/wade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6e5de21bb21b0dde86f9268a54bdf81486f5f1268364071fc874bd943e85f2d9
MD5 bd2909dfa1a4dfe20cfd8928daf20d2d
BLAKE2b-256 340b5dde78289238b56b8b56a37b103853092a013f2c5351b4ddef654f74f425

See more details on using hashes here.

Provenance

The following attestation bundles were made for wade_rnaseq-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: ci.yml on mkiyer/wade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wade_rnaseq-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for wade_rnaseq-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f5eea92a1ecbf6a052f6cfbac990048068d95227e92bf22f5178dec34612fed3
MD5 6b5d1ed5cc551aee8a2e1847b8563beb
BLAKE2b-256 209d0e134ada08be2831a3ef10b3b2642eb88b797c2e8657d28bfa1ae32e1a73

See more details on using hashes here.

Provenance

The following attestation bundles were made for wade_rnaseq-0.1.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: ci.yml on mkiyer/wade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wade_rnaseq-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for wade_rnaseq-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fac771ac43a1f559de73e372312c41b0260f0b07a31cd49106972c0117304ca8
MD5 a076911291285ad18c04e56b8580ceb4
BLAKE2b-256 06219bcf6b96132ff0f7b07ab61019f5d2228d3043cc7790f8577cbd2ec4e6bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for wade_rnaseq-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: ci.yml on mkiyer/wade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

6 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page