Abe Abe - 3 months ago 8
R Question

How to round up to the nearest 10 (or 100 or X)?

I am writing a function to plot data. I would like to specify a nice round number for the y-axis max that is greater than the max of the dataset.

Specifically, I would like a function

foo
that performs the following:

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


I have gotten as far as

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


For the case of nearest 10, 100, but this does not work for arbitrary X.

Is there a better way to do this in R?

Answer

If you just want to round up to the nearest power of 10, then just define:

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

This actually also works when x is a vector:

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

..but if you want to round to a "nice" number you first need to define what a "nice" number is. The following lets up define "nice" as a vector with nice base values from 1 to 10. The default is set to the even numbers plus 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]]]]
}

The above doesn't work when x is a vector - too late in the evening right now :)

> 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

[[EDIT]]

If the question is how to round to a specified nearest value (like 10 or 100), then James answer seems most appropriate. My version lets you to take any value and automatically round it to a reasonably "nice" value. Some other good choices of the "nice" vector above are: 1:10, c(1,5,10), seq(1, 10, 0.1)

If you have a range of values in your plot, for example [3996.225, 40001.893] then the automatic way should take into account both the size of the range and the magnitude of the numbers. And as noted by Hadley, the pretty() function might be what you want.