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

SHR*_*ram 2 numerical r probability decimal

如何治疗R中的p值?

我期待非常低的p值,如:

1.00E-80
Run Code Online (Sandbox Code Playgroud)

我需要-log10

-log10(1.00E-80)
Run Code Online (Sandbox Code Playgroud)

-log10(0)是Inf,但是在圆整的意义上也是Inf.

但似乎在1.00E-308之后,R收益率为0.

1/10^308  
[1] 1e-308

 1/10^309 
[1] 0
Run Code Online (Sandbox Code Playgroud)

p值显示的准确性与lm功能是否与截止点1e-308相同,或者它的设计使得我们需要一个截止点,我需要考虑一个不同的截止点 - 例如1e-100(对于例如)用<1e-100替换0.

Ben*_*ker 8

有各种可能的答案 - 哪一个最有用取决于上下文:

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

版画

....
t = 56.2902, df = 17.904, p-value < 2.2e-16
Run Code Online (Sandbox Code Playgroud)

但您仍然可以从结果中提取精确的p值

> t1$p.value
[1] 1.856174e-18
Run Code Online (Sandbox Code Playgroud)

(在许多情况下,此行为由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)
Run Code Online (Sandbox Code Playgroud)

summary(lm1)打印斜率的p值<2.2e-16,但如果我们使用coef(summary(lm1))(不使用p值格式),我们可以看到值为9.690173e-203.

更极端的情况:

set.seed(101); d$y <- rnorm(50,mean=d$x,sd=1e-7)
lm2 <- lm(y~x,data=d)
coef(summary(lm2))
Run Code Online (Sandbox Code Playgroud)

表明p值实际上已经下降到零.但是,我们仍然可以在日志范围内得到答案:

tval <- coef(summary(lm2))["x","t value"]
2*pt(abs(tval),df=48,lower.tail=FALSE,log.p=TRUE)/log(10)
Run Code Online (Sandbox Code Playgroud)

给出-692.62(您可以使用上一个示例检查此方法,其中p值不会溢出,并且看到您得到与摘要中打印的答案相同的答案).