title: R - pass fixed columns to lapply function in data.table
body: <p>I have a data.table with columns <code>p1</code>, <code>p2</code>, ... which contains percentages. I want to compute the quantiles for each columns given a reference variable <code>val</code>. Conceptually, this is like:</p>
  
  <pre><code>quantile(val, p1, type = 4, na.rm = T)
  quantile(val, p2, type = 4, na.rm = T)
  ...
  </code></pre>
  
  <p>My attempt at using data.table is as follows:</p>
  
  <pre><code>fun &lt;- function(x, y) quantile(y, x, type = 4, na.rm = T)
  dt[, c('q1', 'q2') := lapply(.SD, fun), .SDcols = c('p1', 'p2'), by = grp]
  where grp is some grouping variable
  </code></pre>
  
  <p>However, I am having trouble specifying the <code>y</code> variable in a way that keeps it fixed.</p>
  
  <p>I tried the following:</p>
  
  <pre><code>fun &lt;- function(x, y, dt) quantile(dt[, y], x, type = 4, na.rm = T)
  dt[, c('q1', 'q2') := lapply(.SD, fun, y, dt), .SDcols = c('p1', 'p2'), by = grp]
  </code></pre>
  
  <p>But doing it this fashion does not enforce the grouping when the quantiles are computed. It will compute the quantile based on the whole range of the <code>y</code> variable instead of the <code>y</code> within groups. What is the correct way to do this?</p>
  
  <p>EDIT:</p>
  
  <p>Here is a trivial example of just one variable:</p>
  
  <pre><code>&gt; dt &lt;- data.table(y = 1:10, p1 = rep(seq(0.2, 1, 0.2), 2), g = c(rep('a', 5), rep('b', 5)))
  &gt; dt
       y  p1 g
   1:  1 0.2 a
   2:  2 0.4 a
   3:  3 0.6 a
   4:  4 0.8 a
   5:  5 1.0 a
   6:  6 0.2 b
   7:  7 0.4 b
   8:  8 0.6 b
   9:  9 0.8 b
  10: 10 1.0 b
  &gt; fun &lt;- function(x, dt, y) quantile(dt[, y], x, type = 4, na.rm = T)
  &gt; dt[, c('q1') := lapply(.SD, fun, dt, y), .SDcols = c('p1'), by = c('g')]
  &gt; dt
       y  p1 g q1
   1:  1 0.2 a  2
   2:  2 0.4 a  4
   3:  3 0.6 a  6
   4:  4 0.8 a  8
   5:  5 1.0 a 10
   6:  6 0.2 b  2
   7:  7 0.4 b  4
   8:  8 0.6 b  6
   9:  9 0.8 b  8
  10: 10 1.0 b 10
  </code></pre>
  
  <p>You can see q1 is computed using the entire range of <code>y</code>. </p>