Reputation: 11
I am working on a bar graph that shows counts of cats and dogs that differ across countries. Cats and dogs are levels stored in different factors/ variables. I want to plot the bars for each animal count on top of the other (i.e. 2 layers), and then I want to order the bars from the tallest (i.e. highest count) to lowest according to animal frequency per country.
Here is what I did:
Order the data table according to animal counts per country
plot <- within(plot, country <- factor(country,
levels=names(sort(table(country), decreasing=TRUE))))
Plot the graph
gg <- ggplot(data = plot, aes(x=country))
Add bar for dogs
dogs <- gg +
geom_bar(data = plot[plot$animal1 == 'dog',], #select dogs from animal1 variable
stat="count")
If I do that, I get this (with one geom_bar
):
So far, so good. Next, I add the second geom_bar for the cats:
dogs_cats <- gg +
geom_bar(data = plot[plot$animal1 == 'dog',], #select dogs from animal1 variable
stat="count") +
geom_bar(data = plot[plot$animal2 == 'cat',], #select cats from animal2 variable
stat="count")
Now the order is changed and off-key (after the second geom_bar
):
How can I maintain the order of the bars to follow the initial geom_bar
?
Many thanks!
Upvotes: 1
Views: 5203
Reputation: 6796
Hoom, I did like your code but the order of bars didn't change. Perhaps you made a simple mistake somewhere.
library(ggplot2)
# make a sample data
set.seed(1); d <- data.frame(animal1 = sample(c("dog", "other"), replace=T, 10000, prob=c(0.7,0.3)),
animal2 = sample(c("cat", "other"), replace=T, 10000, prob=c(0.3,0.7)),
country = sample(LETTERS[1:15], replace=T, 10000, prob=runif(15,0,1)))
levels(d$country) # [1] "A" "B" "C" "D" ...
plot <- within(d, country <- factor(country, levels=names(sort(table(country), decreasing=TRUE))))
levels(plot$country) # [1] "N" "O" "L" "F" ...
gg <- ggplot(data = plot, aes(x=country))
dogs <- gg + geom_bar(data = plot[plot$animal1 == "dog",], stat="count", fill="darkblue")
dogs_cats <- gg +
geom_bar(data = plot[plot$animal1 == "dog",], stat="count", fill="darkblue") +
geom_bar(data = plot[plot$animal2 == "cat",], stat="count", fill="blue")
print(dogs)
print(dogs_cats) # I made below img using library(grid) to form two graphs.
Upvotes: 0
Reputation: 3948
I suggest you to use merge
to create a new data frame:
1.Sum up (ddply
and melt
)
require(plyr) #ddply
require(reshape2) # melt
df = ddply(plot, "country", summarize, dogs = sum(animal1 == "dog"),
cats = sum(animal2 == "cat"))
dogs_and_cats = melt(df, id = "country")
You might have a new data frame with 3 columns:
2.Plot
ggplot(dogs_and_cats , aes(x = reorder(country, -value), y = value, fill = variable)) +
geom_bar(stat = "identity", position = "dodge")
3.Example:
Here is an example with the diamonds
dataset, without a reproducible example:
df = ddply(diamonds, "cut", summarize, J = sum(color == "J"),
D = sum(color == "D"))
plot = melt(df, id = "cut")
ggplot(plot, aes(x = reorder(cut, -value), y = value, fill = variable)) +
geom_bar(stat = "identity", position = "dodge")
Upvotes: 2