Home > OS >  Can base:cut() consistently return decimals?
Can base:cut() consistently return decimals?

Time:03-07

Unfortunately cut() does not seem to return values with a given number of decimal places (dig.lab doesn't ensure there are trailing zeros), so I am left with "(2, 2.1]" when I want "(2.0, 2.1]".

I would like to correct this, replacing the first "2" with "2.0", and generally any integer x with "x." followed by a given number of zeros.

If absolutely necessary perhaps someone could suggest a regex for integer (without decimals) x, so that I could replace it myself.

Any help most welcome. Apologies if I am missing something obvious.

CodePudding user response:

You can create your own function with e.g. sprintf:

f <- function(fac, n){
  lapply(strsplit(levels(fac), ","), \(x) sprintf(paste0("%.",n,"f"), parse_number(x))) |>
    lapply(\(x) paste0("(", paste(x, collapse = ","), "]")) |>
    unlist()
}

cu <- cut(1:10, 3)
# [1] (0.991,4] (0.991,4] (0.991,4] (0.991,4] (4,7]     (4,7]     (4,7]     (7,10]    (7,10]   (7,10]   
# Levels: (0.991,4] (4,7] (7,10]

levels(cu) <- f(cu, 3)
# [1] (0.991,4.000]  (0.991,4.000]  (0.991,4.000]  (0.991,4.000]  (4.000,7.000]  (4.000,7.000]  (4.000,7.000]  (7.000,10.000] (7.000,10.000] (7.000,10.000]
# Levels: (0.991,4.000] (4.000,7.000] (7.000,10.000]

CodePudding user response:

You could use my santoku package:

library(santoku)

chop(rnorm(10), c(-1.55, 0, 1, 1.55), labels = lbl_intervals(fmt = "%.2f"))

 [1] [-1.75, -1.55) [0.00, 1.00)   [0.00, 1.00)   [0.00, 1.00)   [-1.75, -1.55)
 [6] [0.00, 1.00)   [1.00, 1.55)   [-1.55, 0.00)  [-1.55, 0.00)  [1.00, 1.55)  
Levels: [-1.75, -1.55) [-1.55, 0.00) [0.00, 1.00) [1.00, 1.55)

fmt is passed to sprintf. Or you can pass in a formatting function, e.g. scales::label_number(...).

  • Related