问题
I am trying to create a barplot where for each category, two bars are plotted (side by side): one is for the "total", the other is stacked by subgroups. For example, in the following data frame, 'names' will be shown on x-axis. For each category in 'names', one bar will represent the value of 'total', the other will be a stacked bar representing values from 'aaa', 'bbb' and 'ccc'. I managed to get a 'back-to-back' plot but I don't know how to apply the 'dodge' position to this case to make the bars side-by-side.
df = data.frame(names = rep(LETTERS[1:3], each=4),
num = c(rep(c("aaa","bbb","ccc","total"), 3)),
values = c(1,2,3,7,2,2,5,10,3,4,2,9)))
p = ggplot(df, aes(x=factor(names))) +
geom_bar(data=subset(df,num=="total"), aes(y=values), stat="identity",width=.5) +
geom_bar(data=subset(df,num!="total"), aes(y=-values,fill=factor(num)), stat="identity",width=.5)
print(p)
回答1:
You can use facets. It seems you cannot stack and dodge at the same time (see related posts below). You can add another factor to your data for the x variable and facet on your names variable to come up with something like this:
Edit: Adjusted width of bars to have bars touching as per comments. See here: Remove space between bars ggplot2.
library(ggplot2)
p <- ggplot(data = df, aes(x = place, y = values, colour = num, fill = num))
p <- p + geom_bar(stat = "identity", width = 1, position = "stack")
p <- p + facet_grid(. ~ names)
p

It looks like you can adjust the margins of the facets to make the ABC groups look closer together if you're interested. For some examples, see these related posts:
ggplot2 - bar plot with both stack and dodge
ggplot2 geom_bar position = "dodge" does not dodge
Plotting a stacked bar plot?
Edited data with added "place" factor:
df <- structure(list(names = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 3L), .Label = c("A", "B", "C"), class = "factor"),
num = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L,
3L, 4L), .Label = c("aaa", "bbb", "ccc", "total"), class = "factor"),
values = c(1, 2, 3, 7, 2, 2, 5, 10, 3, 4, 2, 9), position = structure(c(1L,
1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L), .Label = c("nums",
"total"), class = "factor")), .Names = c("names", "num",
"values", "place"), row.names = c(NA, -12L), class = "data.frame")
回答2:
You can also increase the width of the bars to better fit the figure. Try this:
p = ggplot(df, aes(x=factor(names)), ) +
geom_bar(width=0.75,data=subset(df,num=="total"), aes(y=values), stat="identity",width=.5) +
geom_bar( width=0.75, data=subset(df,num!="total"), aes(y=-values,fill=factor(num)), stat="identity",width=.5)
print(p)

EDIT:
I think I misunderstood your question. Do you want the bars within one name to be side by side?
来源:https://stackoverflow.com/questions/30021410/ggplot2-side-by-side-barplot-with-one-bar-stacked-and-the-other-not