<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/piping-into-ggplot2/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.win-vector.com/blog/2018/10/piping-into-ggplot2/"> R – Win-Vector Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>In our <a rel="nofollow" href="https://winvector.github.io/wrapr/" target="_blank"><code>wrapr</code></a> <a rel="nofollow" href="https://journal.r-project.org/archive/2018/RJ-2018-042/index.html" target="_blank">pipe RJournal article</a> we used piping into <a rel="nofollow" href="https://cran.r-project.org/package=ggplot2" target="_blank"><code>ggplot2</code></a> layers/geoms/items as an example.</p>
<p>Being able to use the same pipe operator for data processing steps and for <code>ggplot2</code> layering is a question that comes up from time to time (for example: <a rel="nofollow" href="https://community.rstudio.com/t/why-cant-ggplot2-use/4372" target="_blank">Why can’t ggplot2 use %>%?</a>). In fact the primary <code>ggplot2</code> package author <a rel="nofollow" href="https://community.rstudio.com/t/why-cant-ggplot2-use/4372/7" target="_blank">wishes that <code>magrittr</code> piping was the composing notation for <code>ggplot2</code></a> (though it is obviously too late to change).</p>
<p>There are some fundamental difficulties in trying to use the <a rel="nofollow" href="https://cran.r-project.org/package=magrittr" target="_blank"><code>magrittr</code></a> pipe in such a way. In particular <code>magrittr</code> looks for its own pipe by name in un-evaluated code, and thus is difficult to engineer over (though it can be <a rel="nofollow" href="https://community.rstudio.com/t/why-cant-ggplot2-use/4372/3" target="_blank">hacked around</a>). The general concept is: pipe stages are usually functions or function calls, and <code>ggplot2</code> components are objects (verbs versus nouns); and at first these seem incompatible.</p>
<p>However, the <code>wrapr</code> <a rel="nofollow" href="https://winvector.github.io/wrapr/reference/dot_arrow.html" target="_blank">dot-arrow-pipe</a> was designed to handle such distinctions.</p>
<p>Let’s work an example.</p>
<p><span></span></p>
<p>
<p>Suppose we want a single pipe notation to combine data processing and <code>ggplot2</code> layer composition steps.</p>
<p>The <code>wrapr</code> dot-arrow-pipe performs data processing steps by explicit use of dot and sequencing of expressions. The dot-arrow semantics treats <code>a %.>% b</code> as being very much like <code>{. &lt;- a; b}</code>. This means if the user writes an expression such as <code>a %.>% b(.)</code> the evaluation is very similar to <code>b(a)</code> (with some visible side-effects in the &quot;<code>.</code>&quot; variable). <a rel="nofollow" href="http://www.win-vector.com/blog/2018/03/r-tip-make-arguments-explicit-in-magrittr-dplyr-pipelines/" target="_blank">Explicit argument notation</a> is in fact a <code>wrapr</code> dot-arrow design principle, though <code>wrapr</code> dot arrow has some short-cuts and convenience methods (such as treating <code>a %.>% f</code> as <code>a %.>% f(.)</code> when <code>f</code> is bound to a function as in <code>5 %.>% sin</code>). The <code>wrapr</code> dot-arrow-pipe concept is sequencing of expressions, which is related to (but not the same as) composition of functions.</p>
<p>With this in mind lets use <code>wrapr</code> dot-arrow-pipe for both data processing and <code>ggplot2</code> layering.</p>
<p>First we load our packages.</p>
<div>
<pre><code><span>library</span>(<span>&quot;ggplot2&quot;</span>)
<span>library</span>(<span>&quot;wrapr&quot;</span>)
<span>suppressPackageStartupMessages</span>(<span>library</span>(<span>&quot;dplyr&quot;</span>))</code></pre>
</div>
<p>Now we tell <code>wrapr</code> what do do when the left-argument to a pipe is of class-<code>gg</code>. In this case we say treat <code>a %.>% b</code> as <code>a + b</code> (instead of the default <code>{. &lt;- a; b}</code>). Notice this is an extension that any user or package can make, <code>wrapr</code> does not have special adaption for <code>ggplot2</code>. Instead it supplies sufficient control to be able to adapt to <code>ggplot2</code>.</p>
<div>
<pre><code>apply_left.gg &lt;-<span> </span>function(pipe_left_arg,
                          pipe_right_arg,
                          pipe_environment,
                          left_arg_name,
                          pipe_string,
                          right_arg_name) {
  pipe_right_arg &lt;-<span> </span><span>eval</span>(pipe_right_arg,
                         <span>envir =</span> pipe_environment,
                         <span>enclos =</span> pipe_environment)
  pipe_left_arg +<span> </span>pipe_right_arg 
}</code></pre>
</div>
<p>Now we can run a single pipeline that combines data processing steps and <code>ggplot</code> plot construction.</p>
<div>
<pre><code><span>data.frame</span>(<span>x =</span> <span>1</span>:<span>20</span>) %.>%
<span> </span><span>mutate</span>(., <span>y =</span> <span>cos</span>(<span>3</span>*x)) %.>%
<span> </span><span>ggplot</span>(., <span>aes</span>(<span>x =</span> x,  <span>y =</span> y)) %.>%
<span> </span><span>geom_point</span>() %.>%
<span> </span><span>geom_line</span>() %.>%
<span> </span><span>ggtitle</span>(<span>&quot;piped ggplot2&quot;</span>)</code></pre>
</div>
<div>
<img border="0" src="https://i2.wp.com/www.win-vector.com/blog/wp-content/uploads/2018/10/unnamed-chunk-3-1.png?resize=336%2C240" alt="Unnamed chunk 3 1" width="336" title="unnamed-chunk-3-1.png" data-recalc-dims="1" height="240">
</div>
<p>Notice the data processing step <code>mutate()</code> and the initial <code>ggplot()</code> step <em>must</em> use &quot;<code>.</code>&quot;, as that is how the dot-arrow-pipe normally moves data forward. The <code>ggplot2</code> geom/layer/item pieces do not use &quot;<code>.</code>&quot;. The evaluation rule is these items are evaluated as &quot;pipe_right_arg&quot; before seeing any of the pipeline to the left; this is roughly how <code>ggplot2</code> handles composition through its override of &quot;<code>+</code>&quot;.</p>
<p>And this is where we stopped the <code>ggplot2</code> example in the <a rel="nofollow" href="https://winvector.github.io/wrapr/" target="_blank"><code>wrapr</code></a>‘s <a rel="nofollow" href="https://journal.r-project.org/archive/2018/RJ-2018-042/index.html" target="_blank">pipe RJournal article</a>. The article was about the <code>wrap</code> dot-arrow-pipe, and not about <code>ggplot2</code> so it seemed important to move on from the example quickly.</p>
<p>A minor (undiscussed) technical difficulty is: <code>ggplot2</code> users can store pieces of a plot in variables (or more correctly variable names my refer to pieces in environments). They may use this to write more modular plotting code. For example suppose the user stored the <code>geom_line()</code> specification and the title in two variables as below.</p>
<div>
<pre><code>line &lt;-<span> </span><span>geom_line</span>(<span>linetype =</span> <span>2</span>)

