Home > Net >  Rearrange order of fields used with geom_col/geom_bar's aesthetic fill
Rearrange order of fields used with geom_col/geom_bar's aesthetic fill

Time:08-18

The data:

group  attendance percent
      <chr>  <chr>        <dbl>
    1 group1 never           72
    2 group1 infrequent      24
    3 group1 often            4
    4 group2 never           24
    5 group2 infrequent      43
    6 group2 often           33
    7 group3 never           10
    8 group3 infrequent      38
    9 group3 often           53

The goal:

I am wanting to display a bar chart (geom_col) with: X = percent, Y = groups and fill = attendance

The problem:

My issue is that despite the dataframe being ordered as shown above everyway I cut it my ggplot renders the fill colors as, 'never, often, infrequent' rather than 'never, infrequent, often.'

Here is the graph I get.

I'm going a little mad trying to figure out what I'm doing wrong and I am very new to R so would appreciate any pointers people might give me.

What I've tried:

  • I've come across an old aes argument 'order' but that seems to be no longer a part of ggplot2.
  • I've googled a tonne and found some stuff mentioning "stat = 'identity'" however that only seems to apply to geom_bar and geom_col apparently makes it redundant... either way if I change to geom_bar and use stat='identity' I get an identical graph.
  • I've tried rebuilding the dataframe in other ways to get the data in a different order.
  • I've tried creating different graphs to present the data in a similar way but none are as clear as what I want to create here and I know it should be possible.
  • I got really excited when I discovered there was a 'scale_fill_manual' option that I could apparently pass limits to but I couldn't get it to work... if that is the answer can someone explain how the syntax would be rendered in this case as I just didn't get it from the documentation
  • I tried playing around with limits and scale_x/scale_y but can't figure out how any of that would link to the fill option or what variation of that I might need - basically I was running out of new things to try at this point.

Which brings me to here... any help would be much appreciated - I'm very new to R and keen to learn so feel free to just point me in the right direction if I'm being a complete idiot and should be able to figure it out easily.

Thanks so much, I've done my best to make this as easy to follow as possible - it's my first post - but if I've done anything wrong please do let me know so I can adapt that for the future (I'm sure this won't be my only question.)

Reproducible code:

Here is some code that should give a reproducible example

library(tidyverse)
library(ggplot)

# create dataframe
group <- c('group1', 'group2','group3')
never <- c(72,24,10)
infrequent <- c(24,43,38)
often <- c(4,33,53)
df <- data.frame(group, never, infrequent, often)

# I then pivot the data to be more readable to for ggplot - sorry if this is a really round about way to do this (I'm still learning a lot!)
df <- df %>% pivot_longer(cols=c('never', 'infrequent', 'often'),
             names_to='attendance',
             values_to='percent')
order <- c('never', 'infrequent', 'often')

# render graph
ggplot(df, aes(x = percent, y=group, fill=attendance))  
geom_col(width=0.75, position = 'fill',  color='#000000')

CodePudding user response:

Try the following.

suppressPackageStartupMessages({
  library(dplyr)
  library(tidyr)
  library(ggplot2)
})

# create dataframe
group <- c('group1', 'group2','group3')
never <- c(72,24,10)
infrequent <- c(24,43,38)
often <- c(4,33,53)
df <- data.frame(group, never, infrequent, often)

order <- c('never', 'infrequent', 'often')

df %>% 
  pivot_longer(cols = c('never', 'infrequent', 'often'),
               names_to = 'attendance',
               values_to = 'percent') %>%
  mutate(attendance = factor(attendance, levels = order)) %>% 
  # render graph
  ggplot(aes(x = percent, y = group, fill = attendance))  
  geom_col(width=0.75, position = 'fill',  color = '#000000')  
  scale_x_continuous(labels = scales::percent)

Created on 2022-08-17 by the reprex package (v2.0.1)

  • Related