2013-03-27 12 views
13

Podczas konstruowania wyrażeń służących do wywoływania j -slotę połączenia [.data.table, często byłoby pomocne, aby móc badać i odtwarzać z zawartością .SD.Można .SD być wyświetlane z przeglądarki w [.data.table()?

Ta naiwna próba nie działa ...

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 

... choć zmienna o nazwie .SD i kilka innych związanych z bieżącym data.table podzbioru są obecne w środowisku lokalnym

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 

Korzystanie .I, mogę zobaczyć coś +/- jak .SD, ale byłoby miło, aby móc bezpośredni dostęp do jego wartości:

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

Moje pytania: Dlaczego jest wartość oczekiwana .SD nie są bezpośrednio dostępne z poziomu browser() rozmowy (podczas .I, .N, .GRP i .BY są)? Czy jest jakiś alternatywny sposób uzyskania dostępu do wartości .SD?

+2

Wygrałem der, w czasie wywoływanym 'browser()', czy '.SD' jest wypełnione czymkolwiek? 'str (.SD)' pokazuje 'Klasy 'data.table' i 'data.frame': \t 0 obs. 0 zmiennych "itp. –

+0

@GavinSimpson - Myślę, że prawdopodobnie coś tam znajdziesz. Częściowa odpowiedź, którą właśnie dodałem, wydaje się dodatkowym dowodem w tym kierunku. Zastanawiam się również, czy opóźniona ocena '.SD' jest w jakiś sposób zaangażowana. –

Odpowiedz

14

aktualizowane w świetle Matthew Dowle za komentarze:

Okazuje się, że .SD jest wewnętrznie, środowisko, w którym wszystkiej wyrażenia są oceniane, łącznie z tymi, które nie są wyraźnie odwoływać .SD w ogóle . Wypełnienie go wszystkimi kolumnami DT dla każdego podzbioru DT nie jest tanie, czasowe, więc [.data.table() nie zrobi tego, chyba że naprawdę tego potrzebuje.

Zamiast tego, korzystając z leniwej oceny argumentów R, wyświetla podgląd niedoszacowanego wyrażenia j i dodaje tylko kolumny .SD, które są w nim przywoływane. Jeśli wspomniano o samej .SD, dodaje ona wszystkie kolumny DT.

Tak więc, aby wyświetlić .SD, wystarczy dołączyć do niego odniesienie w j -expression. Oto jeden z wielu wyrażeń, które będą pracować:

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 

A oto jeszcze kilka:

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

Aby przekonać się, że .SD tylko ładuje kolumn wymaganych przez j -expression uruchom nich każdy z kolei (wpisując .SD przy wejściu środowisku przeglądarki, a Q go opuścić i wrócić do normalnej linii poleceń):

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] 'również działa. –

+0

Sekcja 2.1 ["dane.table 'FAQ] (http://datatable.r-forge.r-project.org/datatable-faq.pdf) odnosi się do ogromnego spowolnienia, które może pociągnąć za sobą użycie '.SD'. –

+0

Josh, niezupełnie. sekcja 2.1 FAQ często zaleca użycie '.SD', ale * nie * z' with = FALSE'. ** ** Obiekt SD jest efektywnie implementowany wewnętrznie i wydajniejszy niż przekazywanie argumentów do funkcji. Nie rób tego jednak: 'DT [,. SD [," sprzedaż ", z = FALSE], by = grp]' ** **. – Arun