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

时间:2013-03-27 19:42:20

标签: r scope data.table

在构建表达式以放入j调用的[.data.table - 插槽时,能够检查和使用.SD的内容通常会很有帮助。< / p>

这种天真的尝试不起作用......

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的价值?

1 个答案:

答案 0 :(得分:14)

根据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)和{{1}离开它并返回到正常的命令行):

Q