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内から直接利用できないのはなぜですか (while 、、およびare)? の値にアクセスする別の方法はありますか?browser().I.N.GRP.BY.SD

4

1 に答える 1

17

Updated in light of Matthew Dowle's comments:

It turns out that .SD is, internally, the environment within which all j expressions are evaluated, including those which don't explicitly reference .SD at all. Filling it with all of DT's columns for each subset of DT is not cheap, timewise, so [.data.table() won't do so unless it really needs to.

Instead, making great use of R's lazy-evaluation of arguments, it previews the unevaluated j expression, and only adds to .SD columns that are referenced therein. If .SD itself is mentioned, it adds all of DT's columns.

So, to view .SD, just include some reference to it in the j-expression. Here is one of many expressions that will work:

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

And here are a couple more:

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

To see for yourself that .SD just loads columns needed by the j-expression, run these each in turn (typing .SD when entering the browser environment, and Q to leave it and return to the normal command-line):

DT[, {.N * y ; browser()}, by=x]
DT[, {v^2 ; browser()}, by=x]
DT[, {y*v ; browser()}, by=x]
于 2013-03-27T20:01:41.893 に答える