<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/r-tip-break-up-function-nesting-for-legibility/"></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/03/r-tip-break-up-function-nesting-for-legibility/"> R – Win-Vector Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>There are a number of easy ways to avoid illegible code nesting problems in <a rel="nofollow" href="https://www.r-project.org/" target="_blank"><code>R</code></a>.</p>
<p>In this <a rel="nofollow" href="http://www.win-vector.com/blog/tag/r-tips/" target="_blank">R tip</a> we will expand upon the above statement with a simple example.</p>
<p><span></span></p>
<p>At some point it becomes illegible and undesirable to compose operations by nesting them, such as in the following code.</p>
<pre>
   head(mtcars[with(mtcars, cyl == 8), c(&quot;mpg&quot;, &quot;cyl&quot;, &quot;wt&quot;)])

#                     mpg cyl   wt
# Hornet Sportabout  18.7   8 3.44
# Duster 360         14.3   8 3.57
# Merc 450SE         16.4   8 4.07
# Merc 450SL         17.3   8 3.73
# Merc 450SLC        15.2   8 3.78
# Cadillac Fleetwood 10.4   8 5.25
</pre>
<p>One popular way to break up nesting is to use <a rel="nofollow" href="https://cran.r-project.org/package=magrittr" target="_blank"><code>magrittr</code></a>‘s “<code>%>%</code>” in combination with <a rel="nofollow" href="https://cran.r-project.org/package=dplyr" target="_blank"><code>dplyr</code></a> transform verbs as we show below.</p>
<pre>
library(&quot;dplyr&quot;)

mtcars                 %>%
  filter(cyl == 8)     %>%
  select(mpg, cyl, wt) %>%
  head

#    mpg cyl   wt
# 1 18.7   8 3.44
# 2 14.3   8 3.57
# 3 16.4   8 4.07
# 4 17.3   8 3.73
# 5 15.2   8 3.78
# 6 10.4   8 5.25
</pre>
<p>Note: the above code lost (without warning) the row names that are part of <code>mtcars</code>. We also pass over the details of how pipe notation works. It is sufficient to say the notational convention is: each stage is approximately treated as an altered function call with a new inserted first argument set to the value of the pipeline up to the current point.</p>
<p>Many <code>R</code> users <em>already</em> routinely avoid nested notation problems through a convention I call “name re-use.” Such code looks like the following.</p>
<pre>
result &lt;- mtcars
result &lt;- filter(result, cyl == 8)
result &lt;- select(result, mpg, cyl, wt)
head(result)
</pre>
<p>The above convention is enough to get around all problems of nesting. It also has the great advantage that it is step-debuggable.</p>
<p>I like a variation I call “dot intermediates”, which looks like the code below (notice we are switching back from <code>dplyr</code> verbs, to base <code>R</code> operators).</p>
<pre>
. &lt;- mtcars
. &lt;- subset(., cyl == 8)
. &lt;- .[, c(&quot;mpg&quot;, &quot;cyl&quot;, &quot;wt&quot;)]
result &lt;- .
head(result)

#                     mpg cyl   wt
# Hornet Sportabout  18.7   8 3.44
# Duster 360         14.3   8 3.57
# Merc 450SE         16.4   8 4.07
# Merc 450SL         17.3   8 3.73
# Merc 450SLC        15.2   8 3.78
# Cadillac Fleetwood 10.4   8 5.25
</pre>
<p>The dot intermediate convention is very succinct, and we can use it with base <code>R</code> transforms to get a correct (and performant) result. Like all conventions: it is just a matter of teaching, learning, and repetition to make this seem natural, familiar and legible.</p>
<pre>
library(&quot;dplyr&quot;)
library(&quot;microbenchmark&quot;)
library(&quot;ggplot2&quot;)

timings &lt;- microbenchmark(
  base = {
    . &lt;- mtcars
    . &lt;- subset(., cyl == 8)
    . &lt;- .[, c(&quot;mpg&quot;, &quot;cyl&quot;, &quot;wt&quot;)]
    nrow(.)
  },
  dplyr = {
    mtcars                 %>%
      filter(cyl == 8)     %>%
      select(mpg, cyl, wt) %>%
      nrow
  })

print(timings)

## Unit: microseconds
##   expr      min       lq      mean   median       uq       max neval
##   base  122.948  136.948  167.2253  159.688  179.924   349.328   100
##  dplyr 1570.188 1654.700 2537.2912 1699.744 1785.611 50759.770   100

autoplot(timings)
</pre>
<p><center><br>
<img border="0" src="https://i1.wp.com/www.win-vector.com/blog/wp-content/uploads/2018/03/Unknown.png?w=660" alt="Unknown" title="Unknown.png" data-recalc-dims="1">
<p>
<p>Durations for related tasks, smaller is better.<br>
</p>
<p><em>Contrary</em> to what many repeat, base <code>R</code> is often faster than the <code>dplyr</code> alternative. In this case the base <code>R</code> is 15 times faster (possibly due to <code>magrittr</code> overhead and the small size of this example). We also see, with some care, base <code>R</code> can be quite legible. <code>dplyr</code> is a useful tool and convention, however it is not the <em>only</em> allowed tool or <em>only</em> allowed convention.</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/03/r-tip-break-up-function-nesting-for-legibility/"> 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/-m3vEz9WxTY" height="1"></a></div></center>