Zhaochen He
Zhaochen He

Reputation: 660

data.table: column name same as variable name

I'm trying to filter a data.table when a column name is the same as a variable in my environment.

dt = data.table(myvar = 1:10)
myvar = 2
dt[myvar %in% myvar]

Result:

   myvar
 1:     1
 2:     2
 3:     3
 4:     4
 5:     5
 6:     6
 7:     7
 8:     8
 9:     9
10:    10

Desired result:

   myvar
1:     2

Upvotes: 2

Views: 279

Answers (2)

mnist
mnist

Reputation: 6954

To use get and avoid .SD, you need to set the environment

dt <- data.table::data.table(myvar = 1:10)
myvar <- 2
dt[myvar %in% get("myvar", envir = parent.env(environment()))]
#>    myvar
#> 1:     2

Using parent.env(environment()) instead of globalenv() is more stable. Consider its usage in a function where looking in the Global Environment would not work

myfun <- function() {
  dt <- data.table::data.table(myvar = 1:10)
  myvar <- 2
  dt[myvar %in% get("myvar", envir = parent.env(environment()))]
}
myfun()
#>    myvar
#> 1:     2

Upvotes: 1

r2evans
r2evans

Reputation: 160742

You can use the ..varname method. However, it only works in the j (second) argument, not the i (first), so while

dt[myvar %in% ..myvar,]
# Error in eval(stub# [[3L]], x, enclos) : object '..myvar' not found

fails, you can do

dt[, .SD[myvar %in% ..myvar,]]
#    myvar
#    <int>
# 1:     2

If you are interested in testing the not-yet-CRAN version of data.table (currently 1.14.5), then you can instead use the env= feature:

packageVersion("data.table")
# [1] '1.14.5'
dt[ myvar %in% Z, env = list(Z = myvar)]
#    myvar
#    <int>
# 1:     2

Upvotes: 3

Related Questions