title: Stacked bar plot ggplot2- ordering samples by specific variables, highest to lowest values
body: <p>I'm trying to plot a data set containing over 2000 samples in a stacked bar chart format, with each sample (represented by "SampleID") on the x-axis and 6 measurement values on the y-axis (<code>Measurement1-6</code>). I want the samples to be displayed/ordered by a the following order of measurement variables: <code>Measurement4</code>, 1, 5, 2, 3, and 6, and from highest to lowest measurement value. Below is a subset of 15 samples as an example of what I'm working with, which I'll refer to as the "dummy_set" data frame:</p>
  
  <pre><code>    SampleID Measurement1 Measurement2 Measurement3 Measurement4 Measurement5 Measurement6
  1         A         0.05         0.00         0.95         0.00          0.0         0.00
  2         B         0.00         0.00         0.43         0.56          0.0         0.01
  3         C         0.64         0.36         0.00         0.00          0.0         0.00
  4         D         0.00         0.82         0.18         0.00          0.0         0.00
  5         E         0.00         0.60         0.00         0.40          0.0         0.00
  6         F         0.80         0.00         0.00         0.20          0.0         0.00
  7         G         0.00         0.00         0.00         1.00          0.0         0.00
  8         H         0.00         0.00         0.00         1.00          0.0         0.00
  9         I         0.00         0.00         1.00         0.00          0.0         0.00
  10        J         0.00         0.00         1.00         0.00          0.0         0.00
  11        K         0.25         0.00         0.00         0.45          0.3         0.00
  12        L         0.10         0.00         0.00         0.10          0.8         0.00
  13        M         0.19         0.10         0.00         0.70          0.0         0.01
  14        N         0.90         0.00         0.00         0.10          0.0         0.00
  15        O         0.00         0.10         0.40         0.00          0.5         0.00
  </code></pre>
  
  <p>Here's the basics of what I've done:</p>
  
  <ol>
  <li><p>Melt the data set:
  melt_dummy_set &lt;- melt(dummy_set, id.var = "SampleID")</p>
  
  <p>Where the melted data set looks like this:</p>
  
  <pre><code>head(melt_dummy_set)
      SampleID     variable value
  1         A Measurement1  0.05
  2         B Measurement1  0.00
  3         C Measurement1  0.64
  4         D Measurement1  0.00
  5         E Measurement1  0.00
  6         F Measurement1  0.80
  </code></pre></li>
  <li><p>Plot the melted data set using ggplot() and geom_bar():</p>
  
  <pre><code>ggplot(melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
  geom_bar(stat = "identity") + 
  </code></pre></li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/oTYLp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oTYLp.png" alt="Original stacked bar chart"></a></p>
  
  <p>As you can see, the samples are plotted in the original order that they were listed (A-O). However, I want them to be plotted in the following order: G, H, M, B, K, N, F, C, L, O, D, E, I, J, and A.</p>
  
  <p>Based on other similar Stack Overflow questions, I've gathered that I need to relevel/re-establish the factors in the order I want. Here is what I've tried so far:</p>
  
  <pre><code>#Attempt 1
  reordered_melt_dummy_set &lt;- transform(melt_dummy_set, variable = reorder(variable, -value))
  ggplot(reordered_melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
  
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/bz8Uy.png" rel="nofollow noreferrer">Attempt 1 results</a></p>
  
  <pre><code>#Attempt 2
  copy_melt_dummy_set &lt;- melt_dummy_set
  copy_melt_dummy_set$variable &lt;- factor(copy_melt_dummy_set$variable, levels = c("Measurement4", "Measurement5", "Measurement1", "Measurement2", "Measurement3", "Measurement6"))
  ggplot(copy_melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
  
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/k9ajt.png" rel="nofollow noreferrer">Attempt 2 results</a></p>
  
  <p>My 3rd attempt resulted in multiple errors (denoted in "##" immediately after the line of code)</p>
  
  <pre><code>#Attempt 3
  copy2_melt_dummy_set &lt;- melt_dummy_set
  
  copy2_melt_dummy_set$SampleID &lt;- factor(copy2_melt_dummy_set$SampleID, levels = copy2_melt_dummy_set[order(-copy2_melt_dummy_set$value), "variable"])
  ##Error in `levels&lt;-`(`*tmp*`, value = as.character(levels)) : factor level [2] is duplicated
  
  copy2_melt_dummy_set$variable &lt;- factor(copy2_melt_dummy_set$variable, levels = copy2_melt_dummy_set[order(copy2_melt_dummy_set$value), "variable"])
  ## Error in `levels&lt;-`(`*tmp*`, value = as.character(levels)) : factor level [2] is duplicated
  
  copy2_melt_dummy_set$SampleID &lt;- factor(copy2_melt_dummy_set$SampleID, levels = copy2_melt_dummy_set[order(-copy2_melt_dummy_set$variable), "SampleID"])
  ## Error in `levels&lt;-`(`*tmp*`, value = as.character(levels)) : factor level [16] is duplicated
  ## In addition: Warning message: In Ops.factor(copy2_melt_dummy_set$variable) : ‘-’ not meaningful for factors
  
  copy2_melt_dummy_set$SampleID &lt;- factor(copy2_melt_dummy_set$SampleID, levels = copy2_melt_dummy_set[order(-copy2_melt_dummy_set$value), "SampleID"])
  ## Error in `levels&lt;-`(`*tmp*`, value = as.character(levels)) : factor level [16] is duplicated
  
  copy2_melt_dummy_set$SampleID &lt;- factor(copy2_melt_dummy_set$SampleID, levels = copy2_melt_dummy_set[order(-copy2_melt_dummy_set$value), "value"])
  ## Error in `levels&lt;-`(`*tmp*`, value = as.character(levels)) : factor level [2] is duplicated
  </code></pre>
  
  <pre><code>#Attempt 4
  copy3_melt_dummy_set &lt;- melt_dummy_set[order(melt_dummy_set$variable, -melt_dummy_set$value), ]
  head(copy3_melt_dummy_set)
  ggplot(copy3_melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
  
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/HxUYt.png" rel="nofollow noreferrer">Attempt 4 results</a></p>
  
  <pre><code>#Attempt 5
  ggplot(melt_dummy_set[order(melt_dummy_set$variable, -melt_dummy_set$value), ], aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
  
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/U9Krl.png" rel="nofollow noreferrer">Attempt 5 results</a></p>
  
  <pre><code>#Attempt 6
  new_melt_dummy_set &lt;- within(melt_dummy_set, 
                               variable &lt;- factor(variable, levels = names(sort(table(variable), decreasing = TRUE))))
  ggplot(new_melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
  
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/wcIfi.png" rel="nofollow noreferrer">Attempt 6 results</a></p>
  
  <pre><code>#Attempt 7
  copy4_melt_dummy_set &lt;- melt_dummy_set
  custom_leveling &lt;- unique(copy4_melt_dummy_set$variable)
  copy4_melt_dummy_set$variable &lt;- factor(copy4_melt_dummy_set$variable, level = custom_leveling)
  ggplot(copy4_melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
  
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/157VH.png" rel="nofollow noreferrer">Attempt 7 results</a></p>
  
  <p>In all cases I can't get the actual samples on the x-axis to be reorganized. I feel there's probably a simple fix for this, but I can't figure out what I'm doing wrong. Any suggestions?</p>
  
  <h3>Edited</h3>
  
  <p>In response to the possible duplicate comment, I tried applying the codes/solutions from <a href="https://stackoverflow.com/questions/5208679/order-bars-in-ggplot2-bar-graph">Order Bars in ggplot2 bar graph</a> and they did not produce the plot in the desired order that I wanted. See below for the codes I tried:</p>
  
  <pre><code>#First solution
  new_melt_dummy_set &lt;- within(melt_dummy_set, 
                               variable &lt;- factor(variable, levels = names(sort(table(variable), decreasing = TRUE))))
  ggplot(new_melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity")
  
  #Second solution
  ggplot(melt_dummy_set, aes(x = reorder(SampleID, variable, function(x)-length(x)), y = value, fill = variable)) + geom_bar(stat = "identity")
  ggplot(melt_dummy_set, aes(x = reorder(variable, SampleID, function(x)-length(x)), y = value, fill = variable)) + geom_bar(stat = "identity")
  
  #Third solution
  ordered_measurements &lt;- c("Measurement4", "Measurement1", "Measurement5", "Measurement2", "Measurement3", "Measurement6")
  ggplot(melt_dummy_set, aes(x = SampleID, y = value, fill = variable)) + 
    geom_bar(stat = "identity") + 
    scale_x_discrete(limits = ordered_measurements)
  
  #Fourth solution
  ggplot(melt_dummy_set, aes(x = reorder(SampleID, -table(variable)[variable]), y = value, fill = variable)) + geom_bar(stat = "identity")
  
  require(forcats)
  ggplot(melt_dummy_set, aes(x = SampleID, fill = fct_infreq(variable), y = value)) + geom_bar(stat = "identity")
  ggplot(melt_dummy_set, aes(x = fct_infreq(variable))) + geom_bar(stat = "identity")
  
  #Fifth solution
  library(tidyverse)
  library(forcats)
  melt_dummy_set %&gt;%
    mutate(variable = fct_reorder(variable, value, .desc = TRUE)) %&gt;%
    ggplot(aes(x = SampleID, y = value, fill = variable)) + geom_bar(stat = 'identity')
  
  #Sixth solution
  library(dplyr)
  melt_dummy_set %&gt;%
    group_by(variable) %&gt;%                              
    summarize(counts = n()) %&gt;%
    arrange(-counts) %&gt;%                                
    mutate(SampleID = factor(SampleID, variable)) %&gt;%   
    ggplot(aes(x = SampleID, y = value, fill = variable)) +                  
    geom_bar(stat = "identity")                         
  
  melt_dummy_set %&gt;%
    group_by(SampleID) %&gt;%                              
    summarize(counts = n()) %&gt;%
    arrange(-counts) %&gt;%                                
    mutate(SampleID = factor(SampleID, value)) %&gt;%   
    ggplot(aes(x = SampleID, y = value, fill = variable)) +                 
    geom_bar(stat = "identity")
  
  #Seventh solution
  new_meltedDummy_set &lt;- transform(melt_dummy_set,
                         variable = ordered(variable, levels = names(sort(-table(variable)))))
  ggplot(new_meltedDummy_set, aes(x = SampleID, y = value, fill = variable)) +
    geom_bar(stat = "identity")
  
  </code></pre>