Format labels produced by cut() as percentages

后端 未结 6 1958
失恋的感觉
失恋的感觉 2021-02-05 10:21

I need to apply cut on a continuous variable to show it with a Brewer color scale in ggplot2, as in Setting breakpoints for data with scale_fill_brewer() function i

相关标签:
6条回答
  • 2021-02-05 10:28

    The new {santoku} package now offers a way to do this in the development version:

    library(santoku)
    
    set.seed(20200607)
    x <- runif(20)
    
    chop_evenly(x, 10, labels = lbl_intervals(fmt = percent))
    #>  [1] [33.13%, 42.11%) [60.08%, 69.06%) [69.06%, 78.04%) [69.06%, 78.04%)
    #>  [5] [87.02%, 96%]    [6.193%, 15.17%) [15.17%, 24.15%) [6.193%, 15.17%)
    #>  [9] [33.13%, 42.11%) [6.193%, 15.17%) [87.02%, 96%]    [51.1%, 60.08%) 
    #> [13] [42.11%, 51.1%)  [6.193%, 15.17%) [42.11%, 51.1%)  [6.193%, 15.17%)
    #> [17] [6.193%, 15.17%) [69.06%, 78.04%) [78.04%, 87.02%) [87.02%, 96%]   
    #> 9 Levels: [6.193%, 15.17%) [15.17%, 24.15%) ... [87.02%, 96%]
    tab_evenly(x, 10, labels = lbl_intervals(fmt = scales::label_percent(accuracy = 0.1)))
    #> x
    #>  [6.2%, 15.2%) [15.2%, 24.2%) [33.1%, 42.1%) [42.1%, 51.1%) [51.1%, 60.1%) 
    #>              6              1              2              2              1 
    #> [60.1%, 69.1%) [69.1%, 78.0%) [78.0%, 87.0%) [87.0%, 96.0%] 
    #>              1              3              1              3
    

    Created on 2020-06-09 by the reprex package (v0.3.0)

    0 讨论(0)
  • 2021-02-05 10:31

    My package cutr does very similar things to @krlmlr's function (that I didn't know up until now).

    cutf is just cut with a format_fun argument, and ... which is passed to format_fun, not cut as incut_format.

    smart_cut has more features and different defaults :

    devtools::install_github("moodymudskipper/cutr")
    library(cutr)
    
    x <- seq(0.1, 0.9, by = 0.2)
    breaks <- seq(0, 1, by = 0.25)
    
    cutf(x, breaks, format_fun = scales::percent)
    # [1] (0%,25%]   (25%,50%]  (25%,50%]  (50%,75%]  (75%,100%]
    # Levels: (0%,25%] (25%,50%] (50%,75%] (75%,100%]
    
    smart_cut(x, breaks, format_fun = scales::percent,simplify = F, closed = "right")
    # [1] [0%,25%]   (25%,50%]  (25%,50%]  (50%,75%]  (75%,100%]
    # Levels: [0%,25%] < (25%,50%] < (50%,75%] < (75%,100%]
    

    Hmisc::cut2 now also has a formatfun argument :

    library(Hmisc)
    Hmisc::cut2(x, breaks, formatfun = scales::percent)
    # [1] [0%,25%)   [25%,50%)  [50%,75%)  [50%,75%)  [75%,100%]
    # Levels: [0%,25%) [25%,50%) [50%,75%) [75%,100%]
    
    0 讨论(0)
  • 2021-02-05 10:35

    Use gsub with some regex after multiplying your original data by 100:

    gsub("([0-9.]+)","\\1%",levels(cut(x*100,breaks=10)))
     [1] "(0.449%,10.4%]" "(10.4%,20.3%]"  "(20.3%,30.2%]"  "(30.2%,40.2%]"  "(40.2%,50.1%]"  "(50.1%,60%]"    "(60%,69.9%]"    "(69.9%,79.9%]"  "(79.9%,89.8%]"  "(89.8%,99.7%]"
    
    0 讨论(0)
  • 2021-02-05 10:36

    Why not copy the code for cut.default and create your own version with modified levels? See this gist.

    Two lines were changed:

    Line 22: ch.br <- formatC(breaks, digits = dig, width = 1) changed to ch.br <- formatC(breaks*100, digits = dig, width = 1).

    Line 29: else "[", ch.br[-nb], ",", ch.br[-1L], if (right) changed to else "[", ch.br[-nb], "%, ", ch.br[-1L], "%", if (right)

    The rest is the same. And here it is in action:

    library(devtools)
    source_gist(4593967)
    
    set.seed(1)
    x <- runif(100)
    levels(cut2(x, breaks=10))
    #  [1] "(1.24%, 11%]"   "(11%, 20.9%]"   "(20.9%, 30.7%]" "(30.7%, 40.5%]" "(40.5%, 50.3%]"
    #  [6] "(50.3%, 60.1%]" "(60.1%, 69.9%]" "(69.9%, 79.7%]" "(79.7%, 89.5%]" "(89.5%, 99.3%]"
    
    0 讨论(0)
  • 2021-02-05 10:37

    A new answer to an oldish question.

    You could use the label argument to pass a function to format the labels. I will use gsubfn and scales::percent

    library(gsubfn)
    library(scales)
    pcut <- function(x) gsubfn('\\d\\.\\d+', function(x) percent(as.numeric(x)),xx)
    d <- data.frame(x=runif(100))
    
    ggplot(d,aes(x=x,y=seq_along(x))) + 
     geom_point(aes(colour = cut(x, breaks = 10))) + 
     scale_colour_brewer(name = 'x', palette = 'Spectral', label = pcut)
    

    enter image description here

    0 讨论(0)
  • 2021-02-05 10:41

    I have implemented cut_format() in version 0.2-3 of my kimisc package, version 0.3 is on CRAN now.

    # devtools::install_github("krlmlr/kimisc")
    x <- seq(0.1, 0.9, by = 0.2)
    
    breaks <- seq(0, 1, by = 0.25)
    
    cut(x, breaks)
    ## [1] (0,0.25]   (0.25,0.5] (0.25,0.5] (0.5,0.75] (0.75,1]  
    ## Levels: (0,0.25] (0.25,0.5] (0.5,0.75] (0.75,1]
    
    cut_format(x, breaks, format_fun = scales::percent)
    ## [1] (0%, 25%]   (25%, 50%]  (25%, 50%]  (50%, 75%]  (75%, 100%]
    ## Levels: (0%, 25%] (25%, 50%] (50%, 75%] (75%, 100%]
    

    It's still not perfect, passing the number of breaks (as in the original example) doesn't work yet.

    0 讨论(0)
提交回复
热议问题