R: decimal ceiling

I want to define a very similar function to @42. Instead of having the floor function defined by how many decimal places you want, I want to define the number of sig figs:

floor_dec <- function(x, sigDig=1) {
  mostSig = ceiling(log10(abs(x)))
  floor(x*10^(sigDig-mostSig))*10^-(sigDig-mostSig)
}

> floor_dec(21.259, 4)
[1] 21.25
> floor_dec(21.259, 3)
[1] 21.2
> floor_dec(21.259, 2)
[1] 21
> floor_dec(21.259, 1)
[1] 20
> floor_dec(.259, 4)
[1] 0.259
> floor_dec(.259, 3)
[1] 0.259
> floor_dec(.259, 2)
[1] 0.25
> floor_dec(.259, 1)
[1] 0.2
> floor_dec(1.2, 0)
[1] 0
> floor_dec(23, -1)
[1] 0

Note that sigDif requires positive integers as input. Just like the prompter guesses, I find the position of the most significant digit, move the decimal place for the appropriate floor and then move the decimal place so that the input's most significant digit is the same as the output.


This answer does not have the problem commented in previous answer, though sadly is based on the unwanted answer in the OP:

customCeiling <- function(x, Decimals=1) {
  x2<-x*10^Decimals
  ceiling(x2)/10^Decimals
}

customFloor <- function(x, Decimals=1) {
  x2<-x*10^Decimals
  floor(x2)/10^Decimals
}

@42- answer in comment seems too useful to be just left in comment, hence this wiki-post.

You can create your own functions and adapt floor and ceiling fonctions, adding a level option to mimic the digits parameter of round function like this:

floor_dec <- function(x, level=1) round(x - 5*10^(-level-1), level)
ceiling_dec <- function(x, level=1) round(x + 5*10^(-level-1), level)

Examples:

# floor
floor_dec(1.259, 2)
[1] 1.25
floor_dec(1.9, 0)
[1] 1
floor_dec(29, -1)
[1] 20
floor_dec(1.251, 2)
[1] 1.25
floor_dec(1.2, 0)
[1] 1
floor_dec(23, -1)
[1] 20

# ceiling
ceiling_dec(1.259, 2)
[1] 1.26
ceiling_dec(1.9, 0)
[1] 2
ceiling_dec(29, -1)
[1] 30
ceiling_dec(1.251, 2)
[1] 1.26
ceiling_dec(1.2, 0)
[1] 2
ceiling_dec(23, -1)
[1] 30