考えられる答えにはさまざまなものがあります。どれが最も役立つかは、コンテキストによって異なります。
- 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 値がオーバーフローしない前の例でこのアプローチを確認すると、要約に出力されたのと同じ答えが得られることがわかります)。