我正在计算R中F检验的p值,并且似乎无法显示低于1e-16的任何值。例如,对于F值从80到90,自由度1,200:
> 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()
函数计算的精度?
答案 0 :(得分:11)
p - 无论如何,这个低值都没有意义。首先,大多数计算使用轻微的近似值,因此不精确性会影响结果,因为您倾向于零 p - 值,其次,可能更重要的是,您的人口与模型分布的任何微小偏差都将压倒你想要的准确度。
只需将 p - 值引用为“ p < 0.0001'并完成它。
答案 1 :(得分:3)
除了杰克关于p值的实用建议之外,函数定义得很好(如果不实用),所以我将给出有限精度的数学推理,但这不起作用。
.Machine$double.eps
是2.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