Why is my Fisher's test "significant" but odds ratio overlaps 1? Given a contingency table of the following rare event, why does my Fisher's exact test produce a "significant value" (i.e., < 0.05) but also show that the confidence interval for OR overlaps 1? My understanding is that a significant value should indicate an OR of 1 is excluded from the 95% CI. Is the p value one-sided and therefore needs to be interpreted as 2 x p (0.0573)?
        FALSE TRUE
  FALSE  3200    6
  TRUE    885    6

    Fisher's Exact Test for Count Data

data:  table
p-value = 0.02865
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
  0.9636962 13.5569691
sample estimates:
odds ratio 
  3.613991 

 A: This is an interesting phenomenon.
The difference is basically that the null hypothesis is more powerful because it ends up being one-sided. The confidence interval is not based on the same powerful tests (but it could).
Null hypothesis is tested with variable weight in left and right tails
Note that probability for the value in the cell 1,1 (which we call $x$) has the p-value of 0.028 only based on the left tail (the sum of probability for values 3200 and above). There is no right tail in this example, because the value can't get lower than 3194.

Confidence interval assumes a two-sided test with equal tails
The confidence interval is computed based on Fisher's noncentral hypergeometric distribution. The lower interval boundary is based on those values of the odds ratio for which the probability of observing $x \geq 3200$ is 0.025 or less.
This value happens to be below 1. This is not strange because we computed that the probability is 0.028 for the odds 1.

The difference
Thus we can say: The difference is that the computation for the confidence interval is based on hypothesis testing with two tails with equal weight. But this is not the case for the hypothesis test that is used to compute the p-value.
The significance test for the null hypothesis will use the set values $\pm$ a certain distance from the maximum likelihood estimate. This might not need to be two equal tails.
In this example, the maximum likelihood estimate is at 3196. So the p-value is based on the probability that the observed $x \geq 3200$ or $x\leq 3192$. Due to the asymmetry this lower tail does not exist.
However, the computation for the confidence intervals uses a test with equal weight in both tails.
R-code
Below is some r-code that may help to manually compute the confidence intervals and p-values, which may be helpfull for gaining more insight in the fisher.test function. The code is a simplified version of the code that is under the hood of the fisher.test function.
### data
mat <- matrix(c(3200,6,885,6),2, byrow = T)

### parameters describing the data
x <- c(3194:3206)   ### possible values for cell 1,1
m <- 3200+6    ### sum of row 1
n <- 885+6     ### sum of row 2
k <- 3200+885  ### sum of column 1


### fisher test
test <- fisher.test(mat)
test

### manual computation of p-values
f <- dhyper(x,m,n,k)
plot(x,f)
pvalue <- sum(f[x >= 3200])

### compare p-values (gives the same)
pvalue
test$p.value


### non-central hypergemoetric distribution
### copied from fisher.test function in R
### greatly simplified for easier overview
logdc <- dhyper(x, m, n, k, log = TRUE)

### PDF
dnhyper <- function(ncp) {
  d <- logdc + log(ncp) * x
  d <- exp(d - max(d))        
  d / sum(d)
}


### CDF
pnhyper <- function(q, ncp = 1, uppertail = F) {
  if (uppertail) {
    sum(dnhyper(ncp)[x >= q])
  }
  else  {
    sum(dnhyper(ncp)[x <= q])
  }
}
pnhyper <- Vectorize(pnhyper)

### alpha level
alpha <- (1-0.95)/2

### compute upper and lower boundaries
x1 <- uniroot(function(t) pnhyper(3200, t) - alpha,
              c(0.5, 20))$root
x2 <- uniroot(function(t) pnhyper(3200, t, uppertail = T) - alpha,
              c(0.5, 20))$root

### plotting
t <- seq(0.2,20,0.001)
plot(t,pnhyper(3200,t, uppertail = T), log = "x", type = "l", xlim = c(0.20,20), ylab = "P(x => 3200)", xlab = "odds")
lines(c(10^-3,10^3), 0.025*c(1,1), col = 2)
lines(c(x2,x2),c(0,1), lty = 2)

