title: Programming-safe version of subset - to evaluate its condition while called from another function
body: <p>As <code>subset()</code> manual states: </p>
  
  <blockquote>
    <p><strong>Warning</strong>: This is a convenience function intended for use interactively</p>
  </blockquote>
  
  <p>I learned from <a href="http://adv-r.had.co.nz/Computing-on-the-language.html" rel="nofollow noreferrer">this great article</a> not only the secret behind this warning, but a good understanding of <code>substitute()</code>, <code>match.call()</code>, <code>eval()</code>, <code>quote()</code>, ‍<code>call</code>, <code>promise</code> and other related R subjects, that are a little bit complicated.</p>
  
  <p>Now I understand what's the warning above for. A super-simple implementation of <code>subset()</code> could be as follows:</p>
  
  <pre><code>subset = function(x, condition) x[eval(substitute(condition), envir=x),]
  </code></pre>
  
  <p>While <code>subset(mtcars, cyl==4)</code> returns the table of rows in <code>mtcars</code> that satisfy <code>cyl==4</code>, enveloping <code>subset()</code> in another function fails:</p>
  
  <pre><code>sub = function(x, condition) subset(x, condition)
  
  sub(mtcars, cyl == 4)
  # Error in eval(expr, envir, enclos) : object 'cyl' not found
  </code></pre>
  
  <p>Using the original version of <code>subset()</code> also produces exactly the same error condition. This is due to the limitation of <code>substitute()-eval()</code> pair: It works fine while <code>condition</code> is <code>cyl==4</code>, but when the <code>condition</code> is passed through the enveloping function <code>sub()</code>, the <code>condition</code> argument of <code>subset()</code> will be no longer <code>cyl==4</code>, but the nested <code>condition</code> in the <code>sub()</code> body, and the <code>eval()</code> fails - it's a bit complicated.</p>
  
  <p>But does it exist any other implementation of <code>subset()</code> with <strong>exactly the same arguments</strong> that would be programming-safe - i.e. able to evaluate its condition while it's called by another function?</p>