2

So I have a column of values ranging from 10 to 100 and I want all of them to be rounded to the nearest 10. The trick is I want it to always round down. For example, 55 would become 50 not 60. I imagine floor would be implemented for this but when I tried floor, it only returned the same value unaltered.

x
10
15
20
27
30
34

etc...

What I want:

x
10
10
20
20
30
30

What I tried:

data$x <- floor(data$x)

This only gave me the exact same values.

Kardinol
  • 191
  • 1
  • 11

3 Answers3

7

Since floor(x) gets the smallest integer y not greater than x, you can divide all the values in x by ten, get the floor, then multiply back by ten; i.e., you can use floor(x/10) * 10

x <- c(10,
       15,
       20,
       27,
       30,
       34)
floor(x/10) * 10
# [1] 10 10 20 20 30 30
duckmayr
  • 16,303
  • 3
  • 35
  • 53
4

You do not need floor here check with %/%

v%/%10*10
[1] 10 10 20 20 30 30
BENY
  • 317,841
  • 20
  • 164
  • 234
  • 2
    Works just as well. On a microbenchmarked sample `%/%` is a bit slower than `floor` (well about 50% slower), but both operations are so fast that it's hard to imagine a case where this would be the bottleneck. I'd encourage users to choose whichever they feel is most readable. – Gregor Thomas Jan 09 '19 at 19:23
  • @Gregor thank you for timing ! :-) – BENY Jan 09 '19 at 19:28
3

I'm late to the party on this, but I do have a similar solution which seems to run pretty fast. It is similar to the other options, but uses the trunc function.

x<- c(10, 15, 20, 27, 30, 34)
trunc(x / 10) * 10
#> [1] 10 10 20 20 30 30
identical(x %/% 10 * 10, floor(x/10) * 10)
#> [1] TRUE
identical(trunc(x / 10) * 10, floor(x/10) * 10)
#> [1] TRUE

Created on 2019-01-09 by the reprex package (v0.2.1)

I have inflated the size of the x vector and run all three with microbenchmark. The trunc method is fastest on this data.

set.seed(42)
x <- sample(x, size = 10000000, replace = TRUE)

library(microbenchmark)
microbenchmark(trunc(x / 10) * 10,
               floor(x / 10) * 10, 
               x%/%10*10)
#> Unit: milliseconds
#>              expr       min        lq      mean    median        uq
#>  trunc(x/10) * 10  55.89856  58.57783  66.08508  65.62727  71.74459
#>  floor(x/10) * 10  95.50139  99.18817 108.17770 108.10694 113.86548
#>       x%/%10 * 10 143.65839 150.77401 157.42086 158.56745 161.84987
#>        max neval
#>   95.49897   100
#>  147.47947   100
#>  188.56060   100

Created on 2019-01-09 by the reprex package (v0.2.1)

Nick Criswell
  • 1,733
  • 2
  • 16
  • 32