Reputation: 5013
Consider the following function:
test <- function(x,...) {
# in practical case, it does more
x[...]
}
Then the wrapper function that calls subsetting does not work in a local environment.
> library(data.table)
> m <- data.table(x=1:3,key="x")
> m[J(1)]
x
1: 1
> local({i <- 1; m[J(i)]})
x
1: 1
> local({i <- 1; test(m, J(i))})
Error in eval(expr, envir, enclos) : object 'i' not found
> local({i <- 1; test(m, i)})
Error in eval(expr, envir, enclos) : object 'i' not found
It is probably because test()
does not try find symbols in that environment. However, if I change data.table
to data.frame
and run the last line, it works fine.
> m <- data.frame(x=1:3)
> local({i <- 1; test(m, i)})
x
1 1
2 2
3 3
How can I modify test()
so that it can work with ...
and subsetting for data.table
?
My session info:
> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.9.2
loaded via a namespace (and not attached):
[1] plyr_1.8.1 Rcpp_0.11.2 reshape2_1.4 stringr_0.6.2 tools_3.1.1
Upvotes: 2
Views: 303
Reputation: 206506
It makes sense that it wouldn't work because the [...]
for data.table takes an expression that's evaluated in the parent.frame. So in this case J(i)
would be evaluated in the environment of test()
since that's where it's called from. Since test()
is defined in the global environment, any variables not found in test()
will be searched for in the global environment by default. The test()
function is not really related to the local environment you've created. You could change the test()
function to be evaluated in it's parent.frame. For example
test <- function(x,...) {
cc <- match.call()
cc[[1]] <- quote(`[`)
names(cc)[2]<-"" #make data.frame happy
eval.parent(cc)
}
Test data
library(data.table)
m <- data.table(x=1:3,key="x")
n <- data.frame(x=1:3)
And now the function
local({i <- 1; m[J(i)]})
# x
# 1: 1
local({i <- 1; test(m, J(i))})
# x
# 1: 1
local({i <- 1; test(n, i)})
# x
# 1 1
# 2 2
# 3 3
i<-2
test(m, J(i))
# x
# 1: 2
Upvotes: 5