如何在data.table中实现J()函数?

yue*_*uez 12 r data.table

我最近了解了优雅的R包data.table.我很想知道该J函数是如何在那里实现的.此函数绑定到函数[.data.table,它在全局环境中不存在.

我下载了源代码但是J在那里找不到这个函数的定义.我发现了lockBind(".SD", ...),但没有J.知道这个功能是如何实现的吗?

非常感谢.

Aru*_*run 14

J()曾经出口过,但自1.8.8以来没有.以下是来自的说明1.8.8:

J()别名现已删除之外 DT[...],但仍然会在里面工作DT[...]; 即,DT[J(...)]很好.正如在v1.8.2中所述(在此文件中见下文)并warning()在v1.8.4中弃用.这解决了与J()XLConnect(#1747)和rJava(#2045)中的功能冲突.请data.table()直接使用,而不是在J()外面DT[...].

使用R的惰性评估,J(.)检测并简单地list(.)使用(不可见)非导出函数替换.massagei.

也就是说,当你这样做时:

require(data.table)
DT = data.table(x=rep(1:5, each=2L), y=1:10, key="x")
DT[J(1L)]
Run Code Online (Sandbox Code Playgroud)

iJ(1L)检查(= )其类型并执行此行:

i = eval(.massagei(isub), x, parent.frame())
Run Code Online (Sandbox Code Playgroud)

其中,isub = substitute(i).massagei很简单:

.massagei = function(x) {
    if (is.call(x) && as.character(x[[1L]]) %chin% c("J","."))
        x[[1L]] = quote(list)
    x
}
Run Code Online (Sandbox Code Playgroud)

基本上,data.table:::.massagei(quote(J(1L)))执行返回list(1L),然后转换为data.table.从那里,很明显join必须发生.