我在R测试中发现了这个问题,但是我认为这个问题通常适用于其他测试。如果我这样做:
a <- 1:10
b <- 100:110
t.test(a,b)
我得到:t = -64.6472, df = 18.998, p-value < 2.2e-16
。我从评论中知道2.2e-16
是.Machine$double.eps
的值 - 最小的浮点数,使1 + x != 1
,但当然R可以表示比这小得多的数字。我也从R FAQ中知道R必须将浮点数舍入到53位二进制数字精度:R FAQ。
一些问题:(1)我是否正确地读到精度的53个二进制数字或R < .Machine$double.eps
中的值未准确计算? (2)为什么在进行这样的计算时,R不提供显示p值较小值的方法,即使精度有所损失? (3)有没有办法显示较小的p值,即使我失去了一些精度?对于单个测试,2个十进制有效数字将是正常的,对于我将要更加正确的Bonferroni值,我需要更多。当我说“失去一些精确度”时,我认为&lt; 53个二进制数字,但是(4)我完全错了,任何p值< .Machine$double.eps
都非常不准确? (5)R只是诚实而其他统计数据包不是吗?
在我的领域中,非常小的p值是常态,一些例子:http://www.ncbi.nlm.nih.gov/pubmed/20154341,http://www.plosgenetics.org/article/info%3Adoi%2F10.1371%2Fjournal.pgen.1002215这就是我想要表示如此小的p值的原因。
感谢您的帮助,对于这样一个曲折的问题感到抱歉。
答案 0 :(得分:20)
我在这里交换答案和评论的几件事情让我感到困惑。
首先,当我尝试OP的原始示例时,我没有得到 p 这么小的值(这里有几个不同的2.13.x版本和R-devel) ):
a <- 1:10
b <- 10:20
t.test(a,b)
## data: a and b
## t = -6.862, df = 18.998, p-value = 1.513e-06
其次,当我将组之间的区别大得多时,我确实得到了@eWizardII建议的结果:
a <- 1:10
b <- 110:120
(t1 <- t.test(a,b))
# data: a and b
# t = -79.0935, df = 18.998, p-value < 2.2e-16
#
> t1$p.value
[1] 2.138461e-25
t.test
中打印输出的行为是由其对stats:::print.htest
的调用驱动的(如OP所述,其他统计测试函数也会调用chisq.test
)反过来调用format.pval
,其{em> p 值小于其值eps
(默认为.Machine$double.eps
)为< eps
。我很惊讶地发现自己不同意这些普遍敏锐的评论者......
最后,虽然担心非常小的 p 值的确切值似乎很愚蠢,但OP是正确的,这些值通常被用作生物信息学文献中证据强度的指标 - - 例如,人们可能会测试100,000个候选基因,并查看结果 p 值的分布(搜索“火山图”这一过程的一个例子)。
答案 1 :(得分:13)
两个问题:
1)统计意义在1e-16和1e-32的p值之间可能存在哪些差异?如果你真的可以证明它的合理性,那么使用记录的值是可行的方法。
2)当你对R?
的数值准确性感兴趣时,为什么要使用维基百科?R-FAQ说“其他[意思是非整数]数字必须四舍五入到(通常)53位二进制数字精度。” 16位数字是有限的。这是在控制台上获得精确度限制的方法:
> .Machine$double.eps
[1] 2.220446e-16
当在[0,1]
的范围内进行解释时,该数字实际上为零答案 2 :(得分:9)
您链接的维基百科页面是R不使用的Decimal64类型 - 它使用标准问题双打。
首先,.Machine
帮助页面中的一些定义。
double.eps:最小的正浮点数'x' '1 + x!= 1'。 ......通常是'2.220446e-16'。
double.xmin:最小的非零标准化浮点数 ......通常是'2.225074e-308'。
因此,您可以表示小于2.2e-16的数字,但它们的准确性会变暗,并且会导致计算出现问题。尝试一些数字接近最小可表示值的例子。
2e-350 - 1e-350
sqrt(1e-350)
您在评论中提到您想要进行bonferroni更正。我建议您使用p.adjust(your_p_value, method = "bonferroni")
而不是为此编制自己的代码。 pairwise.t.test
使用此功能。
答案 3 :(得分:7)
尝试这样的事情t.test(a,b)$p.value
看看它是否能为您提供所需的准确性。我认为它与结果的打印有关,而不是实际存储的计算机值,它应具有必要的精度。
答案 4 :(得分:4)
一些R包解决了这个问题。最好的方法是通过包pspearman。
source("http://www.bioconductor.org/biocLite.R")
biocLite("pspearman")
library("pspearman")
a=c(1:110,110)
b=1:111
out <- spearman.test(a, b, alternative = "greater", approximation="t-distribution")
out$p.value
[1] 3.819961e-294
答案 5 :(得分:2)
最近有同样的问题。统计员建议:
A <- cor.test(…)
p <- 2* pt(A$statistic, df = A$parameter, lower.tail=FALSE)