Значение p из fisher.test () не соответствует phyper () - PullRequest
0 голосов
/ 29 октября 2018

Точный критерий Фишера связан с гипергеометрическим распределением, и я ожидаю, что эти две команды будут возвращать одинаковые значения. Может кто-нибудь объяснить, что я делаю неправильно, что они не совпадают?

#data (variable names chosen to match dhyper() argument names)
x = 14
m = 20
n = 41047
k = 40

#Fisher test, alternative = 'greater'
(fisher.test(matrix(c(x, m-x, k-x, n-(k-x)),2,2), alternative='greater'))$p.value 
#returns 2.01804e-39

#geometric distribution, lower.tail = F, i.e. P[X > x]
phyper(x, m, n, k, lower.tail = F, log.p = F)
#returns 5.115862e-43

1 Ответ

0 голосов
/ 29 октября 2018

В этом случае фактический вызов phyper, который имеет отношение к номеру phyper(x - 1, m, n, k, lower.tail = FALSE). Посмотрите на исходный код fisher.test, соответствующий вашему звонку fisher.test(matrix(c(x, m-x, k-x, n-(k-x)),2,2), alternative='greater'). В строке 138 PVAL устанавливается на:

switch(alternative, less = pnhyper(x, or), 
    greater = pnhyper(x, or, upper.tail = TRUE), 
    two.sided = {
      if (or == 0) as.numeric(x == lo) else if (or == 
        Inf) as.numeric(x == hi) else {
        relErr <- 1 + 10^(-7)
        d <- dnhyper(or)
        sum(d[d <= d[x - lo + 1] * relErr])
      }
    })

Поскольку alternative = 'greater', PVAL имеет значение pnhyper(x, or, upper.tail = TRUE). Вы можете видеть pnhyper, определенный в строке 122. Здесь or = 1, который передается в ncp, поэтому вызов phyper(x - 1, m, n, k, lower.tail = FALSE)

С вашими значениями:

x = 14
m = 20
n = 41047
k = 40
phyper(x - 1, m, n, k, lower.tail = FALSE)
# [1] 2.01804e-39
...