从.5开始

问题描述 投票:50回答:5

是的我知道为什么我们总是四舍五入到最近的偶数,如果我们在两个数字的确切中间(即2.5变为2)。但是,当我想为某些人评估数据时,他们不希望出现这种行为。获得这个的最简单方法是什么:

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

为1,2,3,...,10而不是0,2,2,4,4,...,10。

编辑:要清除:舍入后1.4999应为1。 (我觉得这很明显)

r rounding r-faq
5个回答
52
投票

这不是我自己的功能,不幸的是, 我现在无法找到它的位置 (最初是在Statistically Significant blog发现的匿名评论),但它应该有助于你所需要的。

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

32
投票

如果你想要的东西的行为与round完全相同,除了那些xxx.5值,试试这个:

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

5
投票

这似乎有效:

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
投票

正如@CarlWitthoft在评论中所说,这是?round中提到的IEC 60559标准:

注意,为了四舍五入,预计将使用IEC 60559标准,“转到偶数位”。因此,round(0.5)为0,round(-1.5)为-2。但是,这取决于OS服务和表示错误(因为例如0.15没有准确表示,舍入规则适用于所表示的数字而不是打印数字,因此舍入(0.15,1)可以是0.1或0.2 )。

Greg Snow的additional explanation

圆均匀规则背后的逻辑是我们试图表示一个潜在的连续值,如果x来自一个真正连续的分布,那么x == 2.5的概率为0而2.5可能已经从任何值舍入一次在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(或其他小数字)添加到您的值,但这可以向上偏向你的估计。


2
投票

根据您摇晃数据的舒适程度,这有效:

round(x+10*.Machine$double.eps)
# [1]  1  2  3  4  5  6  7  8  9 10
© www.soinside.com 2019 - 2024. All rights reserved.