Let's look at the difference in distribution of p-values for a Fisher's exact test when the marginals are fixed versus when the marginals are not fixed.
The setup: We have an urn with 20 red balls and 20 white balls. We draw two times a group of 20 balls from the urn and test the hypothesis whether the probability of drawing red and white balls is different between the two groups.
We can do these draws in two different ways, with and without replacement and the distribution of p-values from a Fisher test will be different
With the sampling without replacement (figure on the left) the marginals of a contingency table are fixed, the total number of red and white balls is allways 20 for each.
In that case the Fisher's exact test has the property that for every observable p-value we have that the cumulative distribution function is equal to the p-value value $F(p) = p$.
With the sampling with replacement (figure on the right) the number of red and white balls can very. The marginals are not fixed beforehand. And the hypothetical frequency of a p-value is not equal to it's nominal values. Although, due to it's conservative nature we do have that the frequency is guaranteed to be at least equal or lower $F(p) \leq p$.
So, if an experiment doesn't have the marginals pre-determined, then the real frequencies of a p-value does not equal the nominal frequency of a p-values.
Of course, the discrepancy doesn't mean that the Fisher exact test can not be used as an approximate approach. But it isn't always as exact as the name (unintentionally*) suggests, when the marginals are not fixed before the experiment. And also, there can be better tests such as Barnard's test which also has $F(p) \leq p$, but with more power.
set.seed(1)
balls = 20
sim = function() {
## sample two groups from the urn
b = 1:(2*balls)
y = sample(b, balls, replace = FALSE)
z = sample(b[-y], balls, replace = FALSE)
m = matrix(c(sum(y <= balls),
sum(y > balls),
sum(z <= balls),
sum(z > balls))
,2)
return(fisher.test(m)$p.value)
}
n =10^3
p = replicate(n,sim())
p = p[order(p)]
f = c(1:n)/n
plot(p,f ,
xlab = "observed p-value",
ylab = "empirical cumulative density distribution", type = "s", lwd ="2",
main = "without replacement")
lines(c(0,1),c(0,1), lty = 2)
set.seed(1)
balls = 20
sim2 = function() {
## sample two groups from the urn
b = 1:(2*balls)
y = sample(b, balls, replace = TRUE)
z = sample(b, balls, replace = TRUE)
m = matrix(c(sum(y <= balls),
sum(y > balls),
sum(z > balls),
sum(z <= balls))
,2)
return(fisher.test(m)$p.value)
}
n =10^3
p = replicate(n,sim2())
p = p[order(p)]
f = c(1:n)/n
plot(p,f ,
xlab = "observed p-value",
ylab = "empirical cumulative density distribution", type = "s", lwd ="2", main = "with replacement")
lines(c(0,1),c(0,1), lty = 2)
* The test is 'exact' because it depends on an exact distribution instead of an approximation. The test remains exact when the marginals are not fixed, but due to the conditioning on the marginals the nominal value of the p-values is not any more equal to the true cumulative frequency.