<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/writing-pipe-friendly-functions/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://drdoane.com/writing-pipe-friendly-functions/"> R – William Doane</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><span title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.type=&amp;rft.format=text&amp;rft.source=William Doane&amp;rft.date=2018-07-08&amp;rft.identifier=https://DrDoane.com/?p=638&amp;rft.language=English&amp;rft.subject=Programming&amp;rft.subject=R&amp;rft.au=William Doane"></span></p>
<p>Pipes have been a fundamental aspect of computer programming for many decades. In short, the semantics of pipes can be thought of as taking the output from the left-hand side and passing it as input to the right-hand side. For example, in a linux shell, you might <code>cat example.txt | unique | sort</code> to take the contents of a text file, then take one copy of each row, then sort those remaining rows. <code>|</code> is a common, but not universal, pipe operator and on U.S. Qwerty keyboards, is found above the backslash key: <code>\</code>.</p>
<p>Languages that don’t begin by supporting pipes often eventually implement some version of them. In R, the magrittr package introduced the <code>%>%</code> infix operator as a pipe operator and is most often pronounced as “then”. For example, “take the <code>mtcars</code> data.frame, THEN take the <code>head</code> of it, THEN…” and so on.</p>
<p><span></span></p>
<p>For a function to be pipe friendly, it should at least take a data object (often named <code>.data</code>) as its first argument and return an object of the same type—possibly even the same, unaltered object. This contract ensures that your pipe-friendly function can exist in the middle of a piped workflow, accepting the input from its left-hand side and passing along output to its right-hand side.</p>
<pre>library(magrittr)

custom_function &lt;-
  function(.data) {
    message(str(.data))

    .data
  }

mtcars %>%
  custom_function() %>%
  head(10) %>%
  custom_function()</pre>
<p>This will first display the structure of the 32 by 10 <code>mtcars</code> data.frame, then take the <code>head(10)</code> of <code>mtcars</code> and display the structure of that 10 by 10 reduced version, ultimately returning the reduced version which is, by default in R, printed to the console.</p>
<p>The <code>dplyr</code> package in R introduces the notion of a grouped data.frame. For example, in the <code>mtcars</code> data, there is a <code>cyl</code> parameter that classifies each observation as a 4, 6, or 8 cylinder vehicle. You might want to process each of these groups of rows separately—i.e., process all the 4 cylinder vehicles together, then all the 6 cylinder, then all the 8 cylinder:</p>
<pre>library(dplyr)

mtcars %>%
  group_by(cyl) %>%
  tally()</pre>
<p>Note that <code>dplyr</code> re-exports the <code>magrittr</code> pipe operator, so it’s not necessary to attach both <code>dplyr</code> and <code>magrittr</code> explicitly; attaching <code>dplyr</code> will usually suffice.</p>
<p>In order to make my custom function group-aware, I need to check the incoming <code>.data</code> object to see whether it’s a grouped data.frame. If it is, then I can use <code>dplyr</code>‘s <code>do()</code> function to call my custom function on each subset of the data. Here, the <code>(.)</code> notation denotes the subset of <code>.data</code> being handed to <code>custom_function</code> at each invocation.</p>
<pre>library(dplyr)

custom_function &lt;-
  function(.data) {
    if (dplyr::is_grouped_df(.data)) {
      return(dplyr::do(.data, custom_function(.)))
    }

    message(str(.data))

    .data
  }

mtcars %>%
  custom_function() 

mtcars %>%
  group_by(cyl) %>%
  custom_function()</pre>
<p>In these examples, I’ve messaged some metadata to the console, but your custom functions can do any work they like: create, plot, and save ggplots; compute statistics; generate log files; and so on.</p>
<p>I usually include <a rel="nofollow" href="http://www.burns-stat.com/the-three-dots-construct-in-r/" target="_blank">the R three-dots parameter</a>, <code>...</code>,  to allow additional parameters to be passed into the function.</p>
<pre>custom_function &lt;- 
  function(.data, ...) { 
    if (dplyr::is_grouped_df(.data)) {
      return(dplyr::do(.data, custom_function(., ...))) 
    } 

    message(str(.data)) 

    .data 
  }</pre>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://drdoane.com/writing-pipe-friendly-functions/"> R – William Doane</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/y3gJGgqU0B4" height="1"></a></div>