Home > Software engineering >  The total value alongside the percentage displayed on the top of Bar charts
The total value alongside the percentage displayed on the top of Bar charts

Time:03-05

my dataframe is here

data.frame(
  stringsAsFactors = FALSE,
           Subtype = c("OPC", "Hypopharynx", "Larynx"),
             alive = c(88, 22, 100),
              dead = c(12, 55, 17),
         uncertain = c(10, 2, 2)
)

Title of the dataframe is tata4.

When I enter this code, I get a good graph with percentages. can't embed the image for some reason!

tata4 %>% 
  gather(key = "status", value = value, -Subtype) %>% 
  group_by(Subtype) %>% 
  mutate(value = value / sum(value) * 100, status = factor(status, c("alive", "dead", "uncertain"))) %>% 
  ggplot(aes(y = value, x = Subtype, fill = status))   
  geom_col(width = .6, position = position_dodge(width = .6, preserve = "total"))    
  geom_text(aes(label = paste(round(value, 1), "%"), y = value   7,group = status), 
            position = position_dodge(width = .6, preserve = "total"),size=3,angle=90)  
  labs(y = "percentage", x = "Status")    
  scale_fill_manual(values = c("alive" = "tan2", "dead" = "red", "uncertain" = "green"),
                    aesthetics = c("color", "fill"))   
  theme(text = element_text(size = 15))   
  scale_y_continuous(labels = scales::label_percent(scale = 1, accuracy = 1),limits = c(0, 100))

What I'm trying to do is to get the absolute value as well the percentage displayed on the top of the graph. I'm trying to use the scales function as below, but the code below does not seem to work (Gives me strange values. What am I doing wrong? thanks

tata4 %>% 
  gather(key = "status", value = value, -Subtype) %>% 
  group_by(Subtype) %>% 
  mutate(perc = value / sum(value) * 100, status = factor(status, c("alive", "dead", "uncertain"))) %>%
  ggplot(aes(y = value, x = Subtype, fill = status))   
  geom_col(width = .6, position = position_dodge(width = .6, preserve = "total"))   
  geom_text(aes(Subtype,value   5,label = glue::glue("{value}({percent(perc)})")))  
  labs(y = "percentage", x = "Status")    
  scale_fill_manual(values = c("alive" = "tan2", "dead" = "red", "uncertain" = "green"),
                    aesthetics = c("color", "fill"))   
  theme(text = element_text(size = 15))  

CodePudding user response:

The "strange" labels you get come from your scales::percent(perc) use inside the glue function. This transforms a value that was already manually scaled to be % again by 100 (80 to 8000%). You can either manually define the labels, or pass a scale = 1 argument. Preparing the labels already in the dataframe:

df0 <-  tata4 %>% 
  gather(key = "status", value = value, -Subtype) %>% 
  group_by(Subtype) %>% 
  mutate(perc = value / sum(value) * 100, status = factor(status, c("alive", "dead", "uncertain")))

# this scales the percentage label twice:
df1 <- df0 %>% mutate(perc_label = glue::glue("{value}({percent(perc)})")) 

# Subtype     status    value  perc perc_label 
#<chr>       <fct>     <dbl> <dbl> <glue>     
#1 OPC         alive        88 80    88(8 000%)

# option 1: manually define % labels
df2 <-  df0 %>% mutate(perc_label = glue::glue("{value} ({round(perc, 1)}%)")) 

#Subtype     status    value  perc perc_label
#<chr>       <fct>     <dbl> <dbl> <glue>    
#1 OPC         alive        88 80    88 (80%) 

# option 2: use scale parameter
df3 <- df0 %>% mutate(perc_label = glue::glue("{value}({scales::percent(perc, scale=1)})"))

# Subtype     status    value  perc perc_label
# <chr>       <fct>     <dbl> <dbl> <glue>    
#1 OPC         alive        88 80    88(80.0%) 

For the plot, we in addition need to map perc to the y-axis instead of value (the calculated percentage is defined in different columns in both examples).

df2 %>%
  ggplot(aes(y = perc, x = Subtype, fill = status))   
  geom_col(width = .6, position = position_dodge(width = .6, preserve = "total"))   
  geom_text(aes(Subtype, perc   8, label = perc_label), 
            position = position_dodge(width = .6, preserve = "total"),size=3,angle=90)  
  labs(y = "percentage", x = "Status")    
  scale_fill_manual(values = c("alive" = "tan2", "dead" = "red", "uncertain" = "green"),
                    aesthetics = c("color", "fill"))   
  theme(text = element_text(size = 15))  
  coord_cartesian(ylim = c(0, 100))  
  scale_y_continuous(labels = label_percent(scale = 1))

enter image description here

  • Related