title: How to update a `data.table` within `foreach` by reference
body: <p>I read a large <code>.csv</code> file into a <code>data.table</code> using <code>fread</code>. In a next step, I conduct some data cleaning operations such as converting some character variables to dates.</p>
  <h1>Memory optimized solution</h1>
  <p>Here is my memory optimized solution in a MWE:</p>
  <pre><code>library(data.table)
  library(foreach)
  
  dt &lt;- data.table(chr_date_1 = c(&quot;2017-01-01&quot;, &quot;2017-01-02&quot;, &quot;2017-01-03&quot;),
                   chr_date_2 = c(&quot;2017-01-04&quot;, &quot;2017-01-05&quot;, &quot;2017-01-06&quot;))
  
  for (date_var in c(&quot;chr_date_1&quot;, &quot;chr_date_2&quot;)) {
    dt %&gt;% 
      set(j = date_var, value = ymd(.[[date_var]]))
  }
  </code></pre>
  <h1>Speed optimized solution?</h1>
  <p>Since there are 8.5 million observations and ~30 variables which should be manipulated in some way I was wondering if this could be optimized in terms of speed using <code>foreach</code>. (I run R on a Virtual Client with 128GB RAM, so memory is not the primary concern.) My first attempt looked like this:</p>
  <pre><code>registerDoParallel(cores=7)
  
  foreach (date_var = names(dt), .packages = c(&quot;data.table&quot;)) %dopar% {
    set(dt, j = date_var, value = as.Date(dt[[date_var]]))
  }
  </code></pre>
  <p>Unfortunately, this only prints the results in the console instead of updating <code>dt</code>:</p>
  <pre><code>[[1]]
  chr_date_1 chr_date_2
  1: 2017-01-01 2017-01-04
  2: 2017-01-02 2017-01-05
  3: 2017-01-03 2017-01-06
  
  [[2]]
  chr_date_1 chr_date_2
  1: 2017-01-01 2017-01-04
  2: 2017-01-02 2017-01-05
  3: 2017-01-03 2017-01-06
  </code></pre>
  <p>Next, I tried to set up <code>.combine</code> and <code>.init</code>, ...</p>
  <pre><code>foreach (date_var = names(dt), .packages = c(&quot;data.table&quot;),
           .combine = &quot;cbind&quot;, .init = dt) %dopar% {
             set(dt, j = date_var, value = as.Date(dt[[date_var]]))
           }
  </code></pre>
  <p>... but there were new columns added instead of existing ones updated:</p>
  <pre><code>  chr_date_1 chr_date_2 chr_date_1 chr_date_2 chr_date_1 chr_date_2
    1: 2017-01-01 2017-01-04 2017-01-01 2017-01-04 2017-01-01 2017-01-04
    2: 2017-01-02 2017-01-05 2017-01-02 2017-01-05 2017-01-02 2017-01-05
    3: 2017-01-03 2017-01-06 2017-01-03 2017-01-06 2017-01-03 2017-01-06
  </code></pre>
  <p>So, is it possible at all to update several columns of a <code>data.table</code> in parallel using <code>foreach</code>?</p>
  <p>If not, might there be a solution in which I create all new columns in parallel and the somehow merge them into the existing <code>data.table</code>? One aspect which prevented me from elaborating on this is the fact that the last <code>foreach</code> snipped yields the same (<em>4 columns</em>) when I omit <code>.init = dt</code>.</p>
  <hr />
  <h1>EDIT:</h1>
  <p>I found a way of getting the desired result, but in an example with 7 variables (= number of registered cores) and 3M observations, this took approximately 5 times longer than the <em>memory optimized solution</em>. So just for telling you, how <em>not</em> to do it:</p>
  <pre><code>result &lt;- foreach (date_var = names(dt), .packages = c(&quot;data.table&quot;)) %dopar% {
      dt[, (date_var) := lapply(.SD, as.Date, format = &quot;%Y-%m-%d&quot;), .SDcols = date_var]
    } %&gt;% .[[length(.)]]
  </code></pre>
  <p>Also, the needed amount of memory is insane.</p>