codememo

가장 가까운 10(또는 100 또는 X)까지 반올림하는 방법은 무엇입니까?

tipmemo 2023. 6. 22. 21:53
반응형

가장 가까운 10(또는 100 또는 X)까지 반올림하는 방법은 무엇입니까?

저는 데이터를 플롯하기 위한 함수를 작성하고 있습니다.y축에 대한 적절한 반올림 수를 지정하고 싶습니다.max데이터 집합의 최대값보다 큽니다.

구체적으로, 저는 기능을 원합니다.foo다음을 수행합니다.

foo(4) == 5
foo(6.1) == 10 #maybe 7 would be better
foo(30.1) == 40
foo(100.1) == 110 

저는 멀리까지 갔습니다.

foo <- function(x) ceiling(max(x)/10)*10

가장 가까운 10으로 반올림하는 경우이지만 임의의 반올림 구간에서는 작동하지 않습니다.

R에서 이것을 하는 더 좋은 방법이 있습니까?

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

가장 가까운 10의 거듭제곱으로 반올림하려면 다음을 정의합니다.

roundUp <- function(x) 10^ceiling(log10(x))

이것은 x가 벡터일 때도 실제로 작동합니다.

> roundUp(c(0.0023, 3.99, 10, 1003))
[1] 1e-02 1e+01 1e+01 1e+04

..하지만 "숫자"로 반올림하려면 먼저 "숫자"가 무엇인지 정의해야 합니다.다음을 통해 "nice"를 1에서 10 사이의 nice 기본값을 가진 벡터로 정의할 수 있습니다.기본값은 짝수 더하기 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]]]]
}

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

[[편집]

문제가 지정된 가장 가까운 값(예: 10 또는 100)으로 반올림하는 방법이라면 James 답변이 가장 적합한 것 같습니다.내 버전을 사용하면 모든 값을 사용하여 적절한 "좋은" 값으로 자동 반올림할 수 있습니다.위의 "멋진" 벡터의 다른 좋은 선택은 다음과 같습니다.1:10, c(1,5,10), seq(1, 10, 0.1)

그림에 값의 범위가 있는 경우(예:[3996.225, 40001.893]그런 다음 자동 방법은 범위의 크기와 숫자의 크기를 모두 고려해야 합니다.그리고 해들리가 지적했듯이,pretty()기능이 당신이 원하는 것일 수 있습니다.

R의 반올림 함수는 음수인 경우 자릿수 매개 변수에 특별한 의미를 부여합니다.

반올림(x, 숫자 = 0)

음수 자릿수로 반올림은 10의 거듭제곱으로 반올림하는 것을 의미하므로, 예를 들어 반올림(x, 자릿수 = -2)은 가장 가까운 100으로 반올림합니다.

이것은 다음과 같은 기능이 당신이 요구하는 것과 상당히 가깝다는 것을 의미합니다.

foo <- function(x)
{
    round(x+5,-1)
}

출력은 다음과 같습니다.

foo(4)
[1] 10
foo(6.1)
[1] 10
foo(30.1)
[1] 40
foo(100.1)
[1] 110

음의 숫자를 추가하는 경우digits의 주장.round()R은 10, 100 등의 배수로 반올림합니다.

round(9, digits = -1) 
[1] 10    
round(89, digits = -1) 
[1] 90
round(89, digits = -2) 
[1] 100

어때요?

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

이는 다음을 제공합니다.

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

임의의 숫자를 임의의 간격으로 올림/아래로 올림

모듈로 연산자를 사용하여 숫자를 특정 구간으로 쉽게 반올림할 수 있습니다. %%.

기능:

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)
    }
  }
}

예:

> 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

작동 방식:

로 연산자 모듈자%%첫 번째 숫자를 두 번째 숫자로 나눈 나머지를 결정합니다.이 구간을 관심 구간에 더하거나 빼면 기본적으로 원하는 구간으로 숫자를 '올림'할 수 있습니다.

> 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

업데이트:

편리한 2-인수 버전:

rounder <- function(x,y) {
  if(y >= 0) { x + (y - x %% y)}
  else { x - (x %% abs(y))}
}

인 것yroundUpyroundDown:

 # rounder(7, -4.5) = 4.5, while rounder(7, 4.5) = 9.

아니면..

표준 반올림 규칙에 따라 자동으로 UP 또는 DOWN을 반올림하는 기능:

Round <- function(x,y) {
  if((y - x %% y) <= x %% y) { x + (y - x %% y)}
  else { x - (x %% y)}
}

다음과 같은 경우 자동으로 반올림됩니다.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

임의의 숫자(예: 10)의 배수로 반올림하는 것과 관련하여, 여기 제임스의 대답에 대한 간단한 대안이 있습니다.

반올림되는 모든 실수에 대해 작동합니다.from) 및 ()로 반올림한 실수 양의 숫자to):

