Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

R ggplot2 create a pyramid plot

Based on the code below I am trying to create a pyramid plot by following the 3rd answer to this question:

Simpler population pyramid in ggplot2

However, the code returns a stacked column plot instead of a pyramid plot with one gender on the left-hand side of the x-axis.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How can I fix this?

Data + code:

library(tidyverse)
library(janitor)
library(lemon)

pop = structure(list(age_group = c("<  5 years", "5 - 9", "10 - 14", 
"15  -  19", "20  -  24", "25  -  29", "30  -  34", "35  -  44", 
"45  -  54", "55  -  64", "65  -  74", "75  -  84", "85 +"), 
    males = c(6, 6, 7, 6, 7, 7, 8, 17, 15, 11, 6, 3, 1), females = c(6, 
    5, 6, 6, 6, 7, 7, 16, 15, 12, 7, 4, 2)), row.names = c(NA, 
-13L), spec = structure(list(cols = list(`AGE GROUP` = structure(list(), class = c("collector_character", 
"collector")), MALES = structure(list(), class = c("collector_double", 
"collector")), FEMALES = structure(list(), class = c("collector_double", 
"collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), delim = ","), class = "col_spec"), problems = <pointer: 0x0000029a145331e0>, class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"))

    # Draw a pyramid plot
    
    pop_df = pop %>% select(age_group,
                            males,
                            females) %>% 
                     gather(key = Type, value = Value, -c(age_group))
    
    
    ggplot(data = pop_df, 
           mapping = aes(x = ifelse(test = Type == "male", yes = -Value, no = Value), 
                         y = age_group, fill = Type)) +
      geom_col() +
      scale_x_symmetric(labels = abs) +
      labs(x = "Population")

Current output:

enter image description here

>Solution :

You could make one gender negative to create a pyramid plot and use two geom_bar, one per gender like this:

library(tidyverse)
library(janitor)
library(lemon)
pop = structure(list(age_group = c("<  5 years", "5 - 9", "10 - 14", 
                                   "15  -  19", "20  -  24", "25  -  29", "30  -  34", "35  -  44", 
                                   "45  -  54", "55  -  64", "65  -  74", "75  -  84", "85 +"), 
                     males = c(6, 6, 7, 6, 7, 7, 8, 17, 15, 11, 6, 3, 1), females = c(6, 
                                                                                      5, 6, 6, 6, 7, 7, 16, 15, 12, 7, 4, 2)), row.names = c(NA, 
                                                                                                                                             -13L), spec = structure(list(cols = list(`AGE GROUP` = structure(list(), class = c("collector_character", 
                                                                                                                                                                                                                                "collector")), MALES = structure(list(), class = c("collector_double", 
                                                                                                                                                                                                                                                                                   "collector")), FEMALES = structure(list(), class = c("collector_double", 
                                                                                                                                                                                                                                                                                                                                        "collector"))), default = structure(list(), class = c("collector_guess", 
                                                                                                                                                                                                                                                                                                                                                                                              "collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    "tbl_df", "tbl", "data.frame"))

# Draw a pyramid plot

pop_df = pop %>% 
  dplyr::select(age_group,males,females) %>% 
  gather(key = Type, value = Value, -c(age_group))

# Make male values negative
pop_df$Value <- ifelse(pop_df$Type == "males", -1*pop_df$Value, pop_df$Value)

ggplot(pop_df, aes(x = age_group, y = Value, fill = Type)) +
  geom_bar(data = subset(pop_df, Type == "females"), stat = "identity") + 
  geom_bar(data = subset(pop_df, Type == "males"), stat = "identity") + 
  scale_y_continuous(labels = abs) +
  labs(x = "Age group", y = "Value", fill = "Gender") +
  coord_flip() 

Created on 2022-07-27 by the reprex package (v2.0.1)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading