2

R で p 値を処理する方法は?

次のような非常に低い p 値を期待しています。

1.00E-80

-log10 する必要があります

-log10(1.00E-80)

-log10(0) は Inf ですが、丸めの意味でも Inf です。

しかし、1.00E-308 の後、R は 0 を返すようです。

1/10^308  
[1] 1e-308

 1/10^309 
[1] 0

関数を使用した p 値表示の精度はlm、カットオフ ポイント 1e-308 と同じですか、それとも、カットオフ ポイントが必要で、1e-100 などの別のカットオフ ポイントを考慮する必要があるように設計されているだけですか (例) 0 を <1e-100 に置き換えます。

4

2 に答える 2

8

考えられる答えにはさまざまなものがあります。どれが最も役立つかは、コンテキストによって異なります。

  • R は、通常の状況では よりもゼロに近い浮動小数点値を格納することはできません.Machine$double.xmin。これは、プラットフォームによって異なりますが、通常 (発見したように) のオーダーです1e-308。本当にこれほど小さい数値を扱う必要があり、対数スケールで直接作業する方法が見つからない場合は、スタック オーバーフローまたは R wiki で任意/拡張精度値を処理する方法を検索する必要があります (ただし、おそらく対数スケールで作業してみてください -- 手間がかかりません)
  • 多くの場合、R は内部で (自然な) 対数スケールで p 値を実際に計算し、要求があれば、答えを出す前に指数化するのではなく、対数値を返すことができます。たとえば、dnorm(-100,log=TRUE)-5000.919 を指定します。log10=-2171 で割ることによりlog(10)、 log10スケールに直接変換できます (累乗してから を使用dnorm(-100,log=TRUE)/log(10)する必要はありません)。これは小さすぎて浮動小数点で表すことができません。p***(累積分布関数) 関数については、log.p=TRUEではなくを使用しますlog=TRUE。(この特定の点は、特定のコンテキストに大きく依存します。組み込みの R 関数を使用していない場合でも、対数スケールで結果を抽出する方法を見つけることができる場合があります。)
  • <2.2e-16より正確な値がわかっている場合でも、R は p 値の結果を偶数として表示する場合があります。(t1 <- t.test(rnorm(10,100),rnorm(10,80)))

版画

....
t = 56.2902, df = 17.904, p-value < 2.2e-16

ただし、結果から正確な p 値を抽出することはできます

> t1$p.value
[1] 1.856174e-18

(多くの場合、この動作はformat.pval()関数によって制御されます)

これがどのように機能するかの図lm

d <- data.frame(x=rep(1:5,each=10))
set.seed(101)
d$y <- rnorm(50,mean=d$x,sd=0.0001)
lm1 <- lm(y~x,data=d)

summary(lm1)は勾配の p 値を として出力しますが、 (p 値の書式設定<2.2e-16を使用coef(summary(lm1))しない) を使用すると、値が 9.690173e-203 であることがわかります。

より極端なケース:

set.seed(101); d$y <- rnorm(50,mean=d$x,sd=1e-7)
lm2 <- lm(y~x,data=d)
coef(summary(lm2))

は、p 値が実際にゼロにアンダーフローしたことを示しています。ただし、対数スケールで答えを得ることができます。

tval <- coef(summary(lm2))["x","t value"]
2*pt(abs(tval),df=48,lower.tail=FALSE,log.p=TRUE)/log(10)

-692.62 を返します (p 値がオーバーフローしない前の例でこのアプローチを確認すると、要約に出力されたのと同じ答えが得られることがわかります)。

于 2012-07-04T12:38:55.903 に答える
2

小さい数は一般的に扱いにくいです。

無限に対する R の制限は、倍精度浮動小数点の使用によって引き起こされます。

?double すべての R プラットフォームは、IEC 60559 (IEEE 754 とも呼ばれます) 標準に準拠した値で動作する必要があります。これは基本的に 53 ビットの精度で動作し、その精度で約 2e-308 から 2e+308 までの絶対値の範囲を表します。

http://en.wikipedia.org/wiki/Double_precision_floating-point_format

Rmpfrパッケージを使用すると、複数の精度の数値を作成できるため、ここで役立つことがあります。

install.packages("Rmpfr")
require(Rmpfr)

log(mpfr(1/10^309, precBits=500))
于 2012-07-04T13:03:42.193 に答える