180

I am trying to make a bar-plot where the plot is ordered from the miRNA with the highest value to the miRNA with the lowest. Why does my code not work?

> head(corr.m)

        miRNA         variable value
1    mmu-miR-532-3p      pos     7
2    mmu-miR-1983        pos    75
3    mmu-miR-301a-3p     pos    70
4    mmu-miR-96-5p       pos     5
5    mmu-miR-139-5p      pos    10
6    mmu-miR-5097        pos    47

ggplot(corr.m, aes(x=reorder(miRNA, value), y=value, fill=variable)) + 
  geom_bar(stat="identity")
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
user3741035
  • 2,455
  • 4
  • 15
  • 20

3 Answers3

310

Your code works fine, except that the barplot is ordered from low to high. When you want to order the bars from high to low, you will have to add a -sign before value:

ggplot(corr.m, aes(x = reorder(miRNA, -value), y = value, fill = variable)) + 
  geom_bar(stat = "identity")

which gives:

enter image description here


Used data:

corr.m <- structure(list(miRNA = structure(c(5L, 2L, 3L, 6L, 1L, 4L), .Label = c("mmu-miR-139-5p", "mmu-miR-1983", "mmu-miR-301a-3p", "mmu-miR-5097", "mmu-miR-532-3p", "mmu-miR-96-5p"), class = "factor"),
                         variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = "pos", class = "factor"),
                         value = c(7L, 75L, 70L, 5L, 10L, 47L)),
                    class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6"))
Jaap
  • 81,064
  • 34
  • 182
  • 193
  • it does not get ordered in my plot for some reason – user3741035 Sep 04 '14 at 11:39
  • @user3741035 Strange. Did you use it on the sample dataset you provided above or on the whole dataset? – Jaap Sep 04 '14 at 11:43
  • Which version of R & ggplot are you using? Can you also privede a larger sample dataset (preferrably with more than one value for `variable`)? – Jaap Sep 04 '14 at 11:48
  • 6
    found the solution: I had loaded library(gplots) which messed up things – user3741035 Sep 04 '14 at 11:55
  • nice tip! how does it work BTW? I don't get why adding - should invert the order. – Bakaburg Mar 11 '16 at 15:56
  • @Bakaburg It tells R to use decreasing order instead of increasing. – Jaap Mar 11 '16 at 16:00
  • I meant practically how is it implemented; Guess I should read the code inside. – Bakaburg Mar 12 '16 at 11:03
  • the reordering doesn't work for me neither.... And i don't use library(gplots).. I have ggplot2_2.1.0 R version 3.2.2 (2015-08-14) Platform: x86_64-apple-darwin13.4.0 (64-bit) Running under: OS X 10.9.5 (Mavericks). do you have anothersuggestions, where I am wrong? – maycca Jun 01 '16 at 21:27
  • 1
    @maycca It is giving me the correct result (on both OSX 10.10.4 / Windows 7, R 3.2.3 & ggplot2 2.1.0). Maybe you should start with a fresh session? – Jaap Jun 02 '16 at 06:34
  • Thank, I was doing that on my data and it didn't work... but I've fixed the problem - I firstly needed to convert my factors from numeric to character. and then to factors ! and no directly the numeric to factors. It workd great now ! ;) – maycca Jun 02 '16 at 19:42
  • "object 'value' not found" This answer seems to be invalid. – Luís de Sousa Mar 12 '19 at 09:05
  • @LuísdeSousa The answer is still valid (just checked). The error indicates that the column `value` isn't in your data. You might want to use another column for reordering? – Jaap Mar 12 '19 at 10:24
  • @LuísdeSousa Did you downvote? Anyway, as I said: the answer I posted above still gives the same output with the latest versions of R & ggplot2 – Jaap Mar 12 '19 at 15:40
  • @Jaap I can not find what could be wrong on my side. Copy paste from your answer results in the error above. – Luís de Sousa Mar 12 '19 at 15:45
  • @LuísdeSousa Is there a `value`-column in your data? – Jaap Mar 12 '19 at 15:50
  • @Jaap the column has a different name, but naturally I am changing the `y` and `x` arguments. – Luís de Sousa Mar 13 '19 at 07:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/189928/discussion-between-jaap-and-luis-de-sousa). – Jaap Mar 13 '19 at 07:32
4

Aside from what @Jaap answered, there are two other ways to order the plot:

1: By using desc argument for value:

ggplot(corr.m, aes(x = reorder(miRNA, desc(value)), y = value, fill = variable)) + 
   geom_bar(stat = "identity")

2: By releveling the miRNA factor and omitting reorder argument:

corr.m %>%
   arrange(desc(value)) %>%
   mutate(miRNA = factor(miRNA, levels = unique(miRNA))) %>% 
ggplot(aes(x = miRNA, y = value, fill = variable)) + 
   geom_bar(stat = "identity") 
ETeddy
  • 115
  • 5
2

Another option is creating the variable as a factor where the factor levels are in decreasing order based on your value variable.

decreasing = TRUE

library(ggplot2)
# Create factor column with decreasing order TRUE
corr.m$miRNA <- factor(corr.m$miRNA, levels = corr.m$miRNA[order(corr.m$value, decreasing = TRUE)])

ggplot(corr.m, aes(x=miRNA, y=value, fill=variable)) + 
  geom_bar(stat="identity") 

Created on 2022-08-19 with reprex v2.0.2

decreasing = FALSE

library(ggplot2)
# Create factor column with decreasing order FALSE
corr.m$miRNA <- factor(corr.m$miRNA, levels = corr.m$miRNA[order(corr.m$value, decreasing = FALSE)])

ggplot(corr.m, aes(x=miRNA, y=value, fill=variable)) + 
  geom_bar(stat="identity")

Created on 2022-08-19 with reprex v2.0.2

Quinten
  • 35,235
  • 5
  • 20
  • 53