r-从.5向上取整

  • 本文关键字: r rounding r-faq
  • 更新时间 :
  • 英文 :


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

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

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

编辑:要清除:四舍五入后1.4999应该是1。(我认为这是显而易见的)

这不是我自己的函数,不幸的是,我现在找不到它的位置(最初是在Statistically Significant博客上作为匿名评论找到的),但它应该有助于满足您的需求。

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 = 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)。)

如果您想要一个除了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

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

请注意,对于5的四舍五入,预计将使用IEC 60559标准,"转到偶数"。因此,圆形(0.5)为0,圆形(-1.5)为-2。然而,这取决于操作系统服务和表示误差(因为例如0.15没有准确表示,所以舍入规则适用于表示的数字,而不适用于打印的数字,因此舍入(0.15,1)可以是0.1或0.2)

Greg Snow的额外解释:

四舍五入规则背后的逻辑是,我们正在努力表示一个潜在的连续值,如果x来自连续分布,则x==2.5的概率为02.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(或其他小数字)转换为四舍五入前的值,但这可以把你的估计向上倾斜。

这似乎有效:

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

根据您对数据抖动的舒适程度,这是可行的:

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

此方法:

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存储数字的方式有关,因此truncfloat函数并不总是有效的。我能够以一种不是最优雅的方式绕过它:

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
}

这模拟了从零到.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

您可以使用以下内容:

ceiling(x-0.49)

ceiling(round(x,2)-0.49)

相关内容

  • 没有找到相关文章

最新更新