在构建表达式以放入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
的价值?
答案 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