Home > Blockchain >  Percent stacked barchart: from Excel to ggplot2 in R
Percent stacked barchart: from Excel to ggplot2 in R

Time:11-21

My question is pretty simple. I'm trying to create a percent stacked barchart in ggplot2. I know exactly how I want it to be like because I created the same chart in Excel already, but I don't know how to obtain the same graph in R.

My issue is that the "fill" in my code corresponds to two sets of data: my x axis are nest box numbers, my y axis is a percentage (0%-100%), and the filling should be divided into males and females (e.g., in nest box number 5(b) there were 3 parasites, 2 females and 1 male, so the column should be divided into 67% FF and 33% MM).

This is my dataset:

> dput(broods_2020)
structure(list(`Age.(days)` = c("7-10 days", "15-20 days", "5-7 
days", 
"5-7 days", "5-7 days", "15-20 days", "6-8 days", "5-7 days", 
"13-15 days", "10-12 days", "7-10 days", "8-10 days", "5-7 days", 
"8-10 days", "20-25 days", "7-10 days", "8-10 days", "10-12 days", 
"15-20 days", "15-20 days", "10-12 days", "12-15 days"), `Nest- 
box.number.(x.brood)` = c(" 5 (a)", 
"5 (b)", "7", "10", "11 (a)", "12", "27", "31", "37 (a)", "40", 
"41", "200", "202", "205", "1 west", "5 west", "A3", "B7", "B8", 
"B11", "C18", "C21"), `N.(Carnus)` = c(4, 3, 13, 36, 10, 8, 8, 
17, 6, 3, 13, 8, 8, 9, 5, 10, 22, 28, 8, 8, 1, 3), MM = c(2, 
1, 5, 13, 5, 3, 2, 8, 2, 2, 5, 4, 3, 4, 3, 5, 10, 9, 1, 3, 1, 
1), FF = c(2, 2, 8, 23, 5, 5, 6, 9, 4, 1, 8, 4, 5, 5, 2, 5, 12, 
19, 7, 5, 0, 2)), row.names = c(NA, 22L), class = "data.frame")

This is my code:

ggplot(broods_2020, aes(x=broods_2020$"Nest-box.number.(x.brood)",y=broods_2020$"MM",broods_2020$"FF",fill=broods_2020$"N.(Carnus)",))   geom_col()  
  geom_bar(position="fill", stat="identity")  
  geom_bar(fill="#290DFB","#FF0000")  
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) 
 
  xlab("Nest box")   ylab("Collected Carnus hemapterus (%)")  
  ggtitle("2020 - PARASITE SEX RATIO (per brood)")  
  theme(axis.line.x = element_line(colour = 'black', size=0.5, 
linetype='solid'),
        axis.line.y = element_line(colour = 'black', size=0.5, 
linetype='solid'))  
  theme(title = element_text(face="plain", size = 12))  
  theme(plot.title = element_text(hjust = 0.5, vjust =2))  
  theme(axis.text.x = element_text(angle = 45, hjust=1))  
  theme(panel.background = element_blank()) 

Is there an issue in my dataset? How do I create this chart?

CodePudding user response:

Is this closer to what you're looking for?

If involves a few steps:

  • pivot_wider puts sex as one variable and n as another - this is what allows you to set a colour to represent each sex
  • n is passed as the y value to aes and sex as the fill value
  • geom_col(position = "fill") then fills the bar up to 100% for each x value (Nest-box.number.(x.brood))
  • You only need one geom_ layer for this - geom_bars are not needed
  • Setting the fill colours to match MM and FF is done in scale_fill_manual(values = ...)
library(ggplot2)
library(tidyr)


broods_2020 |>
  pivot_longer(c(MM, FF), names_to = "sex", values_to = "n") |>
  ggplot(aes(x = `Nest-box.number.(x.brood)`, y = n, fill = sex))   
  geom_col(position = "fill")  
  scale_fill_manual("Sex", values = c("MM" = "#290DFB", "FF" = "#FF0000"))  
  scale_y_continuous("Percent", labels = scales::percent_format(accuracy = 1))  
  xlab("Nest box")   ylab("Collected Carnus hemapterus (%)")  
  ggtitle("2020 - PARASITE SEX RATIO (per brood)")  
  theme(
    axis.line.x = element_line(
      colour = 'black',
      size = 0.5,
      linetype = 'solid'
    ),
    axis.line.y = element_line(
      colour = 'black',
      size = 0.5,
      linetype = 'solid'
    )
  )  
  theme(title = element_text(face = "plain", size = 12))  
  theme(plot.title = element_text(hjust = 0.5, vjust = 2))  
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  
  theme(panel.background = element_blank()) 

  • Related