如何舍入到最近的10(或100或X)?

Abe*_*Abe 82 r rounding

我正在编写一个绘制数据的函数.我想为y轴指定一个很好的圆数max,它大于数据集的最大值.

具体来说,我想要一个foo执行以下功能的函数:

foo(4) == 5
foo(6.1) == 10 #maybe 7 would be better
foo(30.1) == 40
foo(100.1) == 110 
Run Code Online (Sandbox Code Playgroud)

我已经到了

foo <- function(x) ceiling(max(x)/10)*10
Run Code Online (Sandbox Code Playgroud)

舍入到最接近的10,但这对任意舍入间隔不起作用.

在R中有更好的方法吗?

Ram*_*ath 120

plyr库具有round_any非常通用的功能,可以进行各种舍入.例如

library(plyr)
round_any(132.1, 10)               # returns 130
round_any(132.1, 10, f = ceiling)  # returns 140
round_any(132.1, 5, f = ceiling)   # returns 135
Run Code Online (Sandbox Code Playgroud)

  • 有关“dplyr”替代品,请参阅:/sf/answers/3254287151/ (4认同)

Tom*_*mmy 60

如果你只想要舍入到最接近的10的幂,那么只需定义:

roundUp <- function(x) 10^ceiling(log10(x))
Run Code Online (Sandbox Code Playgroud)

当x是向量时,这实际上也有效:

> roundUp(c(0.0023, 3.99, 10, 1003))
[1] 1e-02 1e+01 1e+01 1e+04
Run Code Online (Sandbox Code Playgroud)

..但如果你想要舍入到一个"漂亮"的数字,你首先需要定义一个"好"的数字.下面让我们将"nice"定义为具有从1到10的良好基值的向量.默认设置为偶数加5.

roundUpNice <- function(x, nice=c(1,2,4,5,6,8,10)) {
    if(length(x) != 1) stop("'x' must be of length 1")
    10^floor(log10(x)) * nice[[which(x <= 10^floor(log10(x)) * nice)[[1]]]]
}
Run Code Online (Sandbox Code Playgroud)

当x是矢量时,上面的方法不起作用 - 现在晚上太晚了:)

> roundUpNice(0.0322)
[1] 0.04
> roundUpNice(3.22)
[1] 4
> roundUpNice(32.2)
[1] 40
> roundUpNice(42.2)
[1] 50
> roundUpNice(422.2)
[1] 500
Run Code Online (Sandbox Code Playgroud)

[[编辑]]

如果问题是如何舍入到指定的最近值(如10或100),那么詹姆斯的回答似乎是最合适的.我的版本允许您获取任何值并自动将其舍入为合理的"好"值.上面"漂亮"矢量的其他一些好的选择是:1:10, c(1,5,10), seq(1, 10, 0.1)

例如,如果绘图中有一系列值,[3996.225, 40001.893]则自动方式应考虑范围的大小和数字的大小.正如哈德利指出的,pretty()功能可能就是你想要的.


Zer*_*ero 37

R中的round函数如果为负数则赋予digits参数特殊含义.

round(x,digits = 0)

舍入为负数位意味着舍入为10的幂,因此例如round(x,digits = -2)舍入到最接近的百位.

这意味着像下面这样的函数非常接近你所要求的.

foo <- function(x)
{
    round(x+5,-1)
}
Run Code Online (Sandbox Code Playgroud)

输出如下所示

foo(4)
[1] 10
foo(6.1)
[1] 10
foo(30.1)
[1] 40
foo(100.1)
[1] 110
Run Code Online (Sandbox Code Playgroud)

  • 惊人的!你的答案应该被标记为正确的! (2认同)

Jam*_*mes 24

怎么样:

roundUp <- function(x,to=10)
{
  to*(x%/%to + as.logical(x%%to))
}
Run Code Online (Sandbox Code Playgroud)

这使:

> roundUp(c(4,6.1,30.1,100.1))
[1]  10  10  40 110
> roundUp(4,5)
[1] 5
> roundUp(12,7)
[1] 14
Run Code Online (Sandbox Code Playgroud)


Ana*_*ina 17

如果在round()的digits-argument中添加一个负数,R会将其四舍五入为10,100等的倍数.

    round(9, digits = -1) 
    [1] 10    
    round(89, digits = -1) 
    [1] 90
    round(89, digits = -2) 
    [1] 100
