Here is an example data.frame which has 30 unique samples (ID 1 to 30), and each sample has three measurements (at three different thresholds ('G1' column); 5e-03, 5e-05, 5e-08). Each of the 90 observations has a p-value (P column). Finally, each of the thirty samples can belong to one of ten different categories ('G2') [sorry for all the numeric variables!]
# example data.frame
df <- data.frame(
'ID' = as.character(unlist(lapply(seq(1:30), function(x) rep(x,3)))),
'P' = runif(n = 90, min = 0, max = 1),
'G1' = as.character(c('5e-03','5e-05','5e-08')),
'G2' = as.character(unlist(lapply(sample(1:10, size = 30, replace = T), function(x) rep(x,3))))
)
I can generate a nice bar plot using this command;
ggplot(df, aes(x = interaction(ID,G2), y = P, fill = G2)) +
geom_bar(stat = 'identity') +
coord_flip() +
facet_grid(. ~ G1)
which looks like this:
Plot 1: image with one facet, and 'G2' visualised using colour
However, what I would really like to do is have two facets; 'G1' on the columns (as it currently is) and, instead of using bar colour to demarcate the 'G2' variable, I would like a second horizontal facet on G2. This is what I have tried:
ggplot(df, aes(x = interaction(ID,G2), y = P, fill = G2)) +
geom_bar(stat = 'identity') +
coord_flip() +
facet_grid(G2 ~ G1)
and it is not right. When I facet on G2, it is plotting all samples in each facet. This is ugly because each sample can only belong to one G2 category. How do I generate the second facet where only bars that belong to that group are plotted? I have tried adjusting the 'drop', 'scale' and 'space' variables in facet_grid, but it does not improve things.
This is what I am looking for - I have manually drawn rectangles over the parts of the plot that should be in the facet. It is essentially the same as Plot 1, except the bars are split into a G2 facet.
First note that since you are facetting with G2 and G1, you don't need the x=interaction(ID,G2)
anymore: x=ID
is enough.
By default, all facets of a plot share the same scales for their x and y axes. But you can change that with the scales
argument
ggplot(df, aes(x = ID, y = P, fill = G2)) +
geom_bar(stat = 'identity') +
facet_grid(G1 ~ G2, scales="free_x")
Note that I swapped G1 and G2 in the definition of the grid. I don't think it is possible to make it work with coord_flip()
though.