2

I would like to add specific items to the x-axis as empty bars in a bar plot

For example:

# load packages
library(reshape2)
library(tidyverse)
library(scales)


#get data
data(tips, package = "reshape2")

tips

# make plot
myplot <- ggplot(tips, aes(day, group = sex)) + 
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count") + 
  scale_y_continuous(labels=scales::percent) +
  ylab("relative frequencies") +
  facet_grid(~sex)

myplot

now I would like to add the missing week days, as empty bars:

missing_days <-c("Tue","Wed")

enter image description here

If possible, I would like to keetp the "tidy" long data format of tips (so that I can still use other variables in the aes command. What does the trick to add "empty" items to a long data format?

captcoma
  • 1,768
  • 13
  • 29
  • 1
    Do you want the bars to start on Friday? – Rui Barradas Jan 19 '20 at 20:59
  • Does this answer your question? [ggplot2 keep unused levels barplot](https://stackoverflow.com/questions/10834382/ggplot2-keep-unused-levels-barplot) – tjebo Jan 19 '20 at 21:39
  • @RuiBarradas-ReinstateMonic yes, that is fine. thank you. – captcoma Jan 19 '20 at 23:54
  • @Tjebo not fully, I did not know that I can simply add factors to generate empty bars, the question you mentioned only explans how to keep them, not how to generate them. – captcoma Jan 19 '20 at 23:54

2 Answers2

5

The following code will first get all weekdays and then plot the graph without dropping the unused levels.

tips$day <- as.character(tips$day)

days_levels <- weekdays(Sys.Date() + 1:7, abbreviate = TRUE)
fri <- grep("Fri", days_levels)
days_levels <- c(days_levels[fri:length(days_levels)], days_levels[1:(fri - 1)])
days_levels[days_levels == "Thu"] <- "Thur"
tips$day <- factor(tips$day, levels = days_levels)

# make plot
myplot <- ggplot(tips, aes(day, group = sex)) + 
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count") + 
  scale_y_continuous(labels=scales::percent) +
  scale_x_discrete(drop = FALSE) +
  ylab("relative frequencies") +
  facet_grid(~sex)

myplot

enter image description here

Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
2

You can simply add the days to your factor levels:

tips$day <- factor(tips$day, levels = c(attributes(tips$day)$levels, "Tues", "Wed"))

And add the following to ggplot:

scale_x_discrete(drop = FALSE)

Full code

# load packages
library(reshape2)
library(tidyverse)
library(scales)


# get data
data(tips, package = "reshape2")

tips

tips$day <- factor(tips$day, levels = c(attributes(tips$day)$levels, "Tues", "Wed"))

# make plot
myplot <- ggplot(tips, aes(day, group = sex)) + 
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count") + 
  scale_y_continuous(labels=scales::percent) +
  ylab("relative frequencies") +
  scale_x_discrete(drop = FALSE) +
  facet_grid(~sex)

myplot

Output:

enter image description here

Khaynes
  • 1,976
  • 2
  • 15
  • 27