R data.table scoping, reliably refer to unknown column name using variable

Viewed 185

I want to allow users of my function to use arbitrary column names, and I need to refer to these in a data.table. Getting a column name from a var works except when the name of the var is also a column of the dt. I would like a solution to modify my reference approach (i.e. get(id) ) so that it works in the case where the variable and column name overlap, as well as the case where they don't -- with data.table v1.14.0 when a column has the same name as the variable (which contains the desired column reference), the column takes precedence which breaks the get(id).

dt=data.table(id='id1') 
id='id'
dt[get(id) %in% 'id1',] #fails

dt=data.table(subject='id1') 
id='subject'
dt[get(id) %in% 'id1',] #works

There are quite some questions related to referencing column names via variables, but I couldn't find a solution that avoids this kind of corner case where the user happens to use the same column names as my reference variables.

2 Answers

Proper solution for these kind of problems has been recently implemented in data.table. There is new env argument which does not have a local-data.table scoping. Users no longer need to use get.

library(data.table)
dt=data.table(id='id1') 
id='id'
dt[.id %in% 'id1', env=list(.id=id)]
#       id
#   <char>
#1:    id1

Because it is not on CRAN as of now, you need to install data.table from our CRAN-like repo. Note that we publish windows binaries as well, so Rtools is not necessary. Most simple way to install from our repo is:

data.table::update.dev.pkg()

Here's an approach with quote and eval.parent:

library(data.table)
dt=data.table(id='id1') 
id='id'
dt[get(eval.parent(quote(id),1)) %in% 'id1',]
#    id
#1: id1
Related