2
votes

Using mtcars, I am creating a bar graph for cyl and fill gear. There is no car with cyl==8 & gear==4. When plotted, I used position_dodge(preserve = "single") to preserve the width of bars. Then, using geom_text I am adding labels to bars.

library(ggplot)
library(dplyr)

df <- count(mtcars, cyl, gear)

ggplot(df, aes(x = factor(cyl), y = n, fill = factor(gear))) +
  geom_col(position = position_dodge(preserve = "single")) +
  geom_text(aes(label = n, y = n + .07), size = 5, vjust = 0, 
                position = position_dodge(width=.9))

Two problems come out:

  1. The text labels are off for the last group, that is cyl==8
  2. In the last group, there should be a gap between red and blue bars for the green color bar. Instead you see red and blue bars are side by side.

enter image description here

1

1 Answers

2
votes

This is where complete from tidyr can help by filling in those missing values. You also can use vjust entirely rather than adding to your y values, if you wish.

library(ggplot2)
library(dplyr)
library(tidyr)

df <- count(mtcars, cyl, gear) %>% 
  complete(cyl, gear, fill = list(n = 0))

ggplot(df, aes(x = factor(cyl), y = n, fill = factor(gear))) +
  geom_col(position = position_dodge()) +
  geom_text(aes(label = n, y = n), size = 5, vjust = -0.5, 
            position = position_dodge(width=.9))

Created on 2019-01-17 by the reprex package (v0.2.1)