可以从[.data.table()中的浏览器查看.SD吗?

Jos*_*ien 17 scope r data.table

在构造表达式以放入调用的j-slot时[.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
Run Code Online (Sandbox Code Playgroud)

...即使名为变量的变量.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
Run Code Online (Sandbox Code Playgroud)

使用.I,我可以查看+/-类似的东西.SD,但能够直接访问它的值会很好:

Browse[1]> DT[.I]
#    x y v
# 1: b 1 4
# 2: b 3 5
# 3: b 6 6
Run Code Online (Sandbox Code Playgroud)

我的问题:为什么的预期值.SD从内不能直接browser()调用(同时.I,.N,.GRP.BY是什么)?有没有其他方法来获取价值.SD

Jos*_*ien 17

根据Matthew Dowle的评论更新:

事实证明,.SD在内部,评估所有 j表达式的环境,包括那些根本没有明确引用.SD的环境.用DT每个子集的所有列填充它DT 并不便宜,时间,[.data.table()所以除非确实需要,否则不会这样做.

相反,它充分利用了R对参数的惰性评估,它预览了未评估的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
Run Code Online (Sandbox Code Playgroud)

还有以下几点:

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

要自己查看.SD只是加载j-expression 所需的列,请依次运行这些列(.SD在进入浏览器环境时键入,并Q保留并返回到正常的命令行):

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

  • +1确切地说是.在`j`中仅存在符号`.SD`会触发`.SD`以填充该子集的所有列.否则,`.SD`只填充`j`需要的列.在内部,在C级,`.SD`是评估`j`的静态环境.它是所有魔法发生的地方,无论```是否被`j`用作(作为符号).这就是FAQ 3.1第1点所指的内容.这就是为什么我们建议不要使用`.SD`,除非`j`确实需要所有列和它的所有行(例如`DT [,lapply(.SD,sum),by = ...]`). (9认同)
  • 这完全归功于R中的懒惰参数评估.这就是为什么`data.table`在R中,而不是Python或Julia的一个原因.如果没有R的懒惰评估,就不可能在评估之前检查`i`和`j`并优化它们,iiuc. (3认同)
  • @MatthewDowle感谢您在这里的深刻见解.一切都很有趣. (3认同)