Переопределение метода data.table — не удается идеально пересылать аргументы

#r #data.table

#r #data.table

Вопрос:

Я могу успешно изменить поведение [.data.frame , но не могу этого сделать для [.data.table .

Для data.frame:

 # Exact same signature as "[.data.frame" :
"[.my.data.frame" <- function (x, i, j, 
                               drop = if (missing(i)) TRUE 
                                      else length(cols) == 1) {
  if(!missing(j) amp;amp; j==8 ) {
    cat("Oy veyn")
  }
  NextMethod()
}

df <- data.frame(a=1,b=2)
class(df) <- c("my.data.frame", class(df))

# Works as expected:
df[1,2]  # 2
df[1,8]  # Oy Vey    NULL
df[1,]   # 1 2
  

Однако для (значительно более сложного) data.table:

 # Exact same signature as "[.data.table" :
"[.my.data.table" <- function (x, i, j, by, keyby, with = TRUE, nomatch = getOption("datatable.nomatch"), 
                               mult = "all", roll = FALSE, 
                               rollends = if (roll == "nearest") c(TRUE, TRUE) 
                                          else if (roll >= 0) c(FALSE, TRUE) else c(TRUE, FALSE), 
                               which = FALSE, .SDcols, verbose = getOption("datatable.verbose"), 
                               allow.cartesian = getOption("datatable.allow.cartesian"), 
                               drop = NULL, on = NULL) {
  if(!missing(j) amp;amp; j==8 ) {
    cat("Oy veyn")
  }
  NextMethod()
}

dt <- data.table(a=1,b=2)
class(dt) <- c("my.data.table", class(dt))

dt[1,2]   # ERROR:  i is not found in calling scope and it is not a column of type logical. When the first argument inside DT[...] is a single symbol, data.table looks for it in calling scope.
  

Я знаю лучше, чем передавать аргументы в NextMethod. Похоже, я должен вызывать [.data.table явно, захватывать и передавать аргументы как неоценимые обещания — но все мои попытки с quote substitute или match.call до сих пор не увенчались успехом. Любая информация будет оценена.

Ответ №1:

Я нашел частичное решение, публикуя здесь в надежде, что кто-то может улучшить его.

 "[.my.data.table" <- function (x, ...) {

  # Modifications and tests galore - which can be tricky with this signature

  class(x) <- class(x)[-1]
  ret <- x[...]
  class(x) <- c("my.data.table", class(x))
  ret
}
  

Я все еще считаю это частичным, потому что на самом деле выполнение чего-либо в функции, вероятно, включает в себя по крайней мере что-то вроде arglist <- list(...) , и это завершается неудачей, когда [ вызывается так —

 dt[1,]
  

Другие направления по-прежнему приветствуются.