title: R: Group by and Apply a general function to two columns
body: <p>Hi I'd like to groupby two dataframe columns, and apply a function to aother two dataframe columns.
  For e.g.,</p>
  <pre><code>ticker &lt;- c(&quot;A&quot;, &quot;A&quot;, 'A', &quot;B&quot;, &quot;B&quot;, &quot;B&quot;)
  date &lt;- c(1,1,2,1,2,1)
  ret &lt;- c(1,2,4,6,9,5)
  vol &lt;- c(3,5,1,6,2,3)
  dat &lt;- data.frame(ticker,date,ret,vol)
  </code></pre>
  <p>For each ticker and each date, I'd like to calculate its PIN.</p>
  <p>Now, to avoid further confusion, perhaps it helps to just speak out the actual function. YZ is a function in the InfoTrad package, and YZ only accepts a dataframe with two columns. It uses some optimisation tool and returns an estimated PIN.</p>
  <pre><code>install.packages(InfoTrad)
  library(InfoTrad)
  get_pin_yz &lt;- function(data) {
    return(YZ(data[ ,c('volume_krw_buy', 'volume_krw_sell')])[['PIN']])
  }
  </code></pre>
  <p>I know how to do this in R using for loop. But for loop is very computationally costly, and it might take weeks to finish running my large dataset. Thus, I would like to ask how to do this using groupby.</p>
  <pre><code># output format is wide wrt long format as &quot;dat&quot;
  dat_w &lt;- data.frame(ticker = NA, date = NA, PIN = NA)
  for (j in c(&quot;A&quot;, &quot;B&quot;)){
    
    for (k in c(1:2)){
      
      subset &lt;- dat %&gt;% subset((ticker == j &amp; date == k), select = c('ret', &quot;vol&quot;))
      new_row &lt;- data.frame(ticker = j, date = k, PIN = YZ(subset)$PIN)
      dat_w &lt;- rbind(dat_w, new_row)
    }
  }
  dat_w &lt;- dat_w[-1, ]
  dat_w
  </code></pre>
  <p>Don't know if this can help you help me -- I know how to do this in python: I just write a function and run <code>df.groupby(['ticker','date']).apply(function)</code>.</p>
  <p>Finally, the wanted dataframe is:</p>
  <pre><code>ticker &lt;- c('A','A','B','B')
  date &lt;- c(1,2,1,2)
  PIN &lt;- c(1.05e-17,2.81e-09,1.12e-08,5.39e-09)
  data.frame(ticker,date,PIN)
  </code></pre>
  <p>Could somebody help out, please?</p>
  <p>Thank you!</p>
  <p>Best,</p>
  <p>Darcy</p>
  <hr />
  <p>Previous stuff (Feel free to ignore)
  Previously, I wrote this:
  My function is:</p>
  <pre><code>get_rv &lt;- function(data) {
    return(data[['vol']] + data[['ret']])
  }
  </code></pre>
  <p>What I want is:</p>
  <pre><code>ticker_wanted &lt;- c('A','A', 'B', 'B')
  date_wanted &lt;- c(1,2,1,2)
  rv_wanted &lt;- c(7,5,10,11)
  df_wanted &lt;-data.frame(ticker_wanted,date_wanted,rv_wanted)
  </code></pre>
  <p>But this is not literally what my actual function is. The vol+ret is just an example. I'm more interested in the more general case: how to groupby and apply a general function to two or more dataframes. I use the vol + ret just because I didn't want to bother others by asking them to install some potentially irrelevant package on their PC.</p>