Andrej
Andrej

Reputation: 3839

Dodged barplot with zero counts in ggplot2

Suppose we have the following toy data structure:

data <- structure(list(value = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L), class = structure(c(1L, 1L, 1L, 
2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("A", 
"B"), class = "factor")), .Names = c("value", "class"), class = "data.frame", row.names = c(NA, 
-16L))

In this data one grouping has the zero count (i.e., there are no counts for class B with value 3):

> library(dplyr)
> count(data, value, class)
Source: local data frame [5 x 3]
Groups: value [?]

  value  class     n
  <int> <fctr> <int>
1     1      A     3
2     1      B     3
3     2      A     4
4     2      B     2
5     3      A     4

Code below plots the barplot (with relative frequencies on the y axis), but I need to display empty space for the zero count. Instead, ggplot2 eliminates the bar with zero count. Any suggestion how to include zero counts?

ggplot(data, aes(value, fill = class)) +
geom_bar(aes(y = ..count../sapply(fill, FUN=function(x) sum(count[fill == x]))), position="dodge")

enter image description here

This question is related to similar questions (e.g., Don't drop zero count) in the past, but the proposed solutions don't work here.

Upvotes: 1

Views: 2307

Answers (1)

Roman Luštrik
Roman Luštrik

Reputation: 70643

This programmatic enough? I precalculate everything and plot it... Notice that table "counts" zero for factor combinations which have no data.

library(ggplot2)
xy <- table(data$class, data$value)
xy <- as.data.frame(xy)

xy$rel.freq <- xy$Freq / aggregate(Freq ~ Var1, FUN = sum, data = xy)$Freq

ggplot(xy, aes(x = Var2, y = rel.freq, fill = Var1)) +
  theme_bw() +
  scale_fill_brewer(palette = "Set1") +
  geom_bar(stat = "identity", position = "dodge")

enter image description here

Upvotes: 2

Related Questions