2013-03-27 7 views
13

Bei der Konstruktion von Ausdrücken, die in den j -Slot eines [.data.table Aufrufs eingefügt werden, wäre es oft hilfreich, in der Lage zu sein, den Inhalt von .SD zu untersuchen und mit ihm herumzuspielen.Kann .SD von einem Browser in [.data.table() angezeigt werden?

Dieser naive Versuch nicht funktioniert ...

library(data.table) 
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 

DT[, browser(), by=x] 
# Called from: `[.data.table`(DT, , browser(), by = x) 
Browse[1]> 
Browse[1]> .SD 
# NULL data.table 

... obwohl eine Variable .SD und einige andere im Zusammenhang mit der aktuellen data.table Teilmenge genannt sind alle in der lokalen Umgebung

Browse[1]> ls(all.names = TRUE) 
# [1] ".BY"  ".GRP"  ".I"  ".iSD"  ".N"  ".SD"  
# [7] "Cfastmean" "mean"  "print"  "x"   
Browse[1]> .N 
# [1] 3 
Browse[1]> .I 
# [1] 4 5 6 

.I benutzen, kann ich etwas +/- wie .SD sehen, aber es wäre schön, der Lage sein, den direkten Zugriff auf seinen Wert:

Browse[1]> DT[.I] 
# x y v 
# 1: b 1 4 
# 2: b 3 5 
# 3: b 6 6 

Meine Fragen: Warum ist der Erwartungswert von .SD nicht direkt zur Verfügung innerhalb eines browser() Anrufs (während .I, .N, .GRP und .BY sind)? Gibt es eine alternative Möglichkeit, auf den Wert .SD zuzugreifen?

+2

ich gewonnen der, zu der Zeit 'browser()' genannt wird, ist '.SD' eigentlich mit irgendwas bevölkert? 'str (.SD)' zeigt 'Classes 'data.table' und 'dat.frame': \t 0 obs. von 0 Variablen usw. –

+0

@GavinSimpson - Ich denke, Sie sind wahrscheinlich auf etwas da. Die teilweise Antwort, die ich gerade hinzugefügt habe, scheint wie ein zusätzlicher Beweis in diese Richtung zu sein. Ich frage mich auch, ob eine verzögerte Auswertung von '.SD' irgendwie beteiligt ist. –

Antwort

14

im Lichte der Kommentare Matthew Dowle Aktualisiert:

Es stellt sich heraus, dass .SD ist, intern, die Umgebung, in der allej Ausdrücke ausgewertet werden, einschließlich derjenigen, die ausdrücklich .SD verweisen nicht auf allen . Füllen Sie es mit allen DT 's Spalten für jede Teilmenge von DT ist nicht billig, zeitweise, so [.data.table() wird es nicht tun, es sei denn, es muss wirklich.

Stattdessen nutzt R die Lazy-Bewertung von Argumenten ausgiebig, es zeigt eine Vorschau des nicht bewerteten Ausdrucks j an und fügt nur .SD Spalten hinzu, auf die darin verwiesen wird. Wenn .SD selbst erwähnt wird, fügt es alle Spalten DT hinzu.

Also, um .SD anzuzeigen, nur einen Verweis auf es in der j-Ausdruck enthalten. Hier ist eine von vielen Ausdrücke, die funktioniert:

library(data.table) 
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 

## This works 
DT[, if(nrow(.SD)) browser(), by=x] 
# Called from: `[.data.table`(DT, , if (nrow(.SD)) browser(), by = x) 
Browse[1]> .SD 
# y v 
# 1: 1 1 
# 2: 3 2 
# 3: 6 3 

Und hier sind ein paar mehr:

DT[,{.SD; browser()}, by=x] 
DT[,{browser(); .SD}, by=x] ## Notice that order doesn't matter 

für sich selbst zu sehen, dass .SD nur Spalten lädt benötigt durch die j -Ausdrucks, führen diese jeweils wiederum (Eingabe .SD wenn der Browser-Umgebung eingeben und Q es zu verlassen und in der normalen Befehlszeile zurück):

DT[, {.N * y ; browser()}, by=x] 
DT[, {v^2 ; browser()}, by=x] 
DT[, {y*v ; browser()}, by=x] 
+1

FWIW, 'DT [, {. SD; browser()}, by = x] 'funktioniert auch. –

+0

Abschnitt 2.1 von [die Daten.Tabelle "FAQ" (http://datatable.r-forge.r-project.org/datatable-faq.pdf) bezieht sich auf die enorme Verlangsamung, die die Verwendung von '.SD' zur Folge haben kann. –

+0

Josh, nicht wirklich. Abschnitt 2.1 von FAQ empfiehlt die Verwendung von '.SD', aber * nicht * mit' mit = FALSE'. ** ** SD-Objekt wird effizient intern implementiert und effizienter als ein Argument an eine Funktion übergeben. Bitte tu dies jedoch nicht: 'DT [,. SD [," sales ", mit = FALSE], by = grp]' ** **. – Arun

Verwandte Themen