web-dev-qa-db-ja.com

10の累乗が5乗で科学的記数法で印刷されるのはなぜですか?

10の累乗が、コンソールでの科学的記数法の印刷にどのように関連しているかを知りたいのですが。 Rドキュメントを検索しましたが、関連するもの、または本当に理解しているものは見つかりませんでした。

まず、私のscipendigitsの設定は

unlist(options("scipen", "digits"))
# scipen digits 
#      0      7 

現在、10の累乗は通常4乗まで印刷され、その後、印刷は5乗で科学的記数法に切り替わります。

10^(1:4)
# [1]    10   100  1000 10000
10^(1:5)
# [1] 1e+01 1e+02 1e+03 1e+04 1e+05

興味深いことに、これはsome 1より大きい他の数値では発生しません。

11^(1:5)
# [1]     11    121   1331  14641 161051

以下から判断すると、5桁が重要と思われます。

100^(1:2)
# [1]   100 10000
100^(1:3)
# [1] 1e+02 1e+04 1e+06

したがって、私の質問は次のとおりです。

科学的記数法が10の4乗と5乗の間でアクティブになり、他の数値ではアクティブにならないのはなぜですか? 5番は重要ですか?さらに、最大桁数のオプションである22に近い数字ではなく、なぜ5なのですか?

41
Rich Scriven

答えは、実際には_?options_のscipenの定義にありますが、いくつかの例を試さずにそれが何を意味するのかを理解するのはかなり難しいです。

「scipen」:整数。数値を固定表記または指数表記で出力することを決定するときに適用されるペナルティ。正の値は固定に偏り、負の値は科学的記数法に偏ります。「scipen」桁より広い場合を除いて、固定表記が優先されます。

それが何を意味するかを知るために、まったく同じ番号の次の3つのペアを調べてください。最初の2つのケースでは、固定表記の文字幅が科学的な幅以下であるため、固定表記が推奨されます

ただし、3番目のケースでは、5つのゼロが_e+nn_を使用して同じ値を表すために使用される4文字よりも多くの文字になるため、固定表記はより広くなります(つまり、「0桁以上広い」)。その結果、その場合科学的記数法が推奨されます

_1e+03
1000
# [1] 1000

1e+04
10000
# [1] 10000

1e+05
100000      ## <- wider
# [1] 1e+05
_

次に、多くのゼロで終わるが、科学的記数法で表現するには_._を使用する必要があるいくつかの数値を調べます。これらの数値では、ゼロが6つ以上ある場合(つまり、1つの_._と文字_e+nn_が5文字を超える場合)に科学的記数法が使用されます。

_1.1e+06
1100000
# [1] 1100000


1.1e+07
11000000     ##  <- wider
# [1] 1.1e+07
_

トレードオフについての推論は、options("scipen")options("digits")の両方の値が関係する他のほとんどの数値では少し注意が必要ですが、一般的な考え方はまったく同じです。

少し意外な問題が発生するのを確認するには、以下をコンソールに貼り付けることをお勧めします(おそらく、各シリーズのどこで科学的記数法への切り替えが発生するかを最初に予測しようとした後)。

_100001
1000001
10000001
100000001
1000000001
10000000001
100000000001
1000000000001

111111
1111111
11111111
111111111
1111111111
11111111111
111111111111
1111111111111
_
42
Josh O'Brien

私はあなたの質問が正確に何であるかについて混乱しています。または、より具体的には、この質問への回答を使用して、Rの動作を何らかの方法で変更/制御する方法を教えてください。特定の方法で数値をフォーマットしようとしていますか?それを行うためのより良い方法があります。

このような値を入力すると、結果はprint()コマンドの1つを介して暗黙的に実行され、コンソールに「適切に」フォーマットされます。物事が画面上で「素敵」に見える必要があるときはいつでも、それを行うためのコードはしばしば醜いです。ここでは、そのコードのほとんどが formatReal 関数、およびヘルパー scientific 関数によって処理されます。後者は、次の情報を追跡します。

_/* for a number x , determine
 *  sgn    = 1_{x < 0}  {0/1}
 *  kpower = Exponent of 10;
 *  nsig   = min(R_print.digits, #{significant digits of alpha})
 *  roundingwidens = 1 if rounding causes x to increase in width, 0 otherwise
 *
 * where  |x| = alpha * 10^kpower   and  1 <= alpha < 10
 */
_

次に、前者の関数はこの情報を使用して、小数点以下の桁数の左右の値のバランスを取り、「見栄えの良い」数値を作成しようとします。これは、数値の大きさや有効桁数などの多くの組み合わせであり、scipenオプションからの環境への影響などです。

print()は、物事を「素敵」に見せるためだけのものです。ニースとは正確には、ベクトル内のすべての値によって異なります。そのコードにはいくつかのハードカットオフがあります。それは非常に適応性があります。一般的な場合に行うすべてのことを簡潔に説明する簡単な方法はありません(これは、あなたが求めているように聞こえます)。

唯一確実なことは、数値を特定の方法でフォーマットする必要がある場合は、正確な制御を可能にするsprintf()formatC()などの関数を使用することです。

もちろん、この動作はclass()に依存しており、最もトリッキーなことが発生する場所であるため、formatRealのものを指摘しました。ただし、整数を使用する場合は違いに注意してください

_c(10, 100, 1000, 10000, 100000)
# [1] 1e+01 1e+02 1e+03 1e+04 1e+05
c(10L, 100L, 1000L, 10000L, 100000L)
# [1]     10    100   1000  10000 100000
_
8
MrFlick