title: Creating multiple columns from one function (and then averaging over them) in R
body: <p>Starting from:</p>
  <pre><code>dates &lt;- yday(ceiling_date(dmy(sapply(1:11, function(x) paste0(&quot;01/&quot;, x, &quot;/2009&quot;))), &quot;month&quot;) %m-% days(1))
  
  foo &lt;- data.frame(id = 1:1000000) %&gt;%
    mutate(
      datdeb = round(runif(n(), 1, 365)),
      datfin = round(runif(n(), datdeb, 365)),
      etp = runif(n()),
      group = round(runif(n(), 1, 1000))
    )
  </code></pre>
  <p>the most basic version of what I want to do is:</p>
  <pre><code>for(i in 1:11){
    foo &lt;- foo %&gt;%
      group_by(group) %&gt;%
      mutate(
        test = sum((dates[i] &gt;= datdeb &amp; dates[i] &lt;= datfin))
      ) %&gt;%
      rename(!!paste0(&quot;size_date&quot;, dates[i]) := &quot;test&quot;)
  }
  
  res1 &lt;- foo %&gt;%
    mutate(
      m_size = rowMeans(across(starts_with(&quot;size_date&quot;)))
    ) %&gt;%
    group_by(group) %&gt;%
    summarise(
      m_size = mean(m_size)
    )
  </code></pre>
  <p>Now I want to do this in the fastest way possible given that my ultimate dataset I'm applying this on is huge.</p>
  <p>For the first bit the alternative I have come up with is:</p>
  <pre><code>foo &lt;- bind_cols(foo, map_dfc(1:11, ~ foo %&gt;%
                            group_by(group) %&gt;%
                            transmute(!!paste0(&quot;size_date&quot;, dates[.x]) := sum((dates[.x] &gt;= datdeb &amp; dates[.x] &lt;= datfin)))
                            ) %&gt;% select(starts_with(&quot;size_date&quot;)))
  </code></pre>
  <p>But somewhat surpringly to me, this ended up being slower when benchmarked with tictoc.</p>
  <p>For the second part I came up with two other options:</p>
  <pre><code>res2 &lt;- foo %&gt;%
    mutate(
      m_size = rowMeans(across(starts_with(&quot;size_date&quot;)))
    ) %&gt;%
    group_by(group) %&gt;%
    summarise(
      m_size = m_size[1]
    )
  
  res3 &lt;- foo %&gt;%
    group_by(group) %&gt;%
    slice(1) %&gt;%
    mutate(
      m_size = rowMeans(across(starts_with(&quot;size_date&quot;)))
    )
  </code></pre>
  <p>Unsurprisingly the last option is quite a bit faster.</p>
  <p>I was wondering whether there are even faster (and more elegant?) ways of getting this done? In particular, potentially combine the two steps in an intelligent way with a incremental cumulative mean?
  Thanks!</p>