2014-02-25 103 views
12

我最近了解到優雅的R包data.table。我很想知道J函數是如何實現的。該函數綁定到函數[.data.table,它不存在於全局環境中。如何在data.table中實現J()函數?

我下載了源代碼,但是我找不到這個J函數在那裏的定義。我發現lockBind(".SD", ...),但不是J。任何想法如何實現這個功能?

非常感謝。

+1

你可能會發現http://adv-r.had.co.nz/dsl.html有助於描述這種事情實現的一般技術。 – hadley

回答

14

J()以前用於導出,但不是自1.8.8以後導出。下面是從1.8.8注:

J()別名現已刪除DT[...],但還在裏面DT[...]工作;即,DT[J(...)]是好的。正如v1.8.2中警告的(見本文檔中的下面),並且在v1.8.4中使用warning()已棄用。這解決了包XLConnect(#1747)和rJava(#2045)中功能J()的衝突。請直接使用data.table()而不是J(),在DT[...]之外。

基於R的惰性計算J(.)被檢測和使用(不可見的)非導出函數.massageilist(.)簡單地更換。

也就是說,當你這樣做:

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必須發生。