> RoundUp <- function(from,to) ceiling(from/to)*to

예:

> 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

항상 가장 가까운 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

마찬가지로, 항상 반올림하려면 다음을 사용합니다.floor기능.단순히 가장 가까운 Z로 올림하거나 내림하려면 다음을 사용합니다.round대신.

> Z=5
> round(367.8/Z)*Z
[1] 370
> round(367.2/Z)*Z
[1] 365

나는 당신의 코드가 작은 수정에도 잘 작동한다고 생각합니다.

foo <- function(x, round=10) ceiling(max(x+10^-9)/round + 1/round)*round

그리고 다음과 같은 예제가 실행됩니다.

> foo(4, round=1) == 5
[1] TRUE
> foo(6.1) == 10            #maybe 7 would be better
[1] TRUE
> foo(6.1, round=1) == 7    # you got 7
[1] TRUE
> foo(30.1) == 40
[1] TRUE
> foo(100.1) == 110
[1] TRUE
> # ALL in one:
> foo(c(4, 6.1, 30.1, 100))
[1] 110
> foo(c(4, 6.1, 30.1, 100), round=10)
[1] 110
> foo(c(4, 6.1, 30.1, 100), round=2.3)
[1] 101.2

두 가지 방법으로 당신의 기능을 변경했습니다.

  • 두 번째 인수 추가(지정한 X에 대해)
  • 값이 되었습니다.=1e-09자유롭게 수정하세요!)max(x) 큰 ,

은 반올림한 것입니다.x가가 운 배 까 수 지 정 수의 가장 가까운 정수 y 때에y양의 값을 가지며 아래로 이동합니다.y음:

rom=\(x,y)x+(y-x%%y)%%y
rom(8.69,.1) # 8.7
rom(8.69,-.1) # 8.6
rom(8.69,.25) # 8.75
rom(8.69,-.25) # 8.5
rom(-8.69,.25) # -8.5

것은항다상같과은가가장배반다까니올됩림처럼 가장 가까운 합니다.round_anyplyr(https://github.com/hadley/plyr/blob/34188a04f0e33c4115304cbcf40e5b1c7b85fedf/R/round-any.r) :

rnm=\(x,y)round(x/y)*y
rnm(8.69,.25) # 8.75
plyr::round_any(8.69,.25) # 8.75

round_any또한 주어질 수 있습니다.ceiling항상 정리해야 하는 세 번째 주장으로 또는floor항상 반올림하기

plyr::round_any(8.51,.25,ceiling) # 8.75
plyr::round_any(8.69,.25,floor) # 8.5

몇 가지 경우를 고려한 Tommy 답변의 업그레이드 버전을 찾을 수 있습니다.

  • 하한 또는 상한 선택
  • 음수 값과 0 값을 고려합니다.
  • 함수가 작은 숫자와 큰 숫자를 다르게 반올림하기를 원하는 경우 두 개의 다른 좋은 척도.예: 4는 0으로 반올림하고 400은 400으로 반올림합니다.

코드 아래:

round.up.nice <- function(x, lower_bound = TRUE, nice_small=c(0,5,10), nice_big=c(1,2,3,4,5,6,7,8,9,10)) {
  if (abs(x) > 100) {
    nice = nice_big
  } else {
    nice = nice_small
  }
  if (lower_bound == TRUE) {
    if (x > 0) {
      return(10^floor(log10(x)) * nice[[max(which(x >= 10^floor(log10(x)) * nice))[[1]]]])
    } else if (x < 0) {
      return(- 10^floor(log10(-x)) * nice[[min(which(-x <= 10^floor(log10(-x)) * nice))[[1]]]])
    } else {
      return(0)
    }
  } else {
    if (x > 0) {
      return(10^floor(log10(x)) * nice[[min(which(x <= 10^floor(log10(x)) * nice))[[1]]]])
    } else if (x < 0) {
      return(- 10^floor(log10(-x)) * nice[[max(which(-x >= 10^floor(log10(-x)) * nice))[[1]]]])
    } else {
      return(0)
    }
  }
}

외부 라이브러리나 암호화된 기능을 사용하지 않고 사용해봤는데 작동합니다!

누군가에게 도움이 되길 바랍니다.

ceil <- function(val, multiple){
  div = val/multiple
  int_div = as.integer(div)
  return (int_div * multiple + ceiling(div - int_div) * multiple)
}

> ceil(2.1, 2.2)
[1] 2.2
> ceil(3, 2.2)
[1] 4.4
> ceil(5, 10)
[1] 10
> ceil(0, 10)
[1] 0

누락된 부분이 있을 수 있지만 다음과 같이 쉽지는 않습니다.

some_number = 789
1000 * round(some_number/1000, 0)

1000년대로 반올림한 것을 생산하는 것?

언급URL : https://stackoverflow.com/questions/6461209/how-to-round-up-to-the-nearest-10-or-100-or-x

반응형