2013-03-27 68 views
13

在构建表达式以放入j调用的时隙时,能够检查并播放.SD的内容通常会很有帮助。可以通过[.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的值?

+2

我赢了der,在调用'browser()'的时候,'.SD'实际上填充了任何东西? 'str(.SD)'显示'类'data.table'和'data.frame':\t 0 obs。 0变量'等 – 2013-03-27 19:58:33

+0

@Gavin辛普森 - 我想你可能会在那里的东西。我刚刚添加的部分答案似乎是朝着这个方向的更多证据。我也想知道是否延迟对'.SD'进行评估。 – 2013-03-27 20:04:12

回答

14

更新了的马修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 -expression所需的列,每列运行这些反过来(进入浏览器环境中键入内容时.SD,并Q离开并返回到正常的命令行):

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

FWIW,'DT [,{。SD;浏览器()},by = x]'也可以。 – 2013-03-27 20:07:35

+0

[数据的第2.1节。table' FAQ](http://datatable.r-forge.r-project.org/datatable-faq.pdf)指的是使用'.SD'可能导致的巨大减速。 – 2013-03-27 20:49:20

+0

乔希,不是真的。 FAQ的第2.1节建议使用'.SD',但* not * with'with = FALSE'。 ** ** SD对象在内部有效地实现并且比向函数传递参数更高效。请不要这样做:'DT [,。SD [,'sales',with = FALSE],by = grp]'** **。 – Arun 2013-03-27 21:08:40

相关问题