I want to perform a Pearson's $\chi^2$ test to analyse contingency tables; but because I have small numbers, it is recommended to perform instead what is called a Fisher's Exact Test.
This requires generating all integer matrices with the same column and row totals as the one given, and compute and sum all p-values from the corresponding distribution which are lower than the one from the data.
See Wikipedia and MathWorld for relevant context.
Apparently R offers that, but couldn't find it in Mathematica, and after extensive research couldn't find an implementation around, so I did my own.
The examples in the links are with 2x2 matrices, but I did a n x m implementation and, at least for the MathWorld example, numbers match.
I have one question: The code I wrote uses Reduce
; although it seemed to me generating all matrices was more a combinatorial problem. I pondered using FrobeniusSolve
, but still seemed far from what's needed. Am I missing something or is Reduce
the way to go?
The essential part of the code, which I made available in github here, is that for a matrix like
$$ \left( \begin{array}{ccc} 1 & 0 & 2 \\ 0 & 1 & 2 \\ \end{array} \right)$$
with row sums 3, 3 and column sums 1, 1, 4, it creates a system of linear equations like:
$$ \begin{array}{c} x_{1,1}+x_{1,2}+x_{1,3}=3 \\ x_{2,1}+x_{2,2}+x_{2,3}=3 \\ \end{array} $$ $$ \begin{array}{c} x_{1,1}+x_{2,1}=1 \\ x_{1,2}+x_{2,2}=1 \\ x_{1,3}+x_{2,3}=4 \\ \end{array} $$
subject to the constrains $ x_{1,1}\geq 0$, $x_{1,2}\geq 0$, $x_{1,3}\geq 0$, $x_{2,1}\geq 0$, $x_{2,2}\geq 0$, $ x_{2,3}\geq 0 $ and feeds this into Reduce
to solve this system over the Integers
. Reduce
returns all the solutions, which is what we need to compute Fisher's exact p-value.
Note: I just found this advice on how to use github better for Mathematica projects. For the time being, I leave it as-is. Hope easy to use and test.
You can test the above mentioned code like
FisherExact[{{1, 0, 2}, {0, 0, 2}, {2, 1, 0}, {0, 2, 1}}]
It has some debugging via Print
which shows all the generated matrices and their p-value. The last part (use of Select
) to process all found matrices didn't seem very Mathematica to me, but it was late and I was tired - feedback is welcome.
I would give my tick to the answer with more votes after a couple of days if anyone bothers to write me two lines :)
Thanks in advance!