I can't seem to find a way to achieve a test in R with all of these points:

  1. Fisher's exact
  2. One-sided (greater than, at 90% confidence level)
  3. With mid-p correction

What I have found are combinations of two of those characteristics, but not all three. Here are a few examples that have fallen short:

    #Example data
dat<- rbind("exposed"=c(5,3),"unexposed"=c(20,30))
colnames(dat)<- c("case", "control")

    #Fisher's exact, one-sided.  No option for mid-p correction, & gives different ORs:
results.F <- fisher.test (dat, alternative="two.sided", conf.level=.9)

    #Mid-p exact, two-sided.  No option for one-sided:
results.EpiM <- epitab (dat, method="oddsratio", conf.level=.8, oddsratio="midp")

    #Mid-p exact, two-sided.  No option for one-sided.  Same results as above:
results.OrM <- oddsratio.midp (dat, conf.level=.8)

I know that OpenEpi online (not an R package) can calculate what I want. But, since I'm running this through many loops (same test on different geographic areas), I need to be able to output the p-value, odds ratio (OR), and lower confidence limit (LCL) for each loop in R.

Through experimentation, I've confirmed that the p value is impacted by both the sidedness and the mid-p/lack thereof specifications. I've also confirmed that the ORs and LCLs are not impacted by sidedness (UCLs are), but are impacted by mid-p/lack thereof. This makes sense and I can explain if that would be helpful. I therefore need all three characteristics to be in place in the same test to get the correct p value (for a while I thought there may be a way to get the OR & LCL from one test, but the p value from another, but it cannot be).

Does anyone know code that would implement this in R?


  • $\begingroup$ In the one tailed 2x2 case aren't you just dealing with one tail of a hypergeometric? $\endgroup$
    – Glen_b
    Mar 26, 2015 at 5:03

2 Answers 2


Without a reproducible example, it is difficult to be certain but I believe you are looking for ormidp.test from the epitools package. As per the help page description it states that it is a 'Test for independence using the mid-p method'.

Finding a quick example to verify at this link, I use the following table and code.

   Dead Alive
A   41  216
B   64  180

> ormidp.test(41,64,216,180)
    one.sided   two.sided
1 0.002447276 0.004894553

Which is consistent with the results shown at the above link.

  • $\begingroup$ Excellent, it does match and that does make sense. However, this is a test that assumes that the one-sided p is half of the two-sided p; it assumes symmetry and doesn't check for actual greater than or less than boundaries. I might have to settle for this. Also for the record, I realized that if a test is mid-p, then by definition it must be exact. Therefore, in my list of 1-3, if #3 is true then #1 is also automatically true. $\endgroup$
    – Alex G.
    Dec 9, 2014 at 15:09
  • $\begingroup$ Update: I'm still looking for a test that actually calculates the one-sided boundary, rather than halving the two-sided p value. Comparing fisher.test p values from the example above, two-sided is 0.272 but one-sided greater-than is 0.209. This means it's not symmetrical (.209 in upper tail and .063 in lower tail). So, I'm using the uncorrected one-sided fisher.test until I can find a mid-p corrected one-sided method. $\endgroup$
    – Alex G.
    Dec 11, 2014 at 14:11

I don't know an R package that will do exactly what you want and call itself a Fisher test, but if you just think of Fisher's test in terms of the hypergeometric distribution, you can very easily calculate any variant of Fisher's test you care to with any old implementation of the hypergeometric distribution you can find. Comparing the probability formulas on the two linked Wikipedia pages, you see that, for a given 2X2 table, you want a hypergeometric distribution with (in the Wikipedia page notation):

  • $N$ equal to total counts (58 in your example)
  • $K$ equal to first row counts (8 in your example)
  • $n$ equal to first column counts (25 in your example)
  • $k$ equal to first cell counts (5 in your example)

The traditional one-sided probability is $P(k' \le k)$ or $P(k' \ge k)$. The mid-point corrected probability is $P(k' < k) + \frac{1}{2}P(k)$ or its right-sided analog.

In your example data, $\bar{k} = 3.45$, and since 5 is larger than this, you presumably want a right-sided test. So $P = \frac{1}{2}P(5) + P(k > 5) = \frac{1}{2}(0.1512) + (0.0576) = 0.1332$.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.