I would like to make a bar chart for a column with differently colored bars using ggplot.
library(ggplot2)
set.seed(123)
df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))
ggplot(df_a, aes(A1)) +
geom_bar(fill = c("green", "blue", "red", "yellow", "black")) +
scale_x_discrete(drop = FALSE)
That works fine: However, in such a small sample I cannot expect that all possible numbers are present. Here is an example, where this is the case:
set.seed(321)
df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))
Using the ggplot from before...
ggplot(df_a, aes(A1)) +
geom_bar(fill = c("green", "blue", "red", "yellow", "black")) +
scale_x_discrete(drop = FALSE)
...throws an error:
Error: Aesthetics must be either length 1 or the same as the data (3): fill
It seems, that a vector with exactly 3 colors is expected, as there are 3 bars to fill?
Why is that?
Is there a way to fill without checking the numbers first?
And forcing a predefined number of bars (even when empty)?
Edit:
A solution was suggested by AndS.
set.seed(321)
df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))
ggplot(df_a, aes(A1)) +
geom_bar(aes(fill = as.factor(A1))) +
scale_x_discrete(drop = FALSE)
In this case that would result in 4 bars (including 1 empty bar).
However, to get all 5 bars (including missing bars), one has to label the data:
set.seed(321)
df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))
df_a[[1]] <- ordered(df_a[[1]], levels = c(0:4), labels = c(0, 1, 2, 3, 4))
ggplot(df_a, aes(A1)) +
geom_bar(aes(fill = as.factor(A1))) +
scale_x_discrete(drop = FALSE)
Is there a way to avoid this? Like including the sampeling parameters to get the number of possible columns?
Number of required bars:
c_a <- c(0, 1, 2, 3, 4)
df_a <- data.frame(A1 = sample(c_a, 10, replace = TRUE))
length(c_a)
edit2: I found a solution that works for me:
set.seed(321)
c_a <- c(0, 1, 2, 3, 4)
df_a <- data.frame(A1 = sample(c_a, 10, replace = TRUE))
df_a[[1]] <- ordered(df_a[[1]], levels = c_a, labels = as.character(c_a))
ggplot(df_a, aes(A1)) +
geom_bar(aes(fill = as.factor(A1))) +
scale_x_discrete(drop = FALSE)