2013-03-27 4 views
13

Durante la costruzione di espressioni da inserire nello j -slot di una chiamata [.data.table, sarebbe spesso utile poter esaminare e giocare con il contenuto di .SD.Can .SD può essere visualizzato da un browser all'interno di [.data.table()?

Questo tentativo ingenuo non funziona ...

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 

... anche se una variabile denominata .SD e molti altri legati alla corrente sottoinsieme data.table sono tutti presenti nell'ambiente locale

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 

Utilizzando .I, posso osservare qualcosa di simile +/- .SD, ma sarebbe bello essere in grado di accedere direttamente il suo valore:

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

Le mie domande: Perché il valore atteso di .SD non direttamente disponibili all'interno di una chiamata browser() (mentre .I, .N, .GRP e .BY sono)? C'è un modo alternativo per accedere al valore di .SD?

+2

ho vinto der, al momento viene chiamato 'browser()', '.SD' è effettivamente popolato con qualcosa? 'str (.SD)' mostra 'Classes 'data.table' e 'data.frame': \t 0 obs. di 0 variabili' ecc –

+0

@ GavinSimpson - Penso che probabilmente stai facendo qualcosa lì. La risposta parziale che ho appena aggiunto sembra un'ulteriore prova in quella direzione. Mi chiedo anche se la valutazione ritardata di '.SD' sia in qualche modo coinvolta. –

risposta

14

aggiornamento alla luce dei commenti di Matteo Dowle:

Si scopre che .SD è, internamente, l'ambiente in cui vengono valutati tuttej espressioni, comprese quelle che non fanno riferimento esplicitamente .SD a tutti . Riempirlo con tutte le colonne di DT per ogni sottoinsieme di DT non è economico, a tempo, quindi [.data.table() non lo farà a meno che non sia davvero necessario.

Invece, facendo grande uso della valutazione pigra degli argomenti di R, prevede l'espressione non valutata j e aggiunge solo alle colonne .SD a cui si fa riferimento in esso. Se si menziona lo stesso .SD, vengono aggiunte tutte le colonne di DT.

Quindi, per visualizzare .SD, includere solo alcuni riferimenti ad esso nell'expressione j. Ecco uno di molte espressioni che funzioneranno:

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 

e qui ci sono un paio di più:

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

per vedere di persona che .SD carichi solo le colonne necessarie per il j -expression, eseguire questi ogni a sua volta (digitando .SD quando entra nell'ambiente del browser, e Q di lasciarlo e tornare alla normale linea di comando):

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

FWIW, 'DT [, {. SD; browser()}, per = x] 'funziona anche. –

+0

Sezione 2.1 di [i 'dati.table' FAQ] (http://datatable.r-forge.r-project.org/datatable-faq.pdf) si riferisce all'enorme rallentamento che l'uso di '.SD' può comportare. –

+0

Josh, non proprio. la sezione 2.1 delle FAQ consiglia di usare '.SD', ma * not * con' with = FALSE'. ** ** L'oggetto SD viene implementato in modo efficiente internamente e più efficiente del passaggio di un argomento a una funzione. Si prega di non fare questo però: 'DT [,. SD [," vendite ", con = FALSE], da = grp]' ** **. – Arun