<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/annotated-facets-with-ggplot2/"></div></div><div><a data-url="https://www.r-bloggers.com/annotated-facets-with-ggplot2/" data-counturl="https://www.r-bloggers.com/annotated-facets-with-ggplot2/" data-count="horizontal" data-text="Annotated Facets with ggplot2" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://statbandit.wordpress.com/2016/10/20/annotated-facets-with-ggplot2/"> R – Stat Bandit</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I was recently asked to do a panel of grouped boxplots of a continuous variable,<br>
with each panel representing a categorical grouping variable. This seems easy enough with ggplot2 and the <code>facet_wrap</code> function, but then my collaborator wanted p-values on the graphs! This post is my approach to the problem.</p>
<p>First of all, one caveat. I’m a huge fan of Hadley Wickham’s <a target="_blank" rel="nofollow" href="https://blog.rstudio.org/2016/09/15/tidyverse-1-0-0/">tidyverse</a> and so most of my code will reflect this ethos, including packages and pipes. There are, of course, other approaches to doing this.</p>
<pre>library(broom)
library(ggplot2)
library(tidyverse)
</pre>
<p>I will use the <code>warpbreaks</code> dataset as an example. This data looks at the number of breaks in yarn, for two types of yarn (A and B) and three loom tensions (L, M, H)</p>
<pre>data(warpbreaks)
glimpse(warpbreaks)
</pre>
<pre>## Observations: 54
## Variables: 3
## $ breaks  &lt;dbl> 26, 30, 54, 25, 70, 52, 51, 26, 67, 18, 21, 29, 17, 12...
## $ wool    &lt;fctr> A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,...
## $ tension &lt;fctr> L, L, L, L, L, L, L, L, L, M, M, M, M, M, M, M, M, M,...
</pre>
<h3>A single panel</h3>
<p>Let’s first start with creating a grouped boxplot of breaks by wool type. This is pretty straightforward in ggplot2.</p>
<pre>plt1 &lt;- ggplot(warpbreaks, aes(x=wool, y=breaks))+
geom_boxplot()
plt1
</pre>
<p><img alt="plot of chunk plt1" src="https://i1.wp.com/dl.dropboxusercontent.com/u/36792950/wp/figure/plt1-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Adding the p-value to this is also rather simple. We will perform a two-sample t.test and report the p-value on the plot</p>
<pre>tst = t.test(breaks ~ wool, data=warpbreaks)
pval = tidy(tst)$p.value # from broom
plt1 + geom_text(aes(x=2, y = 60, # Where do we put the annotation
label=paste('P-value:', format.pval(pval, digits=2))))
</pre>
<p><img alt="plot of chunk plt1-1" src="https://i1.wp.com/dl.dropboxusercontent.com/u/36792950/wp/figure/plt1-1-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<h3>Multiple panels</h3>
<p>I’ll now show how to do multiple panels. First, we have to transform the data into long format so that ggplot2 can leverage it.</p>
<pre>warp2 &lt;- gather(warpbreaks, variable, value, -breaks)
head(warp2)
</pre>
<pre>##   breaks variable value
## 1     26     wool     A
## 2     30     wool     A
## 3     54     wool     A
## 4     25     wool     A
## 5     70     wool     A
## 6     52     wool     A
</pre>
<p>Now we can plot this using ggplot2</p>
<pre>ggplot(warp2, aes(x = value, y = breaks))+geom_boxplot()+facet_wrap(~variable, nrow=1)
</pre>
<p><img alt="plot of chunk fig1" src="https://i0.wp.com/dl.dropboxusercontent.com/u/36792950/wp/figure/fig1-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Ooops!! When we used <code>gather</code> to melt the data frame and create one variable for the two categorical variables, with the levels all shared in the <code>variable</code> column. So the plot shows all the possible categories. We can easily fix this.</p>
<pre>plt2 &lt;- ggplot(warp2, aes(x=value, y=breaks))+geom_boxplot()+facet_wrap(~variable, nrow=1, scales='free_x')
</pre>
<p>Next, we want to put a p-value on each plot. The trick is to create a new data frame for the p-values, with one row per level of the facetting variable. In our example, wool has two levels while tension has three, so to create one p-value per plot I’ll run ANOVA models and provide the p-value of the model effect, i.e., is there any difference in the average number of breaks by levels of each predictor. I’ll use the template Wickham suggests about <a target="_blank" rel="nofollow" href="http://r4ds.had.co.nz/many-models.html">running multiple models</a> here.</p>
<pre>pvalues &lt;- warp2 %>%
nest(-variable) %>%
mutate(mods = map(data, ~anova(lm(breaks ~ value, data = .))),
pval = map_dbl(mods, ~tidy(.)$p.value[1])) %>%
select(variable, pval)
pvalues
</pre>
<pre>## # A tibble: 2 × 2
##   variable        pval
##      &lt;chr>       &lt;dbl>
## 1     wool 0.108397092
## 2  tension 0.001752817
</pre>
<p>I’ll also include in this data frame (or <code>tibble</code> as the tidyverse calls it) the location of the annotation on each graph, using the same variable names as the graph</p>
<pre>pvalues &lt;- pvalues %>%
mutate(value = c(1.5,2.5), breaks = 60)
pvalues
</pre>
<pre>## # A tibble: 2 × 4
##   variable        pval value breaks
##      &lt;chr>       &lt;dbl> &lt;dbl>  &lt;dbl>
## 1     wool 0.108397092   1.5     60
## 2  tension 0.001752817   2.5     60
</pre>
<p>Now, let’s plot these onto the facetted plot</p>
<pre>plt2_annot &lt;- plt2 +
geom_text(data=pvalues, aes(x=value, y=breaks,
label = paste('P-value:',
format.pval(pval, digits=1))))
plt2_annot
</pre>
<p><img alt="plot of chunk annotated" src="https://i2.wp.com/dl.dropboxusercontent.com/u/36792950/wp/figure/annotated-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Obviously, if we wanted to make this graph publication quality, we’d need to modify the labels and perhaps the background, but this example gets you to the point where you can put p-values onto facetted plots. In fact, there’s nothing special about p-values here; you could add any facet-specific annotation onto your facetted plots using the same template.</p>
<p> <a target="_blank" rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/statbandit.wordpress.com/561/"><img alt="" src="http://feeds.wordpress.com/1.0/comments/statbandit.wordpress.com/561/" border="0"></a> <img alt="" src="https://i1.wp.com/pixel.wp.com/b.gif?resize=1%2C1&ssl=1" border="0" data-recalc-dims="1"></p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/annotated-facets-with-ggplot2/"></div></div><div><a data-url="https://www.r-bloggers.com/annotated-facets-with-ggplot2/" data-counturl="https://www.r-bloggers.com/annotated-facets-with-ggplot2/" data-count="vertical" data-text="Annotated Facets with ggplot2" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://statbandit.wordpress.com/2016/10/20/annotated-facets-with-ggplot2/"> R – Stat Bandit</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/iYeQCjUeFuU"></a></div>