Comment faire une opération de fusion data.table
-
19-09-2019 - |
Question
Note: cette question et les réponses suivantes font référence aux versions data.table <1.5.3; V. 1.5.3 a été publié en février 2011 pour résoudre ce problème voir un traitement plus récent (03-2012). SQL Translating rejoint sur les clés étrangères à la syntaxe R data.table
J'ai fouillais dans la documentation pour les données de la (pour remplacer data.frame qui est beaucoup plus efficace pour certaines opérations), dont présentation de Josh Reich sur SQL et data.table à (pdf) du New York R Meetup, mais ne peut pas comprendre cette opération tout à fait trivial sur.
> 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
Les documents disent « Quand [le premier argument] est lui-même un data.table, une jointure est similaire à la base invoquaient :: fusion, mais utilise la recherche binaire sur la clé de tri. » Il est clair que ce n'est pas le cas. Puis-je obtenir les autres colonnes de y dans le résultat de x [y] avec data.tables? Il semble que c'est juste de prendre les rangées de x où la clé correspond à la clé de y, mais en ignorant le reste de y entièrement ...
La solution
Vous citez la mauvaise partie de la documentation. Si vous avez un oeil à la doc de [.data.table
vous lire:
Quand i est un data.table, x doit avoir un clé, ce qui signifie se joindre à x i et retour les lignes de x qui correspondent à . Un équi-jointure est réalisée entre chaque colonne i à chaque colonne dans la clé de x dans l'ordre. Ceci est similaire à la base R la fonctionnalité de sous-réglage d'une matrice par une matrice à 2 colonnes, et en plus élevés dimensions d'une sous-ensembles à n dimensions matrice par une matrice n-colonne
Je reconnais la description du paquet (la partie que vous avez cité) est un peu déroutant, car il semble dire que le « [ » -operation peut être utilisé au lieu de fusion. Mais je pense que ce qu'il dit est:. Si x et y sont tous deux data.tables nous utilisons une jointure sur un indice (qui est appelé comme fusion) au lieu de recherche binaire
Une autre chose:
La bibliothèque data.table J'ai installé via install.packages
il manquait le merge.data.table method
, donc l'utilisation merge
appellerait merge.data.frame
. Après l'installation du paquet à partir de R-Forge R utilisé la méthode plus rapide merge.data.table
.
Vous pouvez vérifier si vous avez la méthode merge.data.table en vérifiant la sortie:
methods(generic.function="merge")
EDIT [Réponse plus valide]: Cette réponse se réfère à la version 1.3 data.table. Dans la version 1.5.3 le comportement de data.table changé et x [y] renvoie les résultats attendus. Merci Matthew Dowle , auteur de data.table, pour l'avoir signalé dans les commentaires.
Autres conseils
Merci pour les réponses. J'ai raté ce fil quand il a été affiché. data.table a évolué depuis Février. 1.4.1 a été libéré à Cran il y a un moment et 1,5 est bientôt. Par exemple, l'alias DT () a été remplacé par la liste (); comme primitive la plus rapide, et data.table hérite maintenant de data.frame il fonctionne avec des paquets que uniquement acceptent data.frame tels que ggplot et treillis, sans conversion nécessaire (plus rapide et plus pratique ).
Est-il possible de souscrire à l'étiquette data.table si je reçois un e-mail quand quelqu'un poste une question avec cette étiquette? La liste datatable-aide a augmenté à environ 30-40 messages par mois, mais je suis heureux de répondre ici aussi si je peux obtenir une sorte de notification.
Matthieu
Je pense en utilisant la fonction base::merge
n'est pas nécessaire, car l'utilisation data.table
joint peut être beaucoup plus rapide. Par exemple. voir ce qui suit. Je fais data.tables de x
et y
avec 3-3 colonnes:
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)
Et fusionner les deux avec base:merge
et data.table
rejoint pour voir la vitesse des exécutions:
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
Les résultats ne sont pas identiques, comme celui-ci présente une colonne supplémentaire:
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
Ce qui ne pouvait pas faire un gros problème:)
Je pense que f3lix est correcte et que la documentation est un peu trompeur. L'avantage est à faire une jointure rapide au sous-ensemble des données. Vous devez toujours finalement d'utiliser la fonction de merge
ensuite comme dans votre exemple ci-dessus.
Vous verrez dans présentation de Josh sur l'utilisation des données .table que c'est comment son exemple fonctionne. Il a d'abord sous-ensembles l'un des data.tables, fait alors une fusion:
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')]