我正在寻找一种解释,说明如何在R中对这样的序列进行1位小数舍入运算:
seq(1.05, 2.95, by = .1)
在高中时,我会将其四舍五入,即2.05变为2.1。但是R会将其四舍五入为2,以便将小数点后一位舍入。
上面的stackoverflow答案中的以下舍入函数始终实现高中舍入:
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
}
此代码比较R舍入和从上舍入。
data.frame(cbind(
Number = seq(1.05, 2.95, by = .1),
Popular.Round = round2(seq(1.05, 2.95, by = .1), 1),
R.Round = round(seq(1.05, 2.95, by = .1), 1)))
使用R舍入时,1.05舍入到1.1,而2.05舍入到2。然后再次将1.95舍入到2,并将2.95舍入到3。
如果它是“四舍五入”,为什么是3,即奇数。
当被问到这种行为时,有没有比“仅仅处理”更好的响应了?
答案 0 :(得分:2)
阅读时间太长?向下滚动
这对我个人来说是一个有趣的研究。根据文档:
请注意,对于5的四舍五入,请参见IEC 60559标准(另请参见“ IEEE 754”),则应使用“转到偶数位”。因此 round(0.5)为0,round(-1.5)为-2。但是,这取决于 OS服务和表示错误(因为0.15不会 精确表示,四舍五入规则适用于 数字而不是印刷的数字,因此舍入(0.15,1)可能是 0.1或0.2)。
四舍五入为负数意味着四舍五入为 十,因此例如round(x,digits = -2)舍入到最接近的值 一百。
对于数字,如果识别出的数字值为1 ... 22,并且不丢失 值四舍五入到该范围内最接近的整数。复杂 四舍五入以保留指定数字位数 更大的组件。向量的每个元素都经过四舍五入 不同于打印。
首先,您问“如果它是“舍入到偶数”,为什么它是3,即奇数。” 要清楚地说明,舍入到偶数规则适用于舍入5。如果运行round(2.5)
或round(3.5)
,则R分别返回2和4。
如果您在这里https://stat.ethz.ch/pipermail/r-help/2008-June/164927.html,则会看到以下响应:
四舍五入规则的逻辑在于,我们试图 表示基础连续值,如果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(或 四舍五入到您的值,但这可以 向上偏移您的估算值。
简短答案:如果您始终将5s向上舍入,则数据会向上偏移。但是,如果您四舍五入,那么四舍五入的数据将变得平衡。
让我们使用您的数据进行测试:
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 <- data.frame(cbind(
Number = seq(1.05, 2.95, by = .1),
Popular.Round = round2(seq(1.05, 2.95, by = .1), 1),
R.Round = round(seq(1.05, 2.95, by = .1), 1)))
> mean(x$Popular.Round)
[1] 2.05
> mean(x$R.Round)
[1] 2.02
使用更大的样本:
x <- data.frame(cbind(
Number = seq(1.05, 6000, by = .1),
Popular.Round = round2(seq(1.05, 6000, by = .1), 1),
R.Round = round(seq(1.05, 6000, by = .1), 1)))
> mean(x$Popular.Round)
[1] 3000.55
> mean(x$R.Round)
[1] 3000.537