Run Code Online (Sandbox Code Playgroud)


the*_*ist 12

将任意数字向上/向下舍入到任意间隔

您可以使用模运算符 轻松地将数字舍入到特定间隔%%.

功能:

round.choose <- function(x, roundTo, dir = 1) {
  if(dir == 1) {  ##ROUND UP
    x + (roundTo - x %% roundTo)
  } else {
    if(dir == 0) {  ##ROUND DOWN
      x - (x %% roundTo)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

例子:

> round.choose(17,5,1)   #round 17 UP to the next 5th
[1] 20
> round.choose(17,5,0)   #round 17 DOWN to the next 5th
[1] 15
> round.choose(17,2,1)   #round 17 UP to the next even number
[1] 18
> round.choose(17,2,0)   #round 17 DOWN to the next even number
[1] 16
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

模运算符%%确定将第一个数除以第二个数的余数.将此间隔添加或减去您感兴趣的数量可以基本上将该数字"舍入"到您选择的间隔.

> 7 + (5 - 7 %% 5)       #round UP to the nearest 5
[1] 10
> 7 + (10 - 7 %% 10)     #round UP to the nearest 10
[1] 10
> 7 + (2 - 7 %% 2)       #round UP to the nearest even number
[1] 8
> 7 + (100 - 7 %% 100)   #round UP to the nearest 100
[1] 100
> 7 + (4 - 7 %% 4)       #round UP to the nearest interval of 4
[1] 8
> 7 + (4.5 - 7 %% 4.5)   #round UP to the nearest interval of 4.5
[1] 9

> 7 - (7 %% 5)           #round DOWN to the nearest 5
[1] 5
> 7 - (7 %% 10)          #round DOWN to the nearest 10
[1] 0
> 7 - (7 %% 2)           #round DOWN to the nearest even number
[1] 6
Run Code Online (Sandbox Code Playgroud)

更新:

方便的2参数版本:

rounder <- function(x,y) {
  if(y >= 0) { x + (y - x %% y)}
  else { x - (x %% abs(y))}
}
Run Code Online (Sandbox Code Playgroud)

正面y价值roundUp,而负yroundDown:

 # rounder(7, -4.5) = 4.5, while rounder(7, 4.5) = 9.
Run Code Online (Sandbox Code Playgroud)

要么....

根据标准舍入规则自动向上向下舍入的函数:

Round <- function(x,y) {
  if((y - x %% y) <= x %% y) { x + (y - x %% y)}
  else { x - (x %% y)}
}
Run Code Online (Sandbox Code Playgroud)

如果x>在后续舍入值实例之间自动舍入y:

# Round(1.3,1) = 1 while Round(1.6,1) = 2
# Round(1.024,0.05) = 1 while Round(1.03,0.05) = 1.05
Run Code Online (Sandbox Code Playgroud)


han*_*frc 7

关于四舍五入到任意数的多重性,例如10,这是詹姆斯答案的简单替代.

它适用于任何数舍入(from)和任何实数正数舍入到(to):

> RoundUp <- function(from,to) ceiling(from/to)*to
Run Code Online (Sandbox Code Playgroud)

例:

> RoundUp(-11,10)
[1] -10
> RoundUp(-0.1,10)
[1] 0
> RoundUp(0,10)
[1] 0
> RoundUp(8.9,10)
[1] 10
> RoundUp(135,10)
[1] 140

> RoundUp(from=c(1.3,2.4,5.6),to=1.1)  
[1] 2.2 3.3 6.6
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您总是想将数字向上舍入到最接近的 X,可以使用以下ceiling函数:

#Round 354 up to the nearest 100:
> X=100
> ceiling(354/X)*X
[1] 400

#Round 47 up to the nearest 30:
> Y=30
> ceiling(47/Y)*Y
[1] 60
Run Code Online (Sandbox Code Playgroud)

同样,如果您总是想要向下舍,请使用该floor函数。如果您想简单地向上或向下舍入到最近的 Z,请round改为使用。

> Z=5
> round(367.8/Z)*Z
[1] 370
> round(367.2/Z)*Z
[1] 365
Run Code Online (Sandbox Code Playgroud)