他们使用了Fisher精确检验,该检验涉及无放回抽样。
但实际上这并不完全如此,它更像是二项式分布式数据。
对于这种情况,您会得到以下信息:
精确计算功率
您可以简单地通过尝试所有可能性来计算在给定特定样本大小和概率的情况下拒绝原假设的概率,并查看哪些导致负/正 Fisher 检验。然后你对概率求和,得到你拒绝测试的情况。
P(reject)=∑over all i,jwhere Fisher test is rejectedP(i placebo cases and j treatment cases)
下面是一个代码示例
fisherpower <- function(p1, p2, n) {
pf <- 0
for (i in 1:n) {
for (j in 1:n) {
M <- matrix(c(i,n-i,j,n-j),2)
if (fisher.test(M)$p.value <= 0.05) {
pf <- pf + dbinom(i,n,p1)*dbinom(j,n,p2)
}
}
}
pf
}
这使
> fisherpower(0.1,0.05,621)
[1] 0.9076656
然而,这种方法消耗了大量的计算能力。你需要尝试 621 次 621 种可能性。上面的实现可以改进很多(您不需要计算所有 621 x 621 的情况),但它仍然很慢,所以这就是 R 中的标准实现使用模拟的原因。上述内容的快速实现在 Peter Calhoun 的 R 包Exact中,他在此处的回答中对此进行了解释。
模拟计算
您多次计算假设结果,并针对该结果确定 5% 假设检验是否会失败。
作为您获得的样本量的函数:
- 如果原假设为真,那么您将始终获得 5% 的拒绝概率。
实际上,这并不完全正确,并且当条件不正确时,Fisher 精确检验略微保守。即使原假设为真(在我们不带放回抽样的情况下),Fisher 精确检验的拒绝率也低于 5%。在下面的示例图中,我们计算时的拒绝概率(在这种情况下,null 为真)。p1=p2=0.1
- 如果原假设为假,并且概率不相等。然后,当样本量较大时,您会获得更大的概率来拒绝原假设。

### computing
set.seed(1)
n <- seq(100,1000,20)
power <- sapply(n,
FUN = function(xn) {
statmod::power.fisher.test(0.1,0.05,xn,xn, nsim = 10000)
} )
type1 <- sapply(n,
FUN = function(xn) {
statmod::power.fisher.test(0.1,0.1,xn,xn, nsim = 10000)
} )
### plotting of results
plot(n,power, type = "l", ylim = c(0,1),
ylab = "reject probability")
lines(n,type1, col =2)
points(n,power, pch = 21, col = 1, bg = "white", cex = 0.7)
points(n,type1, pch = 21, col = 2, bg = "white", cex = 0.7)
# lines at 0.05 and 0.9
lines(c(0,2000),c(0.05,0.05), col = 2, lty = 2)
lines(c(0,2000),c(0.9,0.9), col = 1, lty = 2)
# legend
legend(1000,0.6,c("if p1 = p2 = 0.1",
"if p1 = 0.1, p2 = 0.05"), title = "reject probability",
col = c(2,1), lty = 1, cex = 0.7, xjust = 1
)
替代测试
还有很多其他的方式来看待它。我们还可以进行 Barnards 测试
> Barnard::barnard.test(49,58,414-49,407-58)
Barnard's Unconditional Test
Treatment I Treatment II
Outcome I 49 58
Outcome II 365 349
Null hypothesis: Treatments have no effect on the outcomes
Score statistic = 1.02759
Nuisance parameter = 0.012 (One sided), 0.986 (Two sided)
P-value = 0.16485 (One sided), 0.320387 (Two sided)
或使用 GLM 模型
> summary(glm(cbind(c(49,58),c(414-49, 407-58)) ~ 1+c("chloroquine", "placebo"), family = binomial(link="identity")))
Call:
glm(formula = cbind(c(49, 58), c(414 - 49, 407 - 58)) ~ 1 + c("chloroquine",
"placebo"), family = binomial(link = "identity"))
Deviance Residuals:
[1] 0 0
Coefficients:
Estimate Std. Error
(Intercept) 0.11836 0.01588
c("chloroquine", "placebo")placebo 0.02415 0.02350
z value Pr(>|z|)
(Intercept) 7.455 8.98e-14 ***
c("chloroquine", "placebo")placebo 1.028 0.304
---
Signif. codes:
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 1.0568e+00 on 1 degrees of freedom
Residual deviance: 2.4780e-13 on 0 degrees of freedom
AIC: 15.355
Number of Fisher Scoring iterations: 2
>
这些方法中的每一种都或多或少地显示相同的东西,结果 58 vs 49 不是异常(而且,效果需要达到 50% 或更多才能使我们有至少 90% 的概率检测到异常用这个测试)。