Misha
Misha

Reputation: 3126

force the evaluation of .SD in data.table

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:

  1. The environment pane is not updated reflecting the browser environment
  2. I often encounter the following error msg
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

Answers (1)

Alexis
Alexis

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

Related Questions