2011-01-21 15 views
13

UPDATE: Vecchio domanda ... è stato risolto da v1.5.3 data.table nel febbraio 2011.R: Quando si utilizza data.table come faccio a ottenere colonne di y quando faccio x [y]?

Sto cercando di usare il pacchetto data.table, e davvero come gli incrementi nella velocità sto ottenendo, ma stumped da questo errore quando faccio x[y, <expr>] dove x e y sono "data-tavoli" con la stessa chiave, e <expr> contiene i nomi delle colonne di entrambi x e y:

require(data.table) 
x <- data.table(foo = 1:5, a = 5:1) 
y <- data.table(foo = 1:5, boo = 10:14) 
setkey(x, foo) 
setkey(y, foo) 
> x[y, foo*boo] 
Error in eval(expr, envir, enclos) : object 'boo' not found 

aggiornamento regolare TE ... Per chiarire la funzionalità Sto cercando nell'esempio di cui sopra: ho bisogno di fare l'equivalente di quanto segue:

with(merge(x,y), foo*boo) 

Tuttavia, secondo l'estratto di sotto della data.table FAQ, questo dovrebbe hanno lavorato :

Infine, anche se sembra come se x [y] non restituisce le colonne in y, si può effettivamente utilizzare le colonne da y nell'espressione j. Questo è ciò che intendiamo per per join dell'ambito ereditato. Perché non basta restituire l'unione di tutte le colonne da xe ye quindi eseguire le espressioni su quello? Si riduce a eciency del codice e ciò che è più veloce da programmare. Quando scrivi x [y, foo boo], data.table automaticamente ispeziona l'espressione j per vedere quali colonne utilizza. Sarà solo sottoinsieme, o gruppo, solo quelle colonne. La memoria viene creata solo per le colonne utilizzate da j . Diciamo che foo è in xe boo è in y (insieme ad altre 20 colonne in y). Non è x [y, foo boo] più veloce nel programma e più veloce da eseguire di un passaggio di merge seguito da un altro sottogruppo passaggio?

Sono a conoscenza di this question che ha risolto un problema simile, ma non sembra che sia stato risolto in modo soddisfacente. Qualcuno sa cosa mi manca o fraintendimento? Grazie. UPDATE: Ho chiesto sulla mailing list di help della tabella di dati e sull'autore del pacchetto (Matthew Dowle) replied che le FAQ sopra citate sono errate, quindi la sintassi che sto usando non funzionerà al momento, cioè non posso riferirmi a le colonne y nell'argomento j (ie second) quando eseguo x[y,...].

+0

Ma l'hai chiesto qualche tempo fa ed è stato risolto dalla versione 1.5.3 rilasciata a CRAN nel febbraio 2011. Per favore guarda le NEWS, nuove? FAQ.table e corrette. –

+0

@Matthew grazie, sì, so che è stato risolto dall'ultima versione, e sono contento che tu l'abbia indicato qui, quindi è chiaro agli altri. –

risposta

4

Non sono sicuro di aver compreso bene il problema e ho anche appena iniziato a leggere i documenti dei dati .tavolo biblioteca, ma credo che se si desidera ottenere le colonne di y e anche fare qualcosa per coloro che dalle colonne di un, si potrebbe provare qualcosa di simile:

> x[y,a*y] 
    foo boo 
[1,] 5 50 
[2,] 8 44 
[3,] 9 36 
[4,] 8 26 
[5,] 5 14 

Qui, si ottiene indietro le colonne di y moltiplicate per a colonna di x. Se si desidera ottenere x 's foo moltiplicato per y ' s boo, provare:

> y[,x*boo] 
    foo a 
[1,] 10 50 
[2,] 22 44 
[3,] 36 36 
[4,] 52 26 
[5,] 70 14 

Dopo la modifica: grazie @Prasad Chalasani rendere la questione più chiara per me.

Se è preferibile l'unione semplice, il seguente dovrebbe funzionare. Ho fatto un insieme di dati più complessi per vedere le azioni più profondo:

x <- data.table(foo = 1:5, a=20:24, zoo = 5:1) 
y <- data.table(foo = 1:5, b=30:34, boo = 10:14) 
setkey(x, foo) 
setkey(y, foo) 

Quindi solo una colonna in più è stato aggiunto ad ogni data.table. Vediamo merge e farlo con data.tables:

> system.time(merge(x,y)) 
    user system elapsed 
    0.027 0.000 0.023 
> system.time(x[,list(y,x)]) 
    user system elapsed 
    0.003 0.000 0.006 

Da cui quest'ultimo si presenta molto più veloce. I risultati non sono identici, però, ma possono essere utilizzate nello stesso modo (con una colonna in più del secondo run):

> merge(x,y) 
    foo a zoo b boo 
[1,] 1 20 5 30 10 
[2,] 2 21 4 31 11 
[3,] 3 22 3 32 12 
[4,] 4 23 2 33 13 
[5,] 5 24 1 34 14 
> x[,list(x,y)] 
    foo a zoo foo.1 b boo 
[1,] 1 20 5  1 30 10 
[2,] 2 21 4  2 31 11 
[3,] 3 22 3  3 32 12 
[4,] 4 23 2  4 33 13 
[5,] 5 24 1  5 34 14 

in modo da ottenere xy potremmo usare: xy <- x[,list(x,y)]. Per calcolare un data.table una colonna dal xy$foo * xy$boo, quanto segue potrebbe funzionare:

> xy[,foo*boo] 
[1] 10 22 36 52 70 

Ebbene, il risultato non è un data.table ma un vettore, invece.


Aggiornamento (29/03/2012): grazie per @ David per indicare la mia attenzione sul fatto che merge.data.table sono stati utilizzati negli esempi precedenti.

+0

Riferendomi all'esempio nella mia domanda, voglio fare un join di 'x' e' y', chiamiamolo 'xy', e quindi creare un data-frame a colonna singola che sia uguale a' xy $ foo * xy $ boo'. –

+0

@Prasad Chalasani: ho modificato la mia risposta, spero che tu possa trovare qualcosa di nuovo e prezioso in essa. – daroczig

+0

grazie per i dettagli, ma la mia domanda riguardava il motivo per cui la sintassi specifica che descrivo nella mia domanda non funziona, contrariamente a quanto afferma nelle FAQ. So che posso farlo in due fasi (unire, quindi operare su colonne), ma voglio la sintassi 'x [y, ]' per lavorare * in un passo * - cioè fare il join e operare su ' x' e 'y' colonne in un unico passaggio. Questo è sinteticamente meno noioso e possibilmente più veloce (se implementato correttamente internamente). Ho a che fare con frame di dati da 10 milioni di righe, quindi non sono interessato ai tempi del piccolo esempio di giocattoli sopra. –

Problemi correlati