【问题标题】:How to compute p-values from z-scores in R when the Z score is large (pvalue much below zero)?当 Z 分数很大(p 值远低于零)时,如何从 R 中的 z 分数计算 p 值?
【发布时间】:2018-03-07 01:29:06
【问题描述】:

在遗传学中,非常小的 p 值很常见(例如 10^-400),我正在寻找一种方法来在 R 中的 z 值很大时获得非常小的 p 值(双尾),例如:

z=40
pvalue = 2*pnorm(abs(z), lower.tail = F)

这给了我一个零而不是一个非常重要的非常小的值。

【问题讨论】:

标签: r statistics normal-distribution genetics


【解决方案1】:

无法处理小于大约 10^(-308) (.Machine$double.xmin) 的 p 值并不是 R 的错,而是任何使用双精度(64 位)浮点数的计算系统的一般限制存储数字信息。

通过对数尺度计算解决问题并不难,但你不能将结果作为数值存储在R中;相反,您需要将结果存储(或打印)为尾数加指数。

pvalue.extreme <- function(z) {
   log.pvalue <- log(2) + pnorm(abs(z), lower.tail = FALSE, log.p = TRUE)
   log10.pvalue <- log.pvalue/log(10) ## from natural log to log10
   mantissa <- 10^(log10.pvalue %% 1)
   exponent <- log10.pvalue %/% 1
   ## or return(c(mantissa,exponent))
   return(sprintf("p value is %1.2f times 10^(%d)",mantissa,exponent))
}

用不太极端的情况进行测试:

pvalue.extreme(5)
## [1] "p value is 5.73 times 10^(-7)"
2*pnorm(5,lower.tail=FALSE)
## [1] 5.733031e-07

更极端:

pvalue.extreme(40)
## [1] "p value is 7.31 times 10^(-350)"

在 R (Brobdingnag, Rmpfr, ...) 中,有多种包可以处理具有扩展精度的极大/极小数字,例如,

2*Rmpfr::pnorm(mpfr(40, precBits=100), lower.tail=FALSE, log.p = FALSE)
## 1 'mpfr' number of precision  100   bits 
## [1] 7.3117870818300594074979715966414e-350

但是,在使用任意精度系统时,您将在计算效率和便利性方面付出巨大代价。

【讨论】:

  • 我明白了!感谢您彻底而清晰的解释,恢复了我对 R 的信心。所以 R 可以达到 10^(-323),这对于顶级遗传关联可能已经足够了。谢谢。
猜你喜欢
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 2020-05-23
  • 1970-01-01
  • 2019-08-02
  • 2017-12-20
相关资源
最近更新 更多