title: Defining an infix operator for use within a formula
body: <p>I'm trying to create a more parsimonious version of <a href="https://stats.stackexchange.com/a/172698/69374">this</a> solution, which entails specifying the RHS of a formula in the form <code>d1 + d1:d2</code>.</p>
  
  <p>Given that <code>*</code> in the context of a formula is a pithy stand-in for full interaction (i.e. <code>d1 * d2</code> gives <code>d1 + d2 + d1:d2</code>), my approach has been to try and define an alternative operator, say <code>%+:%</code> using the infix approach I've grown accustomed to in other applications, <em>a la</em>:</p>
  
  <pre><code>"%+:%" &lt;- function(d1,d2) d1 + d2 + d1:d2
  </code></pre>
  
  <p>However, this predictably fails because I haven't been careful about evaluation; let's introduce an example to illustrate my progress:</p>
  
  <pre><code>set.seed(1029)
  v1 &lt;- runif(1000)
  v2 &lt;- runif(1000)
  y &lt;- .8*(v1 &lt; .3) + .2 * (v2 &gt; .25 &amp; v2 &lt; .8) - 
    .4 * (v2 &gt; .8) + .1 * (v1 &gt; .3 &amp; v2 &gt; .8)
  </code></pre>
  
  <p>With this example, hopefully it's clear why simply writing out the two terms might be undesirable:</p>
  
  <pre><code>y ~ cut(v2, breaks = c(0, .25, .8, 1)) +
    cut(v2, breaks = c(0, .25, .8, 1)):I(v1 &lt; .3)
  </code></pre>
  
  <p>One workaround which is close to my desired output is to define the whole formula as a function:</p>
  
  <pre><code>plus.times &lt;- function(outvar, d1, d2){
    as.formula(paste0(quote(outvar), "~", quote(d1),
                      "+", quote(d1), ":", quote(d2)))
  }
  </code></pre>
  
  <p>This gives the expected coefficients when passed to <code>lm</code>, but with names that are harder to interpret directly (especially in the real data where we take care to give <code>d1</code> and <code>d2</code> descriptive names, in contrast to this generic example):</p>
  
  <pre><code>out1 &lt;- lm(y ~ cut(v2, breaks = c(0, .25, .8, 1)) +
               cut(v2, breaks = c(0, .25, .8, 1)):I(v1 &lt; .3))
  out2 &lt;- lm(plus.times(y, cut(v2, breaks = c(0, .25, .8, 1)), I(v1 &lt; .3)))
  any(out1$coefficients != out2$coefficients)
  # [1] FALSE
  names(out2$coefficients)
  # [1] "(Intercept)"         "d1(0.25,0.8]"        "d1(0.8,1]"           "d1(0,0.25]:d2TRUE"  
  # [5] "d1(0.25,0.8]:d2TRUE" "d1(0.8,1]:d2TRUE"
  </code></pre>
  
  <p>So this is less than optimal.</p>
  
  <p>Is there any way to define the adjust the code so that the infix operator I mentioned above works as expected? How about altering the form of <code>plus.times</code> so that the variables are not renamed?</p>
  
  <p>I've been poking around (<code>?formula</code>, <code>?"~"</code>, <code>?":"</code>, <code>getAnywhere(formula.default)</code>, <a href="https://stackoverflow.com/questions/8055508/the-tilde-operator-in-r/8055683#8055683">this</a> answer, etc.) but haven't seen how exactly R interprets <code>*</code> when it's encountered in a formula so that I can make my desired minor adjustments.</p>