Home > Net >  R: Creating histogram bins to represent gaps in data
R: Creating histogram bins to represent gaps in data

Time:05-25

Is there a way to create bins that represent "artificial" gaps in a range of data using "case_when"? The script I wrote works somewhat, but I can't get it to plot my specified gaps in the data. My attempts are getting ignored:

My data:

> table(df$den)

                0 0.333333333333333 0.666666666666667                 1  1.33333333333333 
              507               155                77                43                18 
 1.66666666666667                 2  2.33333333333333                 3  3.33333333333333 
                7                 5                 8                 3                 1 
                4  4.33333333333333  5.66666666666667  8.33333333333333 
                1                 1                 2                 1 

Generate bins:

df = df %>% mutate(
  bins = case_when(
    den == 0 ~ "0",
    den <= 1 ~ "0 - 1",
    den <= 2 ~ "1 - 2",
    den <= 3 ~ "2 - 3",
    den <= 4 ~ "3 - 4",
    den <= 5 ~ "4 - 5",
    den <= 6 ~ "5 - 6",
    den <= 8 ~ "...",
    TRUE ~ "8.0 " 
  )
)

But the gaps get ignored:

> bins <- as.data.frame(table(df$bins))
> bins
   Var1 Freq
1     0  507
2 0 - 1  275
3 1 - 2   30
4 2 - 3   11
5 3 - 4    2
6 4 - 5    1
7 5 - 6    2
8  8.0     1

I had hoped to achieve something like this, but the "case_when" function won't create it:

>bins
       Var1 Freq
    1     0  507
    2 0 - 1  275
    3 1 - 2   30
    4 2 - 3   11
    5 3 - 4    2
    6 4 - 5    1
    7 5 - 6    2
    8 "..."    NA
    9  8.0     1

other methods don't work either and are a pain to create:

df$bins <- cut(df$den, c(0, seq(0.001, 9, 1)), right = FALSE,
                labels=c("0", "0.001 - 1.001", "1.002 - 2.001", "2.002 - 3.001", 
                         "3.002 - 4.001", "4.002 - 5.001", "5.002 - 6.001", 
                         "...", "8.0 ")) 
    

ggplot:

  ggplot(bins, aes(x = Var1, y = Freq, fill = Var1))   
      geom_bar(stat = "identity", colour="black")   
      geom_text(aes(label = Freq), vjust = -0.5)  
      scale_fill_brewer(breaks = c("0", "0-1","1-2", "2-3","3-4", "4-5", "5-6", "...", "8 "))
  

CodePudding user response:

Does this help? I've assumed freq is the count of the numbers in each bin size.

library(tidyverse)

df <- tibble(den = c(
  0, 0.333333333333333, 0.666666666666667, 1,
  1.33333333333333, 507, 155, 77,
  43, 18, 1.66666666666667, 2, 2.33333333333333,
  3, 3.33333333333333, 7, 5, 8, 3, 1, 4, 3333,
  5.66666666666667, 8.33333333333333, 1, 1, 2, 1
)) 

df |>
  mutate(bin = cut(den, breaks = c(0:8, Inf), right = FALSE)) |>
  count(bin, name = "freq") |>
  add_row(bin = "...", freq = NA_integer_) |>
  mutate(bin = fct_relevel(bin, "...", after = 7)) |>
  ggplot(aes(bin, freq, fill = bin))  
  geom_bar(stat = "identity", colour = "black")  
  geom_text(aes(label = freq), vjust = -0.5)  
  scale_fill_brewer()
#> Warning: Removed 1 rows containing missing values (position_stack).
#> Warning: Removed 1 rows containing missing values (geom_text).

Created on 2022-05-24 by the reprex package (v2.0.1)

  • Related