".SD和其他类似的data.table特殊变量的命名空间环境是什么?"

4

我知道在R中,如果变量没有在函数内定义,则会向上游搜索。所以我认为特殊的data.table变量,如.SD.N等,也应该是这样。但是这段代码无法正常工作:

data(iris)
setDT(iris)

myFunA <- function(){
  return(nrow(.SD))
}

iris[,myFunA(),by=Species]

有没有一种方法可以在函数内部访问.SD,而不像myFunA(.SD)一样将其作为参数传递?(是的,我知道这通常不是一个好习惯,但对于这种用例,我会纵容它)


4
简短回答是:不行。详细回答是,可能有一些折衷方法可以让它工作,但我建议不要这样做。 - MichaelChirico
3
稍微详细解释一下,我认为您的函数设计有误。.SD 是“此组数据”的缩写。因此,您应编写一个以“某些数据”作为输入的函数,而不是使其基本上依赖于全局变量。 - MichaelChirico
是的,我的意图是编写一个可以与“此组数据”一起使用的函数,因此它将针对每个 by= 组进行调用。这只是一个美学问题:例如,我想看到 myDT[,myFunction(),by=grpCol] 而不是 myDT[,myFunction(.SD, .GRP),by=grpCol]。虽然我不得不回到后者的形式,但这并不是什么大问题,我只是好奇为什么那些变量无法访问的机制。 - Vasily A
1个回答

3

很遗憾,似乎在运行myFunA时,尽管.SD是可访问的,但它没有被填充。不过.N是可用的,就像下面的myFunB一样,因此可以修改问题中的特定示例,使其像myFunB一样工作。

问题似乎在于data.table优化计算以避免填充.SD,如果我们使用了它,那么可以像myFunC中所示那样使其正常工作。

library(data.table)
irisDT <- as.data.table(iris)

myFunA <- function(envir = parent.frame()) with(envir, .SD)
irisDT[, myFunA(), by = Species]
## Empty data.table (0 rows and 1 cols): Species

myFunB <- function(envir = parent.frame()) with(envir, .N)
irisDT[, myFunB(), by = Species]
##       Species V1
## 1:     setosa 50
## 2: versicolor 50
## 3:  virginica 50

myFunC <- function(envir = parent.frame()) with(envir, nrow(.SD))
irisDT[, {.SD; myFunC()}, by = Species]
##       Species V1
## 1:     setosa 50
## 2: versicolor 50
## 3:  virginica 50

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接