<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/a-wrapper-around-nested-ifelse/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://edwinth.github.io/blog/ifelse-wrapper/"> That’s so Random</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>The <code>ifelse</code> function is the way to do vectorised <em>if then else</em> in R. One of the first cool things I learned to do in R a few years back, I got from Norman Matloff’s <em>The Art of R Programming</em>. When you have more than one <em>if then</em> statements, you just nest multiple <code>ifelse</code> functions before you reach the <em>else</em>.</p>
<div>
<pre><code><span>set.seed</span><span>(</span><span>0310</span><span>)</span><span>
</span><span>x</span><span> </span><span>&lt;-</span><span> </span><span>runif</span><span>(</span><span>1000</span><span>,</span><span> </span><span>1</span><span>,</span><span> </span><span>20</span><span>)</span><span>
</span><span>y</span><span> </span><span>&lt;-</span><span> </span><span>runif</span><span>(</span><span>1000</span><span>,</span><span> </span><span>1</span><span>,</span><span> </span><span>20</span><span>)</span><span>
</span><span>the_old_way</span><span> </span><span>&lt;-</span><span> </span><span>ifelse</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'A'</span><span>,</span><span>
</span><span>ifelse</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>15</span><span>,</span><span> </span><span>'B'</span><span>,</span><span>
</span><span>ifelse</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'C'</span><span>,</span><span>
</span><span>ifelse</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>15</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'D'</span><span>,</span><span>
</span><span>ifelse</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>15</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>15</span><span>,</span><span> </span><span>'E'</span><span>,</span><span>
</span><span>ifelse</span><span>(</span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'F'</span><span>,</span><span>
</span><span>ifelse</span><span>(</span><span>y</span><span> </span><span>&lt;</span><span> </span><span>15</span><span>,</span><span> </span><span>'G'</span><span>,</span><span>
</span><span>'H'</span><span>)))))))</span><span>
</span></code></pre>
</div>
<p>Although this is very functional and fast, it is not exactly pretty. Matters worsen as the variable names get longer and as the logical expressions get more complicated. During the last session of <em>Friday-afternoon-playground</em> at work, I decided to have a go at cleaning this up a bit and having a look at the <code>lazyeval</code> package along the way. To fully get my mind around the lazy evaluation philosophy, I will need to revisit the vignette a few times. But the wrapper turned out as I intended.</p>
<p>The idea is simple. Get your <em>if then</em> statements in the function <code>i</code>, get your <em>else</em> value in the function <code>e</code>, and stitch those together in <code>ie</code>.</p>
<div>
<pre><code><span>i</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>if_stat</span><span>,</span><span> </span><span>then</span><span>)</span><span> </span><span>{</span><span>
</span><span>if_stat</span><span> </span><span>&lt;-</span><span> </span><span>lazyeval</span><span>::</span><span>expr_text</span><span>(</span><span>if_stat</span><span>)</span><span>
</span><span>then</span><span> </span><span>&lt;-</span><span> </span><span>lazyeval</span><span>::</span><span>expr_text</span><span>(</span><span>then</span><span>)</span><span>
</span><span>sprintf</span><span>(</span><span>&quot;ifelse(%s, %s, &quot;</span><span>,</span><span> </span><span>if_stat</span><span>,</span><span> </span><span>then</span><span>)</span><span>
</span><span>}</span><span>
</span><span>i</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>z</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## [1] &quot;ifelse(x &lt; 5 &amp; y &lt; 5, z, &quot;
</code></pre>
</div>
<p>So <code>i</code> takes the logical expression and the value to return when <code>TRUE</code>. It spits out a string that is the incomplete part of an <code>ifelse</code> function. Next we define the <code>e</code> function that returns the final value if all logical statements in the if-statements are evaluated as <code>FALSE</code>.</p>
<div>
<pre><code><span>e</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>else_ret</span><span>)</span><span> </span><span>{</span><span>
</span><span>else_ret</span><span> </span><span>&lt;-</span><span> </span><span>lazyeval</span><span>::</span><span>expr_text</span><span>(</span><span>else_ret</span><span>)</span><span>
</span><span>else_ret</span><span>
</span><span>}</span><span>
</span></code></pre>
</div>
<p>And finally we stitch them together. You enter as many <code>i</code> functions as you like, but only one <code>e</code> function of course.</p>
<div>
<pre><code><span>ie</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>...</span><span>)</span><span> </span><span>{</span><span>
</span><span>args</span><span> </span><span>&lt;-</span><span> </span><span>list</span><span>(</span><span>...</span><span>)</span><span>
</span><span>for</span><span> </span><span>(</span><span>i</span><span> </span><span>in</span><span> </span><span>1</span><span>:</span><span>(</span><span>length</span><span>(</span><span>args</span><span>)</span><span> </span><span>-</span><span> </span><span>1</span><span>)</span><span> </span><span>)</span><span> </span><span>{</span><span>
</span><span>if</span><span> </span><span>(</span><span>substr</span><span>(</span><span>args</span><span>[[</span><span>i</span><span>]],</span><span> </span><span>1</span><span>,</span><span> </span><span>6</span><span>)</span><span> </span><span>!=</span><span> </span><span>&quot;ifelse&quot;</span><span>)</span><span> </span><span>{</span><span>
</span><span>stop</span><span>(</span><span>&quot;All but the last argument, need to be i functions.&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>}</span><span>
</span><span>if</span><span> </span><span>(</span><span>substr</span><span>(</span><span>args</span><span>[[</span><span>length</span><span>(</span><span>args</span><span>)]],</span><span> </span><span>1</span><span>,</span><span> </span><span>6</span><span>)</span><span> </span><span>==</span><span> </span><span>&quot;ifelse&quot;</span><span>){</span><span>
</span><span>stop</span><span>(</span><span>&quot;Last argument needs to be an e function.&quot;</span><span>,</span><span> </span><span>call.</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>}</span><span>
</span><span>args</span><span>$</span><span>final</span><span> </span><span>&lt;-</span><span> </span><span>paste</span><span>(</span><span>rep</span><span>(</span><span>')'</span><span>,</span><span> </span><span>length</span><span>(</span><span>args</span><span>)</span><span> </span><span>-</span><span> </span><span>1</span><span>),</span><span> </span><span>collapse</span><span> </span><span>=</span><span> </span><span>''</span><span>)</span><span>
</span><span>eval_string</span><span> </span><span>&lt;-</span><span> </span><span>do.call</span><span>(</span><span>'paste'</span><span>,</span><span> </span><span>args</span><span>)</span><span>
</span><span>eval</span><span>(</span><span>parse</span><span>(</span><span>text</span><span> </span><span>=</span><span> </span><span>eval_string</span><span>))</span><span>
</span><span>}</span><span>
</span></code></pre>
</div>
<p>And there we are. Using the power of the nested <code>ifelse</code>, but without the messy code. A whole lot easier to write, read, and debug.</p>
<div>
<pre><code><span>the_new_way</span><span> </span><span>&lt;-</span><span> </span><span>ie</span><span>(</span><span>
</span><span>i</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'A'</span><span>),</span><span>
</span><span>i</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>15</span><span>,</span><span> </span><span>'B'</span><span>),</span><span>
</span><span>i</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'C'</span><span>),</span><span>
</span><span>i</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>15</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'D'</span><span>),</span><span>
</span><span>i</span><span>(</span><span>x</span><span> </span><span>&lt;</span><span> </span><span>15</span><span> </span><span>&amp;</span><span> </span><span>y</span><span> </span><span>&lt;</span><span> </span><span>15</span><span>,</span><span> </span><span>'E'</span><span>),</span><span>
</span><span>i</span><span>(</span><span>y</span><span> </span><span>&lt;</span><span> </span><span>5</span><span>,</span><span> </span><span>'F'</span><span>),</span><span>
</span><span>i</span><span>(</span><span>y</span><span> </span><span>&lt;</span><span> </span><span>15</span><span>,</span><span> </span><span>'G'</span><span>),</span><span>
</span><span>e</span><span>(</span><span>'H'</span><span>)</span><span>
</span><span>)</span><span>
</span><span>all.equal</span><span>(</span><span>the_old_way</span><span>,</span><span> </span><span>the_new_way</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## [1] TRUE
</code></pre>
</div>
<p>These functions can be found in the <a target="_blank" rel="nofollow" href="https://github.com/edwinth/thatssorandom">R package on my github</a>, that accompanies this blog. You can easily install it by running <code>devtools::install_github(&quot;edwinth/thatssorandom&quot;)</code>. Enjoy!</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="https://edwinth.github.io/blog/ifelse-wrapper/"> That’s so Random</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/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/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/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/K6suQ6SVH5U"></a></div>