Rob E.
Rob E.

Reputation: 194

ggplot is not correctly grouping bars when using position="dodge"

Going nuts. I have a melted dataframe that I am trying to display in a simple grouped barplot in ggplot2:

modality <- c("CLASS", "CLASS", "ONLINE", "ONLINE", "HYBRID", "HYBRID")
survey <- c("A Pre", "A Post", "B Pre", "B Post", "C Pre", "C Post")
score <- c(3.45, 4.15, 4.12, 4.34, 4.06, 4.57)
df = data.frame(modality, survey, score)

ggplot(df, aes(fill=modality, y=score, x=survey)) +
  geom_bar(position="dodge", stat="identity")

I expected the bars to be grouped by modality, but it produces this: Barplot with grouping error

I tried to set this up as closely as possible to the example from r-graph-gallery, which works just fine.

specie <- c(rep("sorgho" , 3) , rep("poacee" , 3) , rep("banana" , 3) , rep("triticum" , 3) )
condition <- rep(c("normal" , "stress" , "Nitrogen") , 4)
value <- abs(rnorm(12 , 0 , 15))
data <- data.frame(specie,condition,value)

ggplot(data, aes(fill=condition, y=value, x=specie)) + 
  geom_bar(position="dodge", stat="identity")

Result: Barplot with groups rendered correctly

I don't see a difference in the structure of the two dataframes, but I assume one exists. I would really love to know what I am missing here. Thanks!

Upvotes: 3

Views: 712

Answers (1)

akrun
akrun

Reputation: 887128

Each value is different in pre, post i.e. 'A pre', 'B pre' etc. and similarly, 'A post', 'B post' etc. If we make it to a common group by removing the prefix part leaving the 'pre/post' then it would give similar output as in the example showed

library(dplyr)
library(stringr)
library(ggplot2)
df %>% 
   mutate(survey = str_remove(survey, '\\D+\\s+')) %>% 
   ggplot(aes(fill = modality, y = score, x = survey)) +     
       geom_bar(position = "dodge", stat = "identity")

-output

enter image description here

Upvotes: 2

Related Questions