web-dev-qa-db-ja.com

0.5から切り上げ

はい、2つの数値のちょうど真ん中(つまり、2.5が2になる)にいる場合、常に最も近い偶数に丸める理由を知っています。しかし、一部の人々のデータを評価したいとき、彼らはこの振る舞いを望まない。これを取得する最も簡単な方法は何ですか:

x <- seq(0.5,9.5,by=1)
round(x)

0、2、2、4、4、...、10ではなく、1、2、3、...、10になります。

編集:クリアするには:丸め後、1.4999は1になります。 (これは明らかだと思いました)

52
jakob-r

これは私自身の機能ではありませんが、残念ながら、 今のところどこで手に入れたか分からない (元々 Statistically Significantブログ で匿名のコメントとして見つかりました)、しかしそれはあなたが必要とするものを助けるはずです。

round2 = function(x, n) {
  posneg = sign(x)
  z = abs(x)*10^n
  z = z + 0.5
  z = trunc(z)
  z = z/10^n
  z*posneg
}

xは丸めたいオブジェクトであり、nは丸める桁数です。

x = c(1.85, 1.54, 1.65, 1.85, 1.84)
round(x, 1)
# [1] 1.8 1.5 1.6 1.8 1.8
round2(x, 1)
# [1] 1.9 1.5 1.7 1.9 1.8
56

これらのxxx.5値を除いてroundとまったく同じように動作するものが必要な場合は、これを試してください。

x <- seq(0, 1, 0.1)
x
# [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
floor(0.5 + x)
# [1] 0 0 0 0 0 1 1 1 1 1 1
32
flodel

@CarlWitthoftがコメントで述べたように、これは?roundで言及されているIEC 60559標準です:

5を四捨五入する場合、IEC 60559標準が使用され、「偶数桁に進む」ことが期待されます。したがって、round(0.5)は0で、round(-1.5)は- 2.ただし、これはOSサービスと表現エラーに依存します(たとえば、0.15は正確に表現されないため、丸めルールは印刷された数値ではなく表現された数値に適用されるため、round(0.15、1)は0.1または0.2)。

追加の説明 Greg Snow:

偶数へのラウンドルールの背後にあるロジックは、基礎となる連続値を表現しようとしているので、xが真の連続分布に由来する場合、x == 2.5の確率は0であり、2.5は任意の値からすでに1回丸められている可能性があります2.45から2.54999999999999 ...、学年で学んだ0.5の切り上げルールを使用する場合、二重丸めは2.45から2.50の間の値がすべて3に丸められることを意味します(最初に2.5に丸められます)。これにより、推定値が上方に偏る傾向があります。バイアスを取り除くには、2.5に丸める前に戻る(非現実的ではないことが多い)か、半分の時間を切り上げて半分の時間を切り捨てる必要があります(または、どれだけの可能性に比例して丸めることが良いでしょう) 2.5未満または2.5に丸められた値が表示されますが、ほとんどの基礎となる分布では50/50に近い値になります)。確率論的なアプローチは、ラウンド関数がラウンドする方法をランダムに選択することですが、決定論的なタイプはそれと快適ではないため、ラウンドする一貫したルールとして「偶数に丸める」が選択されました上下約50/50。

2.5が正確な値(お金など)を表す可能性が高いデータを処理している場合、すべての値に10または100を掛けて整数で処理し、最後の印刷のためにのみ元に戻すことでより良い結果を得ることができます。 2.50000001は3に四捨五入するので、最終印刷までより多くの桁数の精度を維持する場合、丸めは予想される方向に進むか、丸めの直前に値に0.000000001(または他の小さな数)を追加できますが、見積もりを上方にバイアスします。

7
Jaap

これは動作しているようです:

rnd <- function(x) trunc(x+sign(x)*0.5)

Ananda Mahtoの応答は、これ以上のことをしているようです。または、言い換えると、上記で定義したrnd()関数をどのように壊すかわかりません。

例:

seq(-2, 2, by=0.5)
#  [1] -2.0 -1.5 -1.0 -0.5  0.0  0.5  1.0  1.5  2.0
round(x)
#  [1] -2 -2 -1  0  0  0  1  2  2
rnd(x)
#  [1] -2 -2 -1 -1  0  1  1  2  2
5
user1854990

データのジグリングの快適さに応じて、これは機能します。

round(x+10*.Machine$double.eps)
# [1]  1  2  3  4  5  6  7  8  9 10
3
MichaelChirico