Подтвердить что ты не робот

Можно ли просматривать .SD из браузера в [.data.table()?

При построении выражений для размещения в j -слоте вызова [.data.table часто было бы полезно иметь возможность исследовать и воспроизводить содержимое .SD.

Эта наивная попытка не работает...

library(data.table)
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)

DT[, browser(), by=x]
# Called from: `[.data.table`(DT, , browser(), by = x)
Browse[1]> 
Browse[1]> .SD
# NULL data.table

... хотя переменная с именем .SD и несколько других, связанных с текущим подмножеством data.table, присутствуют в локальной среде

Browse[1]> ls(all.names = TRUE)
#  [1] ".BY"       ".GRP"      ".I"        ".iSD"      ".N"        ".SD"      
#  [7] "Cfastmean" "mean"      "print"     "x"        
Browse[1]> .N
# [1] 3
Browse[1]> .I
# [1] 4 5 6

Используя .I, я могу просмотреть что-то +/- как .SD, но было бы неплохо иметь возможность прямого доступа к его значению:

Browse[1]> DT[.I]
#    x y v
# 1: b 1 4
# 2: b 3 5
# 3: b 6 6

Мои вопросы: Почему ожидаемое значение .SD недоступно напрямую из-за вызова browser() (тогда как .I, .N, .GRP и .BY)? Есть ли альтернативный способ доступа к значению .SD?

4b9b3361

Ответ 1

Обновлено в свете комментариев Мэтью Доула:

Оказывается, что .SD есть внутренне среда, в которой оцениваются выражения all j, в том числе те, которые явно не ссылаются на .SD вообще. Заполнение его всеми столбцами DT для каждого подмножества DT не является дешевым, поэтому, поэтому [.data.table() не сделает этого, если это действительно не нужно.

Вместо этого, пользуясь R lazy-оценкой аргументов, он просматривает неоценимое выражение j и добавляет только столбцы .SD, на которые они ссылаются. Если упоминается .SD, он добавляет все столбцы DT.

Итак, для просмотра .SD просто включите в него ссылку в j -expression. Вот одно из многих выражений, которые будут работать:

library(data.table)
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)

## This works
DT[, if(nrow(.SD)) browser(), by=x]
# Called from: `[.data.table`(DT, , if (nrow(.SD)) browser(), by = x)
Browse[1]> .SD
#    y v
# 1: 1 1
# 2: 3 2
# 3: 6 3

И вот еще пара:

DT[,{.SD; browser()}, by=x]
DT[,{browser(); .SD}, by=x]  ## Notice that order doesn't matter

Чтобы убедиться, что .SD просто загружает столбцы, необходимые для выражения j, запускайте их поочередно (вводя .SD при входе в среду браузера и Q, чтобы оставить его и вернуться к нормальная командная строка):

DT[, {.N * y ; browser()}, by=x]
DT[, {v^2 ; browser()}, by=x]
DT[, {y*v ; browser()}, by=x]