Come fare un'operazione di fusione data.table
-
19-09-2019 - |
Domanda
Nota: questa domanda e le seguenti risposte si riferiscono a versioni data.table <1.5.3; V. 1.5.3 è stato rilasciato nel febbraio 2011 per risolvere questo problema vedere un trattamento più recente (03-2012):. Translating SQL unisce su chiavi esterne alla R data.table sintassi
Ho scavato attraverso la documentazione per i dati del . pacchetto tavolo (una sostituzione per data.frame che è molto più efficiente per alcune operazioni), compreso presentazione di Josh Reich su SQL e data.table al NYC R Meetup (pdf), ma non riesco a capire questa operazione del tutto banale fuori.
> x <- DT(a=1:3, b=2:4, key='a')
> x
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> y <- DT(a=1:3, c=c('a','b','c'), key='a')
> y
a c
[1,] 1 a
[2,] 2 b
[3,] 3 c
> x[y]
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> merge(x,y)
a b c
1 1 2 a
2 2 3 b
3 3 4 c
La documentazione dice "Quando [il primo argomento] è di per sé un data.table, un join viene invocato simile a basare :: merge, ma usa la ricerca binaria sul tasto ordinato." Chiaramente questo non è il caso. Posso ottenere le altre colonne di y nel risultato di x [y] con data.tables? Sembra come se fosse solo prendendo le file di x in cui la chiave corrisponde alla chiave di y, ma ignorando il resto di y del tutto ...
Soluzione
che stai citando parte sbagliata della documentazione. Se si dispone di uno sguardo al documento di [.data.table
potrete leggere:
Quando i è un data.table, x deve avere una chiave, significato unirsi da I a X e ritorno le righe in x che corrispondono . Un equi-join viene effettuata tra ogni colonna i ad ogni colonna in chiave di x in ordine. Questo è simile basare R funzionalità di sub modificando una matrice da una matrice 2-colonna e in alto dimensioni subsetting un n-dimensionale matrice da una matrice n-colonna
Lo ammetto la descrizione del pacchetto (la parte che hai citato) è un po 'confusa, perché sembra dire che il "[" -operation può essere usato al posto di unione. Ma penso che quello che dice è:. Se x ed y sono entrambi data.tables usiamo un join su un indice (che viene richiamato come merge) al posto di ricerca binaria
Ancora una cosa:
La biblioteca data.table ho installato tramite install.packages
mancava l'merge.data.table method
, in modo da utilizzare merge
chiamerebbe merge.data.frame
. Dopo aver installato il pacchetto rel="noreferrer"> href="http://r-forge.r-project.org/projects/datatable/" R usato il metodo più veloce merge.data.table
.
È possibile controllare se avete il metodo merge.data.table controllando l'output di:
methods(generic.function="merge")
EDIT [risposta non è più valida]: Questa risposta si riferisce alla data.table versione 1.3. Nella versione 1.5.3 il comportamento di data.table cambiato e x [y] restituisce i risultati attesi. Grazie Matthew Dowle , autore di data.table, per la precisazione nei commenti.
Altri suggerimenti
Grazie per le risposte. Mi mancava questa discussione quando è stato originariamente pubblicato. data.table è andato avanti da febbraio. 1.4.1 è stato rilasciato per Cran qualche tempo fa e 1.5 è presto. Per esempio l'alias DT () è stato sostituito con la lista (); come un primitivo la sua molto più veloce, e data.table ora eredita da data.frame in modo che funziona con i pacchetti che solo accettare data.frame come ggplot e reticolare, senza alcuna conversione richiesta (più veloce e più conveniente ).
E 'possibile iscriversi al tag data.table in modo da ottenere una e-mail quando qualcuno invia una domanda con quel tag? L'elenco DataTable-aiuto è cresciuta fino a circa 30-40 messaggi al mese, ma sono felice di rispondere anche qui se posso ottenere un qualche tipo di notifica.
Matthew
Credo che utilizza la funzione base::merge
non è necessario, come l'utilizzo data.table
unisce può essere molto più veloce. Per esempio. vedere quanto segue. Faccio x
e y
data.tables con 3-3 colonne:
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)
e si fondono sia con base:merge
e data.table
si unisce a vedere la velocità di esecuzioni:
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
I risultati non sono identici, in quanto quest'ultimo presenta una colonna supplementare:
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
Il che non potrebbe fare un grosso guaio:)
Credo che f3lix sia corretto e che la documentazione è un po 'fuorviante. Il vantaggio sta nel fare un veloce join sottoinsieme dei dati. È ancora in ultima analisi, è necessario utilizzare la funzione merge
in seguito come nel tuo esempio sopra.
Si vedrà in presentazione di Josh sull'utilizzo dei dati .table che questo è come il suo esempio viene eseguito. In primo luogo ha sottoinsiemi una delle data.tables, poi fa una fusione:
library(data.table)
sdt <- DT(series, key='series_id')
ddt <- DT(data, key='series_id')
u <- sdt[ grepl('^[A-Z]{2}URN', fred_id) & !grepl('DSURN', fred_id) ]
d <- ddt[ u, DT(min=min(value)), by='series_id', mult='all']
data <- merge(d,series)[,c('title','min','mean','max')]