D. Studer
D. Studer

Reputation: 1885

Sort bars according to y-value

I have a dataset with two variables:

Now I'd like to plot a stacked barplot: One bar for each year.

ggplot(aes(x = district, fill=type), data=dat) + geom_bar()

My problem is, that the bars should be in ascending order (of the total of each district). Like this:

  |
  |  x
  |  x
  |  x  x
n |  o  x  x
  |  o  o  o
  |  o  o  o  x
  |  o  o  o  o 
  _______________
     A  C  G  B …

Does anyone know how to do this?

Upvotes: 1

Views: 618

Answers (2)

Matt
Matt

Reputation: 7423

Here is a reprex for your data:

district <- sample(LETTERS, 1000, replace = TRUE)
xo <- c("x","o")
type <- sample(xo, 1000, replace = TRUE)

Here is your df. You need to create a count column that you can order your districts by.

library(tidyverse)

df <- as.data.frame(cbind(district, type)) %>%
  group_by(district) %>%
  mutate(count = n())

Within your aes argument, you can specify reorder district, by descending count:

ggplot(df, aes(x = reorder(district, -count), fill=type)) +
  geom_bar()

And if you don't want to alter your df by grouping or adding a count variable, you can do this:

df %>%
  group_by(district) %>%
  mutate(count = n()) %>%
  ggplot(aes(x = reorder(district, -count), fill=type)) +
  geom_bar()

Upvotes: 3

StupidWolf
StupidWolf

Reputation: 47008

If your data.frame is purely two columns with the levels, then do:

library(ggplot2)
set.seed(111)
df = data.frame(district=sample(LETTERS[1:4],100,replace=TRUE),
type=sample(c("x","o"),100,replace=TRUE))

head(df)

  district type
1        B    x
2        C    o
3        D    x
4        C    x
5        C    x
6        A    x

ggplot(df,aes(x=reorder(district,district,function(i)-length(i)),fill=type)) + 
geom_bar() + xlab("district")

enter image description here

Brief explanation, reorder() can be used to refactor one variable according to another, and it also allows for a function to be applied. In this situation, we just need to count the number of each level in district, so length() will work. The second district is just a dummy

Upvotes: 3

Related Questions