3

Possible Duplicate:
Order Bars in ggplot2 bar graph

I have a dataset and I would like to have a ggplot bar-plot depicting the proportions for one of the variables and sort or order the bars based on another variable. Here is an example of the dataset.

grouping,category,domain
6,W,ced0.11
1,none,ced1.1
2,none,ced1.1
3,Z,ced1.5
2,Z,ced1.7
3,Z,ced1.3
3,none,ced1.6
2,none,ced1.1
1,Z,ced1.1
4,none,ced0.8
4,W,ced0.6
4,W,ced0.6
2,Z,ced1.5
2,W,ced1.6
4,Y,ced0.16
3,Z,ced1.5
4,Y,ced0.15
4,W,ced0.15
4,Y,ced0.24
6,W,ced0.8
4,Y,ced0.4
4,none,ced0.19
4,W,ced0.5
4,W,ced0.10
4,W,ced0.9
4,W,ced0.3
1,Z,ced1.6
4,W,ced0.9
4,W,ced0.15
1,Z,ced1.1
4,Y,ced0.19
6,W,ced0.4
4,W,ced0.16
4,W,ced0.6
4,W,ced0.5
2,Z,ced1.7
4,W,ced0.9
4,Y,ced0.1
4,W,ced0.2
4,Y,ced0.21
2,W,ced0.3
4,Y,ced0.21
4,W,ced0.10
1,Z,ced1.2
4,Y,ced0.16
1,Z,ced1.2
1,Z,ced1.2
5,W,ced0.23
4,Y,ced0.1

and the code below for importing and display a bar chart.

library(ggplot2)
ex1.dta <- read.csv("../../Datasets/ex1.txt",sep=",",header=TRUE)

#sort the data frame
ex1.dta2 <- transform(ex1.dta,domain=reorder(domain,category))

ggplot(ex1.dta2,aes(domain,fill=category)) +
  geom_bar(position="fill") + 
  scale_y_continuous(name="Proportion") + 
  scale_x_discrete(name="domains") +
  scale_fill_manual(values=c("#841108","#16a4e9","#a4a42a","#eb96ed","grey"),name="category") + 
  theme_bw() +
  opts(
    axis.text.x=theme_text(angle=-90,hjust=0),
    axis.line = theme_segment(colour = "black"),
    panel.grid.major = theme_blank(),
    panel.grid.minor = theme_blank(),
    panel.border = theme_blank()) +
  geom_vline(xintercept = 0)

enter image description here

When I use the transform to order the data frame, I get warnings and no ordering/sorting is performed. What I really would like is to sort such that bars for each category are grouped together(and in a decreasing order) along the x-axis. ( all the brown bars together, light-blue together and in 'hierarchical way' and so forth.)

How can I achieve that? Do i need multiple ordering? any idea?

Community
  • 1
  • 1
eastafri
  • 2,186
  • 2
  • 23
  • 34
  • 1
    Have you read the documentation at `?reorder`? Specifically, what meaning do you expect there to be from _averaging_ subsets of values of `category`? – joran Sep 16 '12 at 19:25
  • Thanks joram. oh so the reorder usually expects a numeric variable. But then when you have the above case, what is the recommended approach? – eastafri Sep 16 '12 at 19:33
  • The facet_grid will not produce the desired results. It is also overly 'verbose' as more categories arise. I would just prefer a solution for sorting/reordering the bars in a single plot. – eastafri Sep 16 '12 at 20:15

1 Answers1

1

I'm not entirely sure what ordering you actually want, but you might try something like this:

ex1.dta2 <- transform(ex1.dta,domain=reorder(domain,category,FUN = function(x){ min(as.numeric(x)) }))

The result will depend on how the levels of category are arranged, so you should adjust that if this isn't the exact ordering you want. In this case, I get the following graph:

enter image description here

What's going on here is that factors are stored internally as integer codes and set of labels. So to reorder based on the factor category I simply passed an anonymous function that converts to the integer codes, and then selects the minimum.

joran
  • 169,992
  • 32
  • 429
  • 468
  • Thanks joran! However I expect the columns for ced0.10,ced0.11,ced0.2,ced0.23,ced0.3,ced0.5,0.6 and 0.9 to to be next to each other. – eastafri Sep 17 '12 at 05:01
  • @Biorelated Whenever you want the levels of a factor in a particular order, you have to explicitly tell R that ordering. There are programmatic ways of doing that (i.e. `reorder`) but failing that, you simply will need to do `ex1.dta2 <- factor(ex1.dta2$domain, levels = ...)` and then list the levels in the order you desire. – joran Sep 17 '12 at 09:33