J() 以前是导出的,但从 1.8.8 开始就没有了。这是来自1.8.8的注释:
o J() 别名现已被删除在DT[...] 外部,但仍可在DT[...] 内部工作;即,DT[J(...)] 很好。正如 v1.8.2 中的警告(请参阅此文件中的下文)并在 v1.8.4 中以 warning() 弃用。这解决了与 XLConnect (#1747) 和 rJava (#2045) 包中的函数 J() 的冲突。请在DT[...]之外直接使用data.table()而不是J()。
使用 R 的 惰性评估,J(.) 被检测到,并使用(不可见的)非导出函数 .massagei 简单地替换为 list(.)。
也就是说,当你这样做时:
require(data.table)
DT = data.table(x=rep(1:5, each=2L), y=1:10, key="x")
DT[J(1L)]
检查i (= J(1L)) 的类型并执行此行:
i = eval(.massagei(isub), x, parent.frame())
isub = substitute(i) 和 .massagei 只是:
.massagei = function(x) {
if (is.call(x) && as.character(x[[1L]]) %chin% c("J","."))
x[[1L]] = quote(list)
x
}
基本上,data.table:::.massagei(quote(J(1L))) 被执行,它返回 list(1L),然后转换为 data.table。从那里,很明显join 必须发生。