<p>It seems like this is missing a grouping variable in the aesthetics definition. The R help page for <code>position_dodge</code> mentions the following:</p>
<blockquote>
<p>Position_dodge() requires the grouping variable to be be specified in the global or ⁠geom_*⁠ layer. Unlike position_dodge(), position_dodge2() works without a grouping variable in a layer. position_dodge2() works with bars and rectangles, but is particulary useful for arranging box plots, which can have variable widths.</p>
</blockquote>
<p>Bearing this in mind, setting <code>group=Average.DB.per.FA</code> seems to give the result you want:</p>
<pre><code>long_DF %&gt;%
  ggplot() +
  aes(fill=Average.DB.per.FA,
      y=percentage, x=condition, group=Average.DB.per.FA) +
  geom_col()
</code></pre>
<p>... although this is adding up to 3 rather than 1, as would be expected from looking at the category counts:</p>
<pre><code>&gt; long_DF %&gt;% 
+   group_by(condition) %&gt;%
+   summarise(sumPct = sum(percentage))
# A tibble: 2 × 2
  condition sumPct
  &lt;chr&gt;      &lt;dbl&gt;
1 CDD            3
2 STD            3
</code></pre>
<p><a href="https://i.sstatic.net/NGRES.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/NGRES.png" alt="stacked column plot with grouping based on Average.DB.per.FA" /></a></p>
<p>Note: as seen above, I'm using <code>geom_col</code>instead of <code>geom_bar</code> with a different statistical summary method. If you're using <em>stat=%something%</em>, there's probably a better way to approach the task. The following is from the first paragraph of the R help page for <code>geom_bar</code>/<code>geom_col</code>:</p>
<blockquote>
<p>There are two types of bar charts: geom_bar() and geom_col(). geom_bar() makes the height of the bar proportional to the number of cases in each group (or if the weight aesthetic is supplied, the sum of the weights). If you want the heights of the bars to represent values in the data, use geom_col() instead. geom_bar() uses stat_count() by default: it counts the number of cases at each x position. geom_col() uses stat_identity(): it leaves the data as is.</p>
</blockquote>

CC BY-SA 4.0
2022-10-10T12:13:35.427Z
2022-10-10T12:13:35.427Z
gringer
<p>I am trying to plot a stacked bar graph with mean values from multiple repeats, also showing the range of the data and values labelled.</p>
<p>My data frame is below:</p>
<pre><code>structure(list(Average.DB.per.FA = c(0, 0.5, 1, 1.5, 2, 0, 0.5, 
1, 1.5, 2, 0, 0.5, 1, 1.5, 2, 0, 0.5, 1, 1.5, 2, 0, 0.5, 1, 1.5, 
2, 0, 0.5, 1, 1.5, 2), condition = c(&quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, 
&quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, &quot;CDD&quot;, 
&quot;CDD&quot;, &quot;CDD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, 
&quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;, &quot;STD&quot;), percentage = c(0, 
0.807218011, 0.192781989, 0, 0, 0, 0.737968015, 0.262031985, 
0, 0, 0, 0.739096101, 0.260903899, 0, 0, 0, 0.466751289, 0.346156739, 
0.170617491, 0.016474482, 0, 0.462997344, 0.331833715, 0.183359127, 
0.021809813, 0.012053568, 0.47623097, 0.307175237, 0.182459607, 
0.022080618)), row.names = c(NA, -30L), class = &quot;data.frame&quot;)
</code></pre>
<p>I tried to use the following code:</p>
<pre><code>    ggplot(long_DF, aes(fill=Average.DB.per.FA, y=percentage, x=condition)) + 
  geom_bar(position=position_dodge(), stat=&quot;identity&quot;)
</code></pre>
<p>But the graph I obtained does not have bars add up to 1:
<a href="https://i.sstatic.net/OAc5O.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/OAc5O.png" alt="enter image description here" /></a></p>
<p>I would like to have graphs like below (which I created by Prism using the same set of data but Prism does not allow me to label bars with numbers):
<a href="https://i.sstatic.net/pjEOg.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/pjEOg.png" alt="enter image description here" /></a></p>
<p>Is there any way to reproduce the graph by Prism using R and add values to each stacked bar?</p>
<p>Appreciate your help and thanks in advance.</p>

CC BY-SA 4.0
2022-10-09T09:58:49.877Z
Hi its a great question. Could you kindly explain the biological aspect of the code, i.e. why is this bioformatics rather than pure statistics?
M__
<r><ggplot2>
How to plot stacked bar chart using R showing mean with range and labelled values?
# How to plot stacked bar chart using R showing mean with range and labelled values?

(Asked by: username_0 on 2022-10-09)

I am trying to plot a stacked bar graph with mean values from multiple repeats, also showing the range of the data and values labelled.
My data frame is below:
structure(list(Average.DB.per.FA = c(0, 0.5, 1, 1.5, 2, 0, 0.5, 
1, 1.5, 2, 0, 0.5, 1, 1.5, 2, 0, 0.5, 1, 1.5, 2, 0, 0.5, 1, 1.5, 
2, 0, 0.5, 1, 1.5, 2), condition = c("CDD", "CDD", "CDD", "CDD", 
"CDD", "CDD", "CDD", "CDD", "CDD", "CDD", "CDD", "CDD", "CDD", 
"CDD", "CDD", "STD", "STD", "STD", "STD", "STD", "STD", "STD", 
"STD", "STD", "STD", "STD", "STD", "STD", "STD", "STD"), percentage = c(0, 
0.807218011, 0.192781989, 0, 0, 0, 0.737968015, 0.262031985, 
0, 0, 0, 0.739096101, 0.260903899, 0, 0, 0, 0.466751289, 0.346156739, 
0.170617491, 0.016474482, 0, 0.462997344, 0.331833715, 0.183359127, 
0.021809813, 0.012053568, 0.47623097, 0.307175237, 0.182459607, 
0.022080618)), row.names = c(NA, -30L), class = "data.frame")

I tried to use the following code:
    ggplot(long_DF, aes(fill=Average.DB.per.FA, y=percentage, x=condition)) + 
  geom_bar(position=position_dodge(), stat="identity")

But the graph I obtained does not have bars add up to 1:

I would like to have graphs like below (which I created by Prism using the same set of data but Prism does not allow me to label bars with numbers):

Is there any way to reproduce the graph by Prism using R and add values to each stacked bar?
Appreciate your help and thanks in advance.

**Tags:** r, ggplot2
> **Comments:**
> **username_1**: Hi its a great question. Could you kindly explain the biological aspect of the code, i.e. why is this bioformatics rather than pure statistics?  

---

## 1 answers

### Answer by username_2 on 2022-10-10. Score: 1

It seems like this is missing a grouping variable in the aesthetics definition. The R help page for position_dodge mentions the following:

Position_dodge() requires the grouping variable to be be specified in the global or ⁠geom_*⁠ layer. Unlike position_dodge(), position_dodge2() works without a grouping variable in a layer. position_dodge2() works with bars and rectangles, but is particulary useful for arranging box plots, which can have variable widths.

Bearing this in mind, setting group=Average.DB.per.FA seems to give the result you want:
long_DF %>%
  ggplot() +
  aes(fill=Average.DB.per.FA,
      y=percentage, x=condition, group=Average.DB.per.FA) +
  geom_col()

... although this is adding up to 3 rather than 1, as would be expected from looking at the category counts:
> long_DF %>% 
+   group_by(condition) %>%
+   summarise(sumPct = sum(percentage))
# A tibble: 2 × 2
  condition sumPct
        
1 CDD            3
2 STD            3


Note: as seen above, I'm using geom_colinstead of geom_bar with a different statistical summary method. If you're using stat=%something%, there's probably a better way to approach the task. The following is from the first paragraph of the R help page for geom_bar/geom_col:

There are two types of bar charts: geom_bar() and geom_col(). geom_bar() makes the height of the bar proportional to the number of cases in each group (or if the weight aesthetic is supplied, the sum of the weights). If you want the heights of the bars to represent values in the data, use geom_col() instead. geom_bar() uses stat_count() by default: it counts the number of cases at each x position. geom_col() uses stat_identity(): it leaves the data as is.


---

