Round ANY number Up/Down to ANY interval
You can easily round numbers to a specific interval using the modulo operator %%
.
The function:
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)
}
}
}
Examples:
> 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
How it works:
The modulo operator %%
determines the remainder of dividing the first number by the 2nd. Adding or subtracting this interval to your number of interest can essentially 'round' the number to an interval of your choosing.
> 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
Update:
The convenient 2-argument version:
rounder <- function(x,y) {
if(y >= 0) { x + (y - x %% y)}
else { x - (x %% abs(y))}
}
Positive y
values roundUp
, while negative y
values roundDown
:
# rounder(7, -4.5) = 4.5, while rounder(7, 4.5) = 9.
Or....
Function that automatically rounds UP or DOWN based on standard rounding rules:
Round <- function(x,y) {
if((y - x %% y) <= x %% y) { x + (y - x %% y)}
else { x - (x %% y)}
}
Automatically rounds up if the x
value is >
halfway between subsequent instances of the rounding value 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