2

我正在计算 z 分数以查看某个值是否远离分布的平均值/中位数。我最初是用平均值来做的,然后把它们变成了 2 侧 pvalues。但是现在使用中位数我注意到 pvalues 中有一些 Na。

我确定这发生在离中位数非常远的值上。并且看起来与 pnorm 计算有关。“‘qnorm’基于 Wichura 的算法 AS 241,可提供高达约 16 位的精确结果。”

有谁知道解决这个问题的方法,因为我想要非常小的 pvalue。谢谢,

> z<- -12.5
> 2-2*pnorm(abs(z))
[1] 0
> z<- -10  
> 2-2*pnorm(abs(z))
[1] 0 
> z<- -8 
> 2-2*pnorm(abs(z))
[1] 1.332268e-15
4

3 回答 3

2

中间,您实际上正在计算非常高的p 值:

options(digits=22)
z <- c(-12.5,-10,-8)
pnorm(abs(z))
# [1] 1.0000000000000000000000 1.0000000000000000000000 0.9999999999999993338662
2-2*pnorm(abs(z))
# [1] 0.000000000000000000000e+00 0.000000000000000000000e+00 1.332267629550187848508e-15

我认为使用低 p 值(接近于零)会更好,但我在数学方面还不够好,无法知道接近一 p 值的错误是在 AS241 算法中还是在浮点存储中. 看看低值显示得有多好:

pnorm(z)
# [1] 3.732564298877713761239e-36 7.619853024160526919908e-24 6.220960574271784860433e-16

记住1 - pnorm(x)相当于pnorm(-x). 所以,2-2*pnorm(abs(x))等价于2*(1 - pnorm(abs(x))等价于2*pnorm(-abs(x)),所以只需使用:

2 * pnorm(-abs(z))
#  [1] 7.465128597755427522478e-36 1.523970604832105383982e-23 1.244192114854356972087e-15

这应该更准确地得到你正在寻找的东西。

于 2014-10-20T15:54:37.547 回答
1

一个想法是,您必须使用精度更高的 exp(),但是您可以使用 log(p) 来获得稍微更高的尾部精度,否则对于非 log p 值,您实际上是 0就可以计算的范围而言:

> z<- -12.5
> pnorm(abs(z),log.p=T)
[1] -7.619853e-24

转换回 p 值效果不佳,但您可以在 log(p) 上进行比较...

> exp(pnorm(abs(z),log.p=T))
[1] 1
于 2014-10-20T17:05:38.303 回答
0

pnorm 是一个函数,它根据给定的 x 给出 P 值。如果您未指定更多参数,则默认分布为正态分布,均值为 0,标准差为 1。
基于 simetrity,pnorm(a) = 1-pnorm(-a)。
在 R 中,如果您添加正数,它会将它们四舍五入。但是,如果您添加负数,则不会进行舍入。因此,使用此公式和负数,您可以计算所需的值。

> pnorm(0.25)
[1] 0.5987063
> 1-pnorm(-0.25)
[1] 0.5987063
> pnorm(20)
[1] 1
> pnorm(-20)
[1] 2.753624e-89
于 2014-10-20T14:40:52.107 回答