17

在构造表达式以放入调用的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

...即使一个名为的变量.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()while .I.N和are)?是否有其他方法可以访问 的值?.GRP.BY.SD

4

1 回答 1

17

根据 Matthew Dowle 的评论更新:

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

相反,充分利用 R 对参数的惰性求值,它预览未求值的j表达式,并且只添加到.SD其中引用的列。如果.SD提到它本身,它会添加所有DT的列。

因此,要查看.SD,只需在 - 表达式中包含对它的一些引用j。这是可以使用的许多表达式之一:

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]
于 2013-03-27T20:01:41.893 回答