我最近了解到优雅的R包data.table
。我很想知道J
函数是如何在那里实现的。此函数绑定到函数[.data.table
,它在全局环境中不存在。
我下载了源代码但是在那里找不到这个J
函数的定义。我找到了lockBind(".SD", ...)
,但没有J
。知道如何实现这个功能吗?
非常感谢。
答案 0 :(得分:14)
J()
,但是从1.8.8开始导出。以下是1.8.8
的说明:
o
J()
别名现已移除在DT[...]
之外,但仍可在DT[...]
内使用;即,DT[J(...)]
没问题。正如v1.8.2中所述(在此文件中见下文)并在v1.8.4中使用warning()
弃用。这解决了包J()
(#1747)和XLConnect
(#2045)中函数rJava
的冲突。请在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)]
检查 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
必须发生。