如何处理R中的p值?
我期待非常低的p值,如:
1.00E-80
我需要-log10
-log10(1.00E-80)
-log10(0)是Inf,但也是在四舍五入的意义上。
但似乎在1.00E-308之后,R收益率为0.
1/10^308
[1] 1e-308
1/10^309
[1] 0
p值显示与lm
功能的准确度是否与截止点1e-308相同,或者它的设计使我们需要一个截止点,我需要考虑一个不同的截止点 - 例如1e-100(例如)用< 1e-100替换0。
答案 0 :(得分:8)
有各种可能的答案 - 哪一个最有用取决于具体情况:
.Machine$double.xmin
更接近零的浮点值,1e-308
因平台而异,但通常(如您所发现的)dnorm(-100,log=TRUE)
的顺序。如果你真的需要使用这么小的数字并且找不到直接在日志规模上工作的方法,你需要搜索Stack Overflow或者R wiki来寻找处理任意/扩展精度值的方法(但你可能应该这样做)尝试在日志范围内工作 - 这将不那么麻烦了)log10
给出-5000.919。您可以直接转换为log10比例(不取幂,然后使用log(10)
)除以dnorm(-100,log=TRUE)/log(10)
:p***
= - 2171,这将太小而无法浮点表示。对于log.p=TRUE
(累积分布函数)函数,请使用log=TRUE
而不是<2.2e-16
。 (这个特定点在很大程度上取决于您的特定上下文。即使您没有使用内置R函数,您也可以找到一种在日志范围内提取结果的方法。)(t1 <- t.test(rnorm(10,100),rnorm(10,80)))
:....
t = 56.2902, df = 17.904, p-value < 2.2e-16
打印
> t1$p.value
[1] 1.856174e-18
但您仍然可以从结果中提取精确的p值
format.pval()
(在许多情况下,此行为由lm
函数控制)
说明所有这些如何适用于d <- data.frame(x=rep(1:5,each=10))
set.seed(101)
d$y <- rnorm(50,mean=d$x,sd=0.0001)
lm1 <- lm(y~x,data=d)
:
summary(lm1)
<2.2e-16
将斜率的p值打印为coef(summary(lm1))
,但如果我们使用set.seed(101); d$y <- rnorm(50,mean=d$x,sd=1e-7)
lm2 <- lm(y~x,data=d)
coef(summary(lm2))
(不使用p值格式),我们可以看到该值是9.690173e-203。
更极端的情况:
tval <- coef(summary(lm2))["x","t value"]
2*pt(abs(tval),df=48,lower.tail=FALSE,log.p=TRUE)/log(10)
表明p值实际上已经下降到零。但是,我们仍然可以在对数刻度上得到答案:
{{1}}
给出-692.62(您可以使用上一个示例检查此方法,其中p值不会溢出,并且看到您得到与摘要中打印的答案相同的答案。)
答案 1 :(得分:2)
通常很难处理小数字。
R中对无限的限制是由使用双精度浮点引起的:
?double所有R平台都需要使用符合IEC 60559(也称为IEEE 754)标准的值。这基本上以53位的精度工作,并且在该精度上表示从大约2e-308到2e + 308的绝对值范围。
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
您可以在此处找到 Rmpfr 包,因为它允许您创建多个精确数字。
install.packages("Rmpfr")
require(Rmpfr)
log(mpfr(1/10^309, precBits=500))