<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/what-is-tidy-eval-and-why-should-i-care/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://www.mango-solutions.com/blog/what-is-tidy-eval-and-why-should-i-care"> Mango Solutions</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p> <img sizes="100vw" src="https://i0.wp.com/www.mango-solutions.com/blog/images/0/1/8/2/6/01826ca0c431f4d98a7808dbd6d812fc6f4215f6-tidy-blog.png?w=456&ssl=1" data-recalc-dims="1"></p>
<h4><em>Nic Crane, Data Scientist</em></h4>
<p><em>This article was first published on <a rel="nofollow" href="https://thisisnic.github.io/2018/03/29/what-is-tidy-eval-and-why-should-i-care/" target="_blank">Nic Crane’s Blog</a> and kindly contributed to the Mango Blog.</em></p>
<div>
<p>I’m going to begin this post somewhat backwards, and start with the conclusion: tidy eval is important to anyone who writes R functions and uses dplyr and/or tidyr.</p>
<p>I’m going to load a couple of packages, and then show you exactly why.</p>
<pre><code>library(dplyr)
library(rlang)</code></pre>
<div>
<h4>Data wrangling with base R</h4>
<p>Here’s an example function I have written in base R. Its purpose is to take a data set, and extract values from a single column that match a specific value, with both input and output both being in data frame format.</p>
<pre><code>wrangle_data &lt;- function(data, column, val){

  data[data[[column]]==val, column, drop = FALSE]

}

wrangle_data(iris, &quot;Species&quot;, &quot;versicolor&quot;) %>%
  head()</code></pre>
<pre><code>##       Species
## 51 versicolor
## 52 versicolor
## 53 versicolor
## 54 versicolor
## 55 versicolor
## 56 versicolor</code></pre>
<p>It works, but it’s not great; the code is clunky and hard to decipher at a quick glance. This is where using dplyr can help.</p>
</div>
<div>
<h4>Data wrangling with dplyr</h4>
<p>If I was to run the same code outside of the context of a function, I might do something like this:</p>
<pre><code>one_col &lt;- select(iris, Species)
filter(one_col, Species == &quot;versicolor&quot;)  %>%
  head()</code></pre>
<pre><code>##      Species
## 1 versicolor
## 2 versicolor
## 3 versicolor
## 4 versicolor
## 5 versicolor
## 6 versicolor</code></pre>
<p>This has worked, but how can we turn this into a function?</p>
<p>I may naively attempt the solution below</p>
<pre><code>wrangle_data &lt;- function(data, column, val){
  one_col &lt;- select(data, column)
  filter(one_col, column == val)
}

wrangle_data(iris, &quot;Species&quot;, &quot;versicolor&quot;)  %>%
  head()</code></pre>
<pre><code>## [1] Species
## &lt;0 rows> (or 0-length row.names)</code></pre>
<p>However, this doesn’t work and returns 0 rows. This is due to a special quirk of <code>dplyr</code> that makes typical usage easier, but we need to be aware of when writing functions. This snippet from the <code>programming</code> vignette in dplyr explains it best:</p>
<blockquote>
<blockquote>
<p>“Most dplyr functions use non-standard evaluation (NSE). This is a catch-all term that means they don’t follow the usual R rules of evaluation. Instead, they capture the expression that you typed and evaluate it in a custom way. This has two main benefits for dplyr code:</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<ul>
<li>Operations on data frames can be expressed succinctly because you don’t need to repeat the name of the data frame. For example, you can write filter(df, x == 1, y == 2, z == 3) instead of df[df<span>\(x == 1 &amp; df\)</span>y ==2 &amp; df$z == 3, ].</li>
</ul>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<ul>
<li>dplyr can choose to compute results in a different way to base R. This is important for database backends because dplyr itself doesn’t do any work, but instead generates the SQL that tells the database what to do.&quot;</li>
</ul>
</blockquote>
</blockquote>
<p>In other words, because dplyr functions evaluate things differently to base R, by using a concept called <em>quoting</em>, we have to work with them a bit differently. I’d recommend checking out <a rel="nofollow" href="https://www.rstudio.com/resources/webinars/tidy-eval/" target="_blank">this RStudio webinar</a> and the <a rel="nofollow" href="https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html" target="_blank">dplyr programming vignette</a> for more detail.</p>
<p>Let’s go back to the previous example.</p>
<pre><code>wrangle_data &lt;- function(data, column, val){
  one_col &lt;- select(data, column)
  filter(one_col, column == val)
}

wrangle_data(iris, &quot;Species&quot;, &quot;versicolor&quot;)  %>%
  head()</code></pre>
<pre><code>## [1] Species
## &lt;0 rows> (or 0-length row.names)</code></pre>
<p>This doesn’t work as <code>select</code> and <code>filter</code> are looking for a column called “column” in their inputs, and failing to find them. Therefore we must use tidy evaluation to override this behaviour.</p>
</div>
<div>
<h4>Tidy evaluation with dplyr</h4>
<p>Using the <code>!!</code> (bang bang) operator and <code>sym</code> functions from the rlang package, we can change this behaviour to make a version of our function which will run.</p>
<pre><code>wrangle_data &lt;- function(x, column, val){

  one_col &lt;- select(x, !!sym(column))
  filter(one_col, !!sym(column) == val)
}

wrangle_data(iris, &quot;Species&quot;, &quot;versicolor&quot;) %>%
  head()</code></pre>
<pre><code>##      Species
## 1 versicolor
## 2 versicolor
## 3 versicolor
## 4 versicolor
## 5 versicolor
## 6 versicolor</code></pre>
<p>I’m not going to go into detail about these functions here, but if you want more information, check out my blog posts on using tidy eval in dplyr <a rel="nofollow" href="https://thisisnic.github.io/2018/02/20/exploring-tidy-eval-snails-pace/" target="_blank">here</a> and <a rel="nofollow" href="https://thisisnic.github.io/2018/03/27/using-tidy-eval-with-dplyr-filter/" target="_blank">here</a>.</p>
<p>In conclusion, whilst tidy eval is not necessary for all uses of dplyr or tidyr, it quickly becomes an extremely handy tool when working with these packages within the context of function. There are some great resources about tidy eval out there, and as ever, I welcome feedback on this blog post <a rel="nofollow" href="https://twitter.com/nic_crane/status/979360864070459392" target="_blank">via Twitter</a>.</p>
</div>
</div>
	<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://www.mango-solutions.com/blog/what-is-tidy-eval-and-why-should-i-care"> Mango Solutions</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/1nMrQMq3kaY" height="1"></a></div>