I am stuck with the same problem. I searched and searched in stackExchange and Google, and I did not find anything explicitly explaining how the odds ratio in fisher.test()
is calculated. This is not a complete answer, but it provides something useful to the discussion.
One thing is clear, fisher.test()
calculates a completely different odds ratio with a different (and more complicated) method.
If you write fisher.test
in R Console and press Enter, the output will be the complete code of the function fisher.test()
. The interesting part concerning our doubt is:
m <- sum(x[, 1L])
n <- sum(x[, 2L])
k <- sum(x[1L, ])
x <- x[1L, 1L]
lo <- max(0L, k - n)
hi <- min(k, m)
support <- lo:hi #Interval of definition of Hypergeometric Distribution
logdc <- dhyper(support, m, n, k, log = TRUE) #log of Hypergeometric Probability Function
dnhyper <- function(ncp) {
d <- logdc + log(ncp) * support
d <- exp(d - max(d))
d/sum(d)
}
mnhyper <- function(ncp) {
if (ncp == 0)
return(lo)
if (ncp == Inf)
return(hi)
sum(support * dnhyper(ncp))
}
mle <- function(x) {
if (x == lo)
return(0)
if (x == hi)
return(Inf)
mu <- mnhyper(1)
if (mu > x)
uniroot(function(t) mnhyper(t) - x, c(0, 1))$root
else if (mu < x)
1/uniroot(function(t) mnhyper(1/t) - x, c(.Machine$double.eps,
1))$root
else 1
}
Well, if you
- Define
x = matrix(c(3, 6, 5, 6), nrow=2)
- Run every line of the code extracted from
fisher.test
in order
- Run
mle(x)
You get 0.6155891
. So this is how the odds ratio in fisher.test
is calculated. However, I do not understand the algorithm. I have not found any article explaining it, and it does not seems possible to translate it to a "simple" mathematical formula.