Description
The problem occurs with both CRAN version and latest dev of dplyr.
When I'm trying to create some closures to simplify some work, I found the following errors.
Fails with closure produced in a package function
A minimal reproducible example:
library(dplyr)
library(data.table)
When the following function is evaluated in global environment, it works fine.
test <- function(data, fun) {
function(...) {
fun(data,...)
}
}
> f <- test(as.data.table(mtcars), filter)
> head(f(mpg <= mean(mpg)),1)
mpg cyl disp hp drat wt qsec vs am gear carb
1: 18.7 8 360.0 175 3.15 3.44 17.02 0 0 3 2
> f <- test(as.data.table(mtcars), mutate)
> head(f(m = mpg * 2),1)
mpg cyl disp hp drat wt qsec vs am gear carb m
1: 21 6 160 110 3.9 2.62 16.46 0 1 4 4 42
However, if test()
is defined and exported in a package, it does not work any more when data
is a data.table
and fun
is a dplyr verb function. For example,
# in some package
#' @export
test <- function(data, fun) {
function(...) {
fun(data,...)
}
}
> f <- test(as.data.table(mtcars), filter)
> head(f(mpg <= mean(mpg)))
Error in `[.data.frame`(x, i, j) : object 'mpg' not found
> f <- test(as.data.table(mtcars), mutate)
> f(m = mpg * 2)
Error in `:=`(m, mpg * 2) :
Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").
Fails with ordinary package function
After some testing, I found that the original problem is a bit indirect. The same problem occurs simply with ordinary function as long as it is defined in a package.
If I evaluate the following function in global environment, it works fine.
test1 <- function(data, fun, ...) {
fun(data,...)
}
> head(test1(as.data.table(mtcars), mutate, m = mpg * 2),1)
mpg cyl disp hp drat wt qsec vs am gear carb m
1: 21 6 160 110 3.9 2.62 16.46 0 1 4 4 42
If test1()
is a package function like
#' @export
test1 <- function(data, fun, ...) {
fun(data,...)
}
then it no longer works (same problems occur as shown in previous section)
> head(test1(as.data.table(mtcars), mutate, m = mpg * 2),1)
Error in `:=`(m, mpg * 2) :
Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").
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 dplyr_0.2.0.99 pipeR_0.4-1
loaded via a namespace (and not attached):
[1] assertthat_0.1 magrittr_1.1.0 parallel_3.1.1 plyr_1.8.1 Rcpp_0.11.2
[6] reshape2_1.4 stringr_0.6.2 tools_3.1.1
See also: renkun-ken/pipeR#28.