R 圆的,但是。5应该铺地板
From R help function(R帮助功能):请注意,对于5的四舍五入,预计将使用IEC 60559标准“至偶数”。因此,R 圆的,但是。5应该铺地板,r,rounding,R,Rounding,From R help function(R帮助功能):请注意,对于5的四舍五入,预计将使用IEC 60559标准“至偶数”。因此,round(0.5)为0,round(-1.5)为-2 > round(0.5) [1] 0 > round(1.5) [1] 2 > round(2.5) [1] 2 > round(3.5) [1] 4 > round(4.5) [1] 4 但我需要将所有以.5结尾的值向下舍入。所有其他值都应该四舍五入,因为它们是通过round(
round(0.5)
为0,round(-1.5)
为-2
> round(0.5)
[1] 0
> round(1.5)
[1] 2
> round(2.5)
[1] 2
> round(3.5)
[1] 4
> round(4.5)
[1] 4
但我需要将所有以.5结尾的值向下舍入。所有其他值都应该四舍五入,因为它们是通过round()函数完成的。
例如:
有没有快速的方法?检查
x%%1
的剩余部分是否等于.5
,然后将数字放低或四舍五入:
x <- seq(1, 3, 0.1)
ifelse(x %% 1 == 0.5, floor(x), round(x))
> 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3
x11233
此函数通过查找小数部分等于0.5
的元素,并在四舍五入之前向其添加一个小负数,确保它们向下四舍五入。(它以无害但稍微模糊的方式依赖于这样一个事实,即R中的布尔向量与数值向量相乘时将转换为0
和1
的向量。)
f该函数(不是golfed)非常简单,可以检查剩下的小数是.5
还是更少。实际上,您可以轻松地使其更有用,并将0.5
作为参数:
nice.round <- function(x, myLimit = 0.5) {
bX <- x
intX <- as.integer(x)
decimals <- x%%intX
if(is.na(decimals)) {
decimals <- 0
}
if(decimals <= myLimit) {
x <- floor(x)
} else {
x <- round(x)
}
if (bX > 0.5 & bX < 1) {
x <- 1
}
return(x)
}
我也要加入马戏团:
rndflr <- function(x) {
sel <- vapply(x - floor(x), function(y) isTRUE(all.equal(y, 0.5)), FUN.VALUE=logical(1))
x[sel] <- floor(x[sel])
x[!sel] <- round(x[!sel])
x
}
rndflr(c(3.5,8.6,8.1,4.5))
#[1] 3 9 8 4
rndflr根据Dietrich Epp的评论,您可以使用带有偏移量的天花()
函数来获得快速、矢量化、正确的解决方案:
round_down <- function(x) ceiling(x - 0.5)
round_down(seq(-2, 3, by = 0.5))
## [1] -2 -2 -1 -1 0 0 1 1 2 2 3
这种舍入程序的应用是什么?为什么不干脆ceil(x-0.5)
?@DietrichEpp我来问同样的问题:我觉得你的问题可能应该是一个答案:)我们能后退一点,问你为什么要这样做吗。您在舍入数据集中引入了偏差。什么是手头的问题,为什么你们认为它需要这种特殊的治疗?密切相关:+1来自我。唯一的答案是使用all.equal()
,这是处理此类情况的正确方法。这是迄今为止最好的方法。“不是golfed”-这应该是件坏事吗???@WChargin绝对不是,我只是说这个函数可以很容易地缩短。下面是参与编辑这篇文章的@Kreuff的一句评论:“目前,这个函数在0.5到1.0之间的值下不能正常工作。nice.round(0.6)
返回0。”
> nice.round(1.5)
[1] 1
> nice.round(1.6)
[1] 2
> nice.round(10000.624541)
[1] 10001
> nice.round(0.4)
[1] 0
> nice.round(0.6)
[1] 1
rndflr <- function(x) {
sel <- vapply(x - floor(x), function(y) isTRUE(all.equal(y, 0.5)), FUN.VALUE=logical(1))
x[sel] <- floor(x[sel])
x[!sel] <- round(x[!sel])
x
}
rndflr(c(3.5,8.6,8.1,4.5))
#[1] 3 9 8 4
round_down <- function(x) ceiling(x - 0.5)
round_down(seq(-2, 3, by = 0.5))
## [1] -2 -2 -1 -1 0 0 1 1 2 2 3
mean(round_down(seq(-2, 3, by = 0.5)))
## [1] 0.2727273
mean(round(seq(-2, 3, by = 0.5)))
## [1] 0.4545455
mean(seq(-2, 3, by = 0.5))
## [1] 0.5