Aleya Marzuki
Aleya Marzuki

Reputation: 71

ggplot2 is not ordering bars alphabetically when it should be doing so?

I'm trying to create a bar chart based on the data below. There are two independent variables, namely Last Win (factors: Rewarded, Unrewarded) and Last Transition (Common, Rare)

#make data and put into table
library(ggplot2)
values_MB <- matrix (c(0.75,0.4, 0.4, 0.75),ncol = 1)
lastWin <- matrix (c("Rewarded","Rewarded","Unrewarded","Unrewarded"),ncol = 1)
lastTransition <- matrix (c("Common","Rare","Common","Rare"),ncol = 1)

MB_table <- cbind(lastWin, lastTransition,values_MB)
colnames(MB_table) <- c('lastWin', 'lastTransition', 'meanStay')

MB_table <- as.data.frame(MB_table)

## plot data ##
 ggplot(MB_table, aes(x = lastWin, fill = lastTransition, y = meanStay)) +
  geom_bar(colour = "black", stat = "identity", position = position_dodge(width = .9)) +
  coord_cartesian(ylim = c(.5, 2)) +
  ylab("p(First-Stage Stays)") +
  xlab("Previous Reward") +
  ggtitle("Model-Free")+
  theme(text = element_text(size=15))+
  scale_fill_manual(values = c("#00AFBB", "#E7B800"), name = "Transition Type", labels = c("Common", "Rare")) +
  theme ( text = element_text (family = "sans", color = "grey20"),
          panel.background = element_rect(fill = "white"),
          axis.line = element_line(linetype = "solid"))

Ideally I would like the 'Common' bars to always be first, followed by Rare bars, at each level of lastWin but this isn't happening (see image below). I'm wondering why this is as I'd have thought ggplot2 would have ordered the bars alphabetically? Is there any way I can rectify this? Thank you!

enter image description here

Upvotes: 2

Views: 92

Answers (3)

FrsLry
FrsLry

Reputation: 417

You could just use:

MB_table$lastTransition <- as.factor(MB_table$lastTransition)

R didn't know that lastTransition is a factor

Upvotes: 0

neilfws
neilfws

Reputation: 33812

The problem here lies in the way you created the data frame. By using matrices, which cannot contain mixed data types, you have forced everything including the values of meanStay, to be of type character.

str(MB_table)
'data.frame':   4 obs. of  3 variables:
 $ lastWin       : chr  "Rewarded" "Rewarded" "Unrewarded" "Unrewarded"
 $ lastTransition: chr  "Common" "Rare" "Common" "Rare"
 $ meanStay      : chr  "0.75" "0.4" "0.4" "0.75"

If you simply use the data.frame command instead, like this:

MB_table <- data.frame(lastWin = c("Rewarded", "Rewarded", "Unrewarded", "Unrewarded"),
                       lastTransition = c("Common", "Rare", "Common", "Rare"),
                       meanStay = c(0.75, 0.4, 0.4, 0.75))

str(MB_table)
'data.frame':   4 obs. of  3 variables:
 $ lastWin       : chr  "Rewarded" "Rewarded" "Unrewarded" "Unrewarded"
 $ lastTransition: chr  "Common" "Rare" "Common" "Rare"
 $ meanStay      : num  0.75 0.4 0.4 0.75

then meanStay is numeric and everything works as expected. Here is a much simplified version of your ggplot:

MB_table %>% 
  ggplot(aes(lastWin, meanStay)) + 
  geom_col(aes(fill = lastTransition), 
           position = position_dodge())

enter image description here

I see these convoluted ways of making data frames in a lot of Stack Overflow questions. They can cause issues - just use data.frame.

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389325

Try :

library(ggplot2)

values_MB <- c(0.75,0.4, 0.4, 0.75)
lastWin <- c("Rewarded","Rewarded","Unrewarded","Unrewarded")
lastTransition <- c("Common","Rare","Common","Rare")
MB_table <- data.frame(lastWin, lastTransition, values_MB)
colnames(MB_table) <- c('lastWin', 'lastTransition', 'meanStay')

ggplot(MB_table, aes(x = lastWin, fill = lastTransition, y = meanStay)) +
  geom_bar(colour = "black", stat = "identity", position = position_dodge(width = .9)) + 
  ylab("p(First-Stage Stays)") +
  xlab("Previous Reward") +
  ggtitle("Model-Free") + 
  theme(text = element_text(size=15)) + 
  scale_fill_manual(values = c("Common" = "#00AFBB", "Rare" = "#E7B800"), 
                    name = "Transition Type", 
                    breaks = c("Common", "Rare"),
                    labels = c("Common", "Rare")) + 
  theme ( text = element_text (family = "sans", color = "grey20"),
          panel.background = element_rect(fill = "white"),
          axis.line = element_line(linetype = "solid"))

enter image description here

Upvotes: 2

Related Questions