3

我正在计算 R 中的 F 检验的 p 值,它似乎无法显示低于 1e-16 的任何内容。例如,对于从 80 到 90 且自由度为 1,200 的 F 值:

> 1-pf(80:90,1,200)
 [1] 2.220446e-16 2.220446e-16 1.110223e-16 1.110223e-16 0.000000e+00 0.000000e+00 0.000000e+00
 [8] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00

如何提高pf()函数计算的精度?

4

2 回答 2

12

无论如何,这么低的p值毫无意义。首先,大多数计算使用轻微的近似值,因此当您倾向于零p值时,不精确性会主导结果,其次,可能更重要的是,您的总体与建模分布的任何微小偏差都会压倒您想要的准确性。

只需将 p 值引用' p < 0.0001' 并完成它。

于 2013-01-31T16:31:21.860 回答
4

除了 Jack 关于 p 值的实用建议外,函数定义明确(如果不实用),因此我将给出有限精度的数学原因,这不起作用。

.Machine$double.eps2.220446e-16,这是你可以加到 1 并得到不同的最小数字。所以与 1 不同,这是你得到的最小值。

> pf(80:90,1,200)
 [1] 1 1 1 1 1 1 1 1 1 1 1
> sprintf("%.17f",pf(80:90,1,200))
 [1] "0.99999999999999978" "0.99999999999999978" "0.99999999999999989"
 [4] "0.99999999999999989" "1.00000000000000000" "1.00000000000000000"
 [7] "1.00000000000000000" "1.00000000000000000" "1.00000000000000000"
[10] "1.00000000000000000" "1.00000000000000000"
> sprintf("%a", pf(80:90,1,200))
 [1] "0x1.ffffffffffffep-1" "0x1.ffffffffffffep-1" "0x1.fffffffffffffp-1"
 [4] "0x1.fffffffffffffp-1" "0x1p+0"               "0x1p+0"              
 [7] "0x1p+0"               "0x1p+0"               "0x1p+0"              
[10] "0x1p+0"               "0x1p+0"              

但是,您可以使用近似值 $1-p = -\ln(p)$ 并且您可以更精确地获得 p 值的对数

> -pf(80:90,1,200,log.p=TRUE)
 [1] 2.540347e-16 1.770938e-16 1.236211e-16 8.640846e-17 6.047690e-17
 [6] 4.238264e-17 2.974043e-17 2.089598e-17 1.470045e-17 1.035491e-17
[11] 7.303070e-18
于 2013-01-31T16:44:57.867 回答