title: bitmap masks, (avoiding of) passing by reference - need advices for code optimization
body: <p>In my datatable, I would like to be able to add some kind of "flags" (error messages) about each record, and keep it in one column (not separate column for each flag). I implemented some solution, but I don't like it and would be grateful for any advices of how this can be done better. I decided to convert my flags to bit mask and store just an integer in my table. Due to that, I have to make separate list of correspondence between number and error text. For adding flags, I made a function, which takes condition (i.e. which records should be flagged), error text, and name of variable containing existing errors.</p>
  
  <pre><code># sample table:
  dt1 &lt;- data.table(colA=c(2,5,4,8), 
                    colB=c('foo', 'bar', 'xyz', 'qwe') )
  dt1
  #&gt; dt1
  #   colA colB
  #1:    2  foo
  #2:    5  bar
  #3:    4  xyz
  #4:    8  qwe
  
  # main function which adds a flag:
  # dtIn      - data.table containing our records
  # condition - expression defines which records will be flagged
  # flagtxt   - text of error message
  # inpArrName- name of the variable which contains existing flags list
  adderrb &lt;- function(dtIn, condition, flagtxt, inpArrName="flagsList"){
    wEnv &lt;- globalenv(); # environment needed to modify variable with flags list
  
    if (exists(inpArrName, envir=wEnv )){ # check if variable with flags list is defined
      inpArr &lt;- get(inpArrName, envir = wEnv); # then use it
    } else {inpArr &lt;- array(dim=0);} # otherwise create it as an empty array
  
    newval &lt;- match(flagtxt, inpArr); # trying to find requested flag text in current list, to avoid duplication
  
    if (length(newval)==0 || is.na(newval)) { # if this flag text isn't in list
      newval &lt;- length(inpArr)+1; # we will add it as new member
      inpArr[newval] &lt;- flagtxt;
      assign(inpArrName, inpArr, envir=wEnv); # modify variable in parent (global) variable
    }
  
    # adding flags to the 'errors' column of our table
    eval.parent(substitute({ # 
      if (!is.element('errors', names(dtIn))) {dtIn[,errors:=0L];} # if this column did not exist, create it, initialize with 0L
      dtIn[condition, errors:=bitwOr(errors, 2^(newval-1))]; # for records which meet condition, we add new flad to existing mask
      invisible(dtIn);
    })); # 
  
  }
  
  # example of usage:
  adderrb(dt1, colA&gt;3,      "A&gt;3!",   "errorList")
  adderrb(dt1, colB=="xyz", "B=xyz!", "errorList")
  dt1
  #&gt; dt1
  #   colA colB errors
  #1:    2  foo      0
  #2:    5  bar      1
  #3:    4  xyz      3
  #4:    8  qwe      1
  
  # for human-readable form, we can later convert bitmask to list of errors - as their numbers, or as their text:
  # for this, I use a helper function converting bitmask from number to list of binary orders,
  # for example: 
  # 2L = '010', so int2bitsV(4) = 2 
  # 4L = '100', so int2bitsV(4) = 3 
  # 6L = '110', so int2bitsV(4) = 2, 3 
  int2bitsV &lt;- function(x) { which(as.logical(intToBits(x)), T);}
  
  # here's how it works
  dt1$errList &lt;- sapply(dt1$errors, function(x){paste0("e", int2bitsV(x),  collapse = "; ");})
  dt1$errText &lt;- sapply(dt1$errors, function(x){errorList[int2bitsV(x)]})
  dt1
  #&gt; dt1
  #   colA colB errors errList     errText
  #1:    2  foo      0       e            
  #2:    5  bar      1      e1        A&gt;3!
  #3:    4  xyz      3  e1; e2 A&gt;3!,B=xyz!
  #4:    8  qwe      1      e1        A&gt;3!
  </code></pre>
  
  <p>Overall, this works as I want, but I don't like that I have to mess with <code>globalenv()</code>, and also not sure about how I use bitmasks - maybe there's some nicer way to store flags?</p>