fexact
fexact is Fisher's exact test for r x c contingency tables: a port of R's network algorithm (ACM 643), with a Monte Carlo variant
Install
pip install fexact
Wheels are built for Linux, macOS and Windows (Python >= 3.9). Building from source needs a Rust toolchain.
Usage
import numpy as np
from fexact import fexact, fexact_many, fexact_simulate
contingency = np.array([[5, 1, 5], [1, 1, 5]], dtype=np.int64)
fexact(contingency) # 0.40045...
fexact(contingency, workspace=10**7, hybrid=True) # Cochran-condition hybrid approximation
# Many tables in parallel (the GIL is released; threads=None uses all cores).
fexact_many([t1, t2, t3], workspace=10**6, threads=None) # -> [p1, p2, p3]
# Monte Carlo p-value from random tables with the same margins, in parallel.
# Reproducible for a given seed, whatever the number of threads.
fexact_simulate(contingency, samples=100_000, seed=1, threads=None)
fexact_simulate works like R's fisher.test(simulate.p.value = TRUE): it
returns (1 + hits) / (samples + 1), where hits are the random tables at most
as probable as the observed one. It has no workspace limit, so it also handles
tables too large for the exact test, including counts beyond 2^31 (about 0.2 s
per million samples for a 10x10 table with n = 5000 on 32 threads).
Tables must be two-dimensional np.int64 arrays. fexact raises ValueError on
invalid input or when workspace is too small; fexact_many raises
ValueError("table i: ...") for the first table that fails.
Implementation
fexact is written in Rust (src/): a port of R's fexact.c (ACM TOMS 643,
Mehta & Patel's network algorithm) that returns bit-identical p-values and the
same errors as the original C extension, about twice as fast, except where the
C code's 32-bit integers overflow. There the C extension either fails (error
501) or, on wide tables such as 2 x 21 and above, silently returns wrong
p-values; this version uses 64-bit node keys and path counts and gets them
right (checked against R's and its own Monte Carlo simulation). src/lib.rs maps
each module to the C routine it ports. The C code is kept in legacy/ as the
reference.
It can also be used as a Rust library:
use fexact::{fisher_exact, fisher_exact_many, Hybrid, Options, Table};
let counts = [5, 1, 5,
1, 1, 5];
let table = Table::from_row_major(&counts, 2, 3);
let exact = fisher_exact(&table, &Options::default())?.p_value;
let hybrid = fisher_exact(&table, &Options { hybrid: Some(Hybrid::COCHRAN), ..Options::default() })?;
fexact::fisher_simulated(&table, &Simulation { samples, seed, threads })
is the Monte Carlo test. fexact::compat::fexact keeps the C signature (column-major table with leading
dimension, expect/percnt/emin, workspace, mult).
Development
cargo test # unit tests + tests/golden.rs
pip install maturin pytest
maturin develop --release # or: pip install .
pytest
tests/golden.rsreplays ~15k cases recorded from the C extension (tests/data/golden.txt) and requires exact agreement.tests/test_parity.pycompares random tables against the C extension. It is skipped unless the C reference has been built withpython legacy/setup.py build_ext --inplace, which is also whattests/gen_golden.pyneeds to regenerate the corpus.
Contributing
See CONTRIBUTING.md. Changes are listed in CHANGELOG.md.
📈 Releases
You can see the list of available releases on the GitHub Releases page.
We follow Semantic Versions specification.
We use Release Drafter. As pull requests are merged, a draft release is kept up-to-date listing the changes, ready to publish when you’re ready. With the categories option, you can categorize pull requests in release notes using labels.
For Pull Request this labels are configured, by default:
| Label | Title in Releases |
|---|---|
enhancement, feature |
🚀 Features |
bug, refactoring, bugfix, fix |
🔧 Fixes & Refactoring |
build, ci, testing |
📦 Build System & CI/CD |
breaking |
💥 Breaking Changes |
documentation |
📝 Documentation |
dependencies |
⬆️ Dependencies updates |
You can update it in release-drafter.yml.
GitHub creates the bug, enhancement, and documentation labels for you. Dependabot creates the dependencies label. Create the remaining labels on the Issues tab of your GitHub repository, when you need them.
To release:
- Bump the version with
bump2version patch|minor|major(updatesCargo.tomlandCargo.lock, commits and tags), and push with--follow-tags. - Publish a pre-release on GitHub to upload to Test PyPI, then a release to upload to PyPI. Both build wheels for Linux, macOS and Windows plus an sdist.
🛡 License
This project is licensed under the terms of the GNU GPL v3.0 license (GPL-3.0-only). See LICENSE.txt for more details.
📃 Citation
@misc{fexact,
author = {boussoffara},
title = {`fexact` is a port of R's Fisher test for nxm contingency tables (acm 643 algorithm) },
year = {2021},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/boussoffara/fexact}}
}
Credits
The algorithm is Mehta & Patel's network algorithm (ACM TOMS 643) as found in R's fexact.c. The project was started from python-package-template.
Metadata
Release files for fexact 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| fexact-0.2.0.tar.gz | 53.1 kB | Without provenance | Details for fexact-0.2.0.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| fexact-0.2.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details for fexact-0.2.0-cp39-abi3-win_amd64.whl |
| fexact-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details for fexact-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| fexact-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details for fexact-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
| fexact-0.2.0-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details for fexact-0.2.0-cp39-abi3-macosx_11_0_arm64.whl |
| fexact-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details for fexact-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl |
Total release size: 1.4 MB
Release files / fexact-0.2.0.tar.gz
| Download URL | fexact-0.2.0.tar.gz |
|---|---|
| Size | 53.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e2b0367a36573eacc3e69f94a45cdf587621edd4c945bb75c22de4027b0bae61
|
|
BLAKE2b-256 checksum How to use checksums |
467e945d133e7aac4ca7152094e44687ae0405c30cb0b78029ab74a3551bd1fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fexact-0.2.0-cp39-abi3-win_amd64.whl
| Download URL | fexact-0.2.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 185.8 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
a173e568171316ad8e328aade24bf08f9df4ac188ba01e001df15b0e04992918
|
|
BLAKE2b-256 checksum How to use checksums |
281ae1aa85f48254ce126ac0d11a1bde3cb2ae61a4decff6da5815d194c553df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fexact-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | fexact-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 304.8 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bb087cc34722925e2649a46d48a8dcab3feeaa370c6334ddfb7a51d7fb5a1e5d
|
|
BLAKE2b-256 checksum How to use checksums |
11862f4b4f03f4df621875932d7ba12663b07a815704124036acd5e16ff3c9b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fexact-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | fexact-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 305.3 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
c5676935acddd824c92cfcee667141a0719f32df6b6b964d508709295c8d6a0a
|
|
BLAKE2b-256 checksum How to use checksums |
70d6b4a25bf783cabeb870ecdc20834246f2413fece923cd84b79c7f7ba6a849
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fexact-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | fexact-0.2.0-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 274.4 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e31c5eea01d3575d768b83edb12ccbf88fbf3072ce65a45974819b6a3e250283
|
|
BLAKE2b-256 checksum How to use checksums |
0f84c9070dcb4f7881952ba9f689ffc896f524dcff12dc5d4671ed238ac56d2e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fexact-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | fexact-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 279.9 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
b3ebd68c1f150b1febf3cc47d308e93309120ff10cf383078b5bc384e5de2103
|
|
BLAKE2b-256 checksum How to use checksums |
076f261d425b6be0a638075b9d21c48a6afdb8728a00c367e01804b6f4a94d70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for fexact 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.