小数点 - 语言R中的概率值为0

时间:2012-07-04 12:06:39

标签: r decimal probability numerical

如何处理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。

2 个答案:

答案 0 :(得分:8)

有各种可能的答案 - 哪一个最有用取决于具体情况:

  • 在普通情况下,R确实无法存储比.Machine$double.xmin更接近零的浮点值,1e-308因平台而异,但通常(如您所发现的)dnorm(-100,log=TRUE)的顺序。如果你真的需要使用这么小的数字并且找不到直接在日志规模上工作的方法,你需要搜索Stack Overflow或者R wiki来寻找处理任意/扩展精度值的方法(但你可能应该这样做)尝试在日志范围内工作 - 这将不那么麻烦了)
  • 在许多情况下,R实际上在内部计算(自然)对数刻度上的p值,并且如果请求则可以返回日志值而不是在给出答案之前对其进行取幂。例如,log10给出-5000.919。您可以直接转换为log10比例(不取幂,然后使用log(10))除以dnorm(-100,log=TRUE)/log(10)p*** = - 2171,这将太小而无法浮点表示。对于log.p=TRUE(累积分布函数)函数,请使用log=TRUE而不是<2.2e-16。 (这个特定点在很大程度上取决于您的特定上下文。即使您没有使用内置R函数,您也可以找到一种在日志范围内提取结果的方法。)
  • 在某些情况下,即使知道更准确的值,R也会将p值结果显示为(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))