Reputation: 3126
In order to debug j
in data.table I prefer to interactively inspect the resulting -by
- dt´s with browser()
. SO 2013 adressed this issue and I understand that .SD must be invoked in j
in order for all columns to be evaluated. I use Rstudio and using the SO 2013 method, there are two problems:
Error: option error has NULL value In addition: Warning message: In get(object, envir = currentEnv, inherits = TRUE) : restarting interrupted promise evaluation
I can get around this by doing:
f <- function(sd=force(.SD),.env = parent.frame(n = 1)) {
by = .env$.BY;
i = .env$.I;
sd = .env$.SD;
grp = .env$.GRP;
N = .env$.N;
browser()
}
library (data.table)
setDT(copy(mtcars))[,f(.SD),by=.(gear)]
But - in the data.table
spirit of keeping things short and sweet- can I somehow force (the force
in f
does not work) the evaluation of .SD in the call to f
so that the final code could run:
setDT(copy(mtcars))[,f(),by=.(gear)]
Upvotes: 3
Views: 138
Reputation: 5059
As far as I know,
data.table
needs to explicitly see .SD
somewhere in the code passed to j
,
otherwise it won't even expose it in the environment it creates for the execution.
See for example this question and its comments.
Why don't you create a different helper function that always specifies .SD
in j
?
Something like:
dt_debugger <- function(dt, ...) {
f <- function(..., .caller_env = parent.frame()) {
by <- .caller_env$.BY;
i <- .caller_env$.I;
sd <- .caller_env$.SD;
grp <- .caller_env$.GRP;
N <- .caller_env$.N;
browser()
}
dt[..., j = f(.SD)]
}
dt_debugger(as.data.table(mtcars), by = .(gear))
Upvotes: 3