2014-02-25 1 views
12

Ich habe vor kurzem über das elegante R-Paket data.table erfahren. Ich bin sehr neugierig zu wissen, wie die J Funktion dort implementiert ist. Diese Funktion ist an die Funktion [.data.table gebunden, sie existiert nicht in der globalen Umgebung.Wie ist die J() Funktion in data.table implementiert?

Ich habe den Quellcode heruntergeladen, aber ich kann die Definition für diese J Funktion nirgends dort finden. Ich fand lockBind(".SD", ...), aber nicht J. Irgendeine Idee, wie diese Funktion implementiert wird?

Vielen Dank.

+1

Sie könnten http://adv-r.had.co.nz/dsl.html hilfreich finden, um die allgemeinen Techniken zu beschreiben, mit denen diese Art von Dingen implementiert wird. – hadley

Antwort

14

J() früher exportiert, aber nicht seit 1.8.8. Hier ist der Hinweis von 1.8.8:

o Die J() alias jetzt außen entfernt wirdDT[...], aber immer noch innerhalb DT[...] arbeiten; d.h. DT[J(...)] ist in Ordnung. Wie in v1.8.2 (siehe unten in dieser Datei) gewarnt und mit warning() in v1.8.4 veraltet. Dies behebt den Konflikt mit der Funktion J() in Paket XLConnect (# 1747) und rJava (# 2045). Bitte verwenden Sie data.table() direkt anstelle von J(), außerhalb DT[...].

Verwenden R lazy evaluation, J(.) detektiert und einfach mit list(.) ersetzt unter Verwendung der (unsichtbare) nicht exportierten Funktion .massagei.

Das heißt, wenn Sie tun:

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

i (= J(1L)) ist bekannt für seine Art überprüft und diese Zeile ausgeführt wird:

i = eval(.massagei(isub), x, parent.frame()) 

wo isub = substitute(i) und .massagei einfach ist:

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

Grundsätzlich data.table:::.massagei(quote(J(1L))) wird ausgeführt, was list(1L) zurückgibt, das dann in data.table konvertiert wird. Und von dort ist klar, dass ein join passieren muss.