是的,我知道为什么我们总是四舍五入到最近的偶数,如果我们在两个数字的确切中间(即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。(我以为这会很明显)
ylamdve61#
这不是我自己的函数,不幸的是,我现在找不到它的来源(最初是在Statistically Significant blog上的匿名评论中找到的),但它应该能帮助你。
round2 = function(x, digits) { posneg = sign(x) z = abs(x)*10^digits z = z + 0.5 + sqrt(.Machine$double.eps) z = trunc(z) z = z/10^digits z*posneg }
x是要舍入的对象,digits是要舍入到的位数。
x
digits
示例
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
(感谢@Gregor添加+ sqrt(.Machine$double.eps)。
+ sqrt(.Machine$double.eps)
hrysbysz2#
如果你想要的东西,除了那些xxx.5的值,行为完全像round,试试这个:
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
ozxc1zmp3#
正如@CarlWitthoft在评论中所说,这是?round中提到的IEC 60559标准:请注意,对于舍入5,预期将使用IEC 60559标准,“转到偶数位”。(0.5)为0且舍入(-1.5)为-2。但是,这取决于操作系统服务和表示错误(因为例如0.15没有被精确地表示,所以舍入规则适用于所表示的数而不适用于所打印的数,因此舍入(0.15,1)可以是0.1或0.2)。Greg Snow的additional explanation:舍入到偶数规则背后的逻辑是,我们试图表示一个潜在的连续值,如果x来自一个真正的连续分布,那么x==2.5的概率为0,并且2.5可能已经从2.45和2.549999999999之间的任何值舍入过一次......,如果我们用小学里学过的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(或其他小数字)到你的值之前,四舍五入,但这可能会使你的估计偏高。
?round
tzdcorbm4#
这似乎起作用:
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
hxzsmxv25#
这取决于您对抖动数据的舒适程度,可以使用:
round(x+10*.Machine$double.eps) # [1] 1 2 3 4 5 6 7 8 9 10
8fq7wneg6#
该方法:
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(2436.845, 2)
trunc(z)
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 }
qkf9rpyu7#
这模拟了在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
mitkmikd8#
您可以使用以下命令:
ceiling(x-0.49)
或
ceiling(round(x,2)-0.49)
8条答案
按热度按时间ylamdve61#
这不是我自己的函数,不幸的是,我现在找不到它的来源(最初是在Statistically Significant blog上的匿名评论中找到的),但它应该能帮助你。
x
是要舍入的对象,digits
是要舍入到的位数。示例
(感谢@Gregor添加
+ sqrt(.Machine$double.eps)
。hrysbysz2#
如果你想要的东西,除了那些xxx.5的值,行为完全像
round
,试试这个:ozxc1zmp3#
正如@CarlWitthoft在评论中所说,这是
?round
中提到的IEC 60559标准:请注意,对于舍入5,预期将使用IEC 60559标准,“转到偶数位”。(0.5)为0且舍入(-1.5)为-2。但是,这取决于操作系统服务和表示错误(因为例如0.15没有被精确地表示,所以舍入规则适用于所表示的数而不适用于所打印的数,因此舍入(0.15,1)可以是0.1或0.2)。
Greg Snow的additional explanation:
舍入到偶数规则背后的逻辑是,我们试图表示一个潜在的连续值,如果x来自一个真正的连续分布,那么x==2.5的概率为0,并且2.5可能已经从2.45和2.549999999999之间的任何值舍入过一次......,如果我们用小学里学过的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(或其他小数字)到你的值之前,四舍五入,但这可能会使你的估计偏高。
tzdcorbm4#
这似乎起作用:
Ananda Mahto的回应似乎做到了这一点,甚至更多--我不确定他的回应中的额外代码是什么;或者,换句话说,我不知道如何破坏上面定义的rnd()函数。
示例:
hxzsmxv25#
这取决于您对抖动数据的舒适程度,可以使用:
8fq7wneg6#
该方法:
当我们有很多位数的数字时,似乎不能很好地工作。例如,执行
round2(2436.845, 2)
将给予我们2436.84。这个问题似乎发生在trunc(z)
函数上。总的来说,我认为这与R存储数字的方式有关,因此
trunc
和float
函数并不总是有效。我能够以不太优雅的方式绕过它:qkf9rpyu7#
这模拟了在0.5处从零舍入:
mitkmikd8#
您可以使用以下命令:
或