在构造表达式以放置在j
调用的[.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
的值?
最佳答案
根据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]
关于r - 可以通过[.data.table()中的浏览器查看.SD吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15667984/