title: Multi windows range calculations data.table vs dplyr
body: <p>I'm doing range calculations (i.e. max and min) over multiple windows on stocks returns. 
  I have my version in dplyr, but many people publishing benchmarking where calculations with data.table are much faster. I've created the version with data.table syntax, however it's slower than dplyr one.
  Could anyone help me to find better way to use data.table to make it faster?
  Many thanks.</p>
  
  <pre><code>library(Quandl)
  library(tidyr)
  library(dplyr)
  library(data.table)
  library(microbenchmark)
  
  tickers &lt;- c("GOOG/NASDAQ_AAPL", "GOOG/NASDAQ_MSFT", 
               "GOOG/NYSE_IBM", "GOOG/NASDAQ_GOOG") 
  
  data &lt;- Quandl(tickers,transformation = "rdiff")
  
  returns &lt;- gather(data, stock, value, -Date) %&gt;%
      separate(stock, c("name", "field"), " - ") %&gt;%
      filter(
         field == "Close"
      ) %&gt;%
      select(
         - field
      )
  
  returns_dt &lt;- data.table(returns)
  
  multi_window_range &lt;- function(data) {
      result_1y &lt;- data %&gt;%
          filter(
              Date &gt;= Sys.Date() - 365
          ) %&gt;% 
          group_by(name) %&gt;%
          summarise(
              max_1y = max(value, na.rm = TRUE),
              min_1y = min(value, na.rm = TRUE)
          )
      result_2y &lt;- data %&gt;%
          filter(
              Date &gt;= Sys.Date() - 365 * 2
          ) %&gt;%
          group_by(name) %&gt;%
          summarise(
              max_2y = max(value, na.rm = TRUE),
             min_2y = min(value, na.rm = TRUE)
         )
      result_5y &lt;- data %&gt;%
          filter(
              Date &gt;= Sys.Date() - 365 * 5
          ) %&gt;%
          group_by(name) %&gt;%
          summarise(
              max_5y = max(value, na.rm = TRUE),
              min_5y = min(value, na.rm = TRUE)
          )
      return(inner_join(inner_join(result_1y, result_2y, by = "name"), result_5y, by = "name"))
  }
  
  multi_window_range_dt &lt;- function(data) {
      setkey(data, name)
      result_1y &lt;- data[Date &gt;= Sys.Date() - 365,
                        list(
                          max_1y = max(value, na.rm = TRUE),
                          min_1y = min(value, na.rm = TRUE)
                        ), by = "name"]
     result_2y &lt;- data[Date &gt;= Sys.Date() - 365 * 2,
                       list(
                          max_2y = max(value, na.rm = TRUE),
                          min_2y = min(value, na.rm = TRUE)
                       ), by = "name"]
     result_5y &lt;- data[Date &gt;= Sys.Date() - 365 * 5,
                       list(
                          max_5y = max(value, na.rm = TRUE),
                          min_5y = min(value, na.rm = TRUE)
                       ), by = "name"]
     return(result_1y[result_2y][result_5y])
  }
  
  microbenchmark(
      multi_window_range(returns),
      multi_window_range_dt(returns_dt)
  )
  
  
  Unit: milliseconds
                                expr      min       lq     mean   median       uq      max neval
         multi_window_range(returns) 6.341532 6.522303 6.915266 6.692666 6.922623 10.16709   100
   multi_window_range_dt(returns_dt) 7.537073 7.738516 8.066579 7.865968 8.073114 12.68021   100 
  </code></pre>