是的我知道为什么我们总是四舍五入到最近的偶数,如果我们在两个数字的确切中间(即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。 (我认为这很明显)
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分: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(或 在四舍五入之前,你的价值就是其他小数字,但那可以 向上偏向你的估计。
答案 4 :(得分:2)
根据您对数据摆动的舒适程度,这有效:
round(x+10*.Machine$double.eps)
# [1] 1 2 3 4 5 6 7 8 9 10
答案 5 :(得分:2)
此方法:
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
}
当我们有许多位数的数字时,似乎不能很好地工作。例如。做round2(2436.845, 2)
将给我们2436.84。 trunc(z)
函数似乎出现了此问题。
总的来说,我认为这与R存储数字的方式有关,因此trunc
和float
函数并不总是起作用。我能够以最优雅的方式解决它:
round2 = function(x, n) {
posneg = sign(x)
z = abs(x)*10^n
z = z + 0.5
z = trunc(as.numeric(as.character(z)))
z = z/10^n
(z)*posneg
}
答案 6 :(得分:1)
这模仿了从零到0.5的舍入:
round_2 <- function(x, digits = 0) {
x = x + abs(x) * sign(x) * .Machine$double.eps
round(x, digits = digits)
}
round_2(.5 + -2:4)
-2 -1 1 2 3 4 5
答案 7 :(得分:-2)
最好,最简单的解决方案是在数字上加上0.00000001,然后四舍五入。
回合(1.15 + 0.00000001,1)= 1.2