title &lt;-<span> </span><span>ggtitle</span>(<span>&quot;piped ggplot2&quot;</span>,
                 <span>subtitle =</span> <span>&quot;pre-stored title&quot;</span>)</code></pre>
</div>
<p>We can not, without a bit more adaption, pipe into these structures.</p>
<div>
<pre><code><span>data.frame</span>(<span>x =</span> <span>1</span>:<span>20</span>) %.>%
<span> </span><span>mutate</span>(., <span>y =</span> <span>cos</span>(<span>3</span>*x)) %.>%
<span> </span><span>ggplot</span>(., <span>aes</span>(<span>x =</span> x,  <span>y =</span> y)) %.>%
<span> </span><span>geom_point</span>() %.>%
<span> </span>line %.>%
<span> </span>title</code></pre>
</div>
<pre><code>## Error: wrapr::apply_right_S4 default called with classes:
##   gg, ggplot 
##  line gg, ggplot 
##   must have a more specific S4 method defined to dispatch</code></pre>
<p>The above error message is intentional. When the right-hand side of a <code>wrapr</code> pipe is the name of an object (instead of an expression or function) <code>wrapr</code> uses a right-dispatch followed by an <code>S4</code> dispatch to decide what to do. The error message here just means there is no registered right or <code>S4</code> dispatch for the classes of objects seen. This is easy to fix by examining the classes of the objects and adding appropriate right dispatch methods. What we are trying to say: the original left dispatch was enough to deal with plots where all the layers are presented as un-evaluated function calls (the most typical way to user <code>ggplot2</code>), however layers/geoms/items already evaluated and stored in variables need additional adaption.</p>
<p>This detail is not fragility of the <code>wrapr</code> dot-arrow-pipe, but an important design distinction. Names and objects on the right side of the pipe can explicitly specify stand-in or surrogate functions or effects. The idea was already present in allowing <code>5 %.>% sin</code> to be a shorthand for <code>5 %.>% sin(.)</code>. We have merely generalized the surrogate effect and added explicit control points.</p>
<p>To extend the <code>ggplot2</code> effects to use stored values, we first examine the classes of the items we want rules for.</p>
<div>
<pre><code><span>class</span>(line)</code></pre>
</div>
<pre><code>## [1] &quot;LayerInstance&quot; &quot;Layer&quot;         &quot;ggproto&quot;       &quot;gg&quot;</code></pre>
<div>
<pre><code><span>class</span>(title)</code></pre>
</div>
<pre><code>## [1] &quot;labels&quot;</code></pre>
<p>Notice <code>title</code> is not of class <code>gg</code>, so it will need its own rule.</p>
<p>The new S3 right-dispatch rules are.</p>
<div>
<pre><code>apply_right.gg &lt;-<span> </span>function(pipe_left_arg,
                           pipe_right_arg,
                           pipe_environment,
                           left_arg_name,
                           pipe_string,
                           right_arg_name) {
  pipe_left_arg +<span> </span>pipe_right_arg 
}

apply_right.labels &lt;-<span> </span>function(pipe_left_arg,
                               pipe_right_arg,
                               pipe_environment,
                               left_arg_name,
                               pipe_string,
                               right_arg_name) {
  if(!(<span>&quot;gg&quot;</span> %in%<span> </span><span>class</span>(pipe_left_arg))) {
    <span>stop</span>(<span>&quot;apply_right.labels expected left argument to be class-gg&quot;</span>)
  }
  pipe_left_arg +<span> </span>pipe_right_arg 
}</code></pre>
</div>
<p>And, just for fun, let’s assign the <code>wrapr</code>-dot-arrow-pipe to the shorter pipe-name <code>%.%</code>. Unlike <code>magrittr</code> pipe the dot-arrow-pipe semantics do not depend on the name of the pipe.</p>
<div>
<pre><code><span>`</span><span>%.%</span><span>`</span> &lt;-<span> </span>wrapr::<span>`</span><span>%.>%</span><span>`</span></code></pre>
</div>
<p>With these rules in place we can now build up a <code>ggplot2</code> combining data processing, in-line steps, and stored layers/items.</p>
<div>
<pre><code><span>data.frame</span>(<span>x =</span> <span>1</span>:<span>20</span>) %.%
<span> </span><span>mutate</span>(., <span>y =</span> <span>cos</span>(<span>3</span>*x)) %.%
<span> </span><span>ggplot</span>(., <span>aes</span>(<span>x =</span> x,  <span>y =</span> y)) %.%
<span> </span><span>geom_point</span>() %.%
<span> </span>line %.%
<span> </span>title</code></pre>
</div>
<div>
<img border="0" src="https://i2.wp.com/www.win-vector.com/blog/wp-content/uploads/2018/10/unnamed-chunk-9-1.png?resize=336%2C240" alt="Unnamed chunk 9 1" width="336" title="unnamed-chunk-9-1.png" data-recalc-dims="1" height="240"></div>
<p>More details on <code>wrapr</code> dot-arrow-pipe can be found in the <a rel="nofollow" href="https://journal.r-project.org/archive/2018/RJ-2018-042/index.html" target="_blank">RJournal article</a>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://www.win-vector.com/blog/2018/10/piping-into-ggplot2/"> R – Win-Vector Blog</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 rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/ZR0sPf1AIcs" height="1"></a></div>