2013-01-31 133 views
2

我正在計算R中F檢驗的p值,並且似乎無法顯示低於1e-16的任何值。例如,適用於F值從80到90自由度爲1,200:如何在R中獲得精確的低p值(來自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()函數的計算精度?

+2

你的意思是你想更多數字顯示?試試:options(digits = 15) 或者您需要知道R使用有限精度算術,您的答案在15或16位小數後不準確 – ThiS

+1

這個練習的實際目的是什麼?如果概率非常低,那麼它的「確切」值應該不重要。然而,也許'pf(80:90,1,200,log.p = TRUE)'很有意思。 – Roland

+1

閱讀http://stackoverflow.com/q/11328784/1412059 – Roland

回答

11

p - 無論如何,這個低點是沒有意義的。首先,大多數計算都使用輕微的近似值,所以不精確性主導了結果,因爲趨向於零值,其次,更重要的是,您的人口與模型分佈的任何微小偏差都會壓倒您期望的準確度。

簡單地引用p - 值作爲 'p < 0.0001',並用它做。

+0

不回答這個問題;忽略評論中討論的多個測試場景。 –

3

除了傑克關於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 
+0

這是對我的答案的一個很好的補充,謝謝Brian。 –