note: cette question et les réponses suivantes se réfèrent aux versions de data.table <1.5.3; v. 1.5.3 a été publié en février 2011 pour résoudre ce problème. voir le traitement plus récent (03-2012): Traduire les jointures SQL sur les clés étrangères en syntaxe R data.table
J'ai parcouru la documentation du package data.table (un remplacement de data.frame qui est beaucoup plus efficace pour certaines opérations), y compris Présentation de Josh Reich sur SQL et les données. table au NYC R Meetup (pdf), mais ne peut pas comprendre cette opération totalement triviale.
> 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 "Lorsque [le premier argument] est lui-même un data.table, une jointure est invoquée de la même manière que base :: merge mais utilise une recherche binaire sur la clé triée." Ce n'est clairement pas le cas. Puis-je obtenir les autres colonnes de y dans le résultat de x [y] avec data.tables? Il semble que cela prenne simplement les lignes de x où la clé correspond à la clé de y, mais en ignorant complètement le reste de y ...
Vous citez la mauvaise partie de la documentation. Si vous regardez le doc de [.data.table
vous lirez:
Lorsque i est une table de données, x doit avoir une clé, ce qui signifie joindre i à x et renvoyer les lignes de x qui correspondent . Une équi-jointure est effectuée entre chaque colonne de i et chaque colonne de la clé de x dans l'ordre. Ceci est similaire à la fonctionnalité de base R de sous-paramétrage d'une matrice par une matrice à 2 colonnes, et dans les dimensions supérieures sous-ensemble d'un tableau à n dimensions par une matrice à n colonnes
J'admets que la description du paquet (la partie que vous avez citée) est quelque peu déroutante, car elle semble dire que l'opération "[" peut être utilisée à la place de la 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 index (qui est invoquée comme fusion) au lieu de la recherche binaire.
Encore une chose:
La bibliothèque data.table que j'ai installée via install.packages
manquait le merge.data.table method
, donc utiliser merge
appeler merge.data.frame
. Après avoir installé le paquet de R-Forge R utilisé le plus rapide merge.data.table
méthode.
Vous pouvez vérifier si vous disposez de la méthode merge.data.table en vérifiant la sortie de:
methods(generic.function="merge")
EDIT [La réponse n'est plus valide]: Cette réponse fait référence à data.table version 1.3. Dans la version 1.5.3, le comportement de data.table a changé et x [y] renvoie les résultats attendus. Merci Matthew Dowle , auteur de data.table, pour l'avoir signalé dans les commentaires.
Merci pour les réponses. J'ai raté ce fil lorsqu'il a été initialement publié. data.table a évolué depuis février. La version 1.4.1 a été publiée sur CRAN il y a quelque temps et la version 1.5 est bientôt disponible. Par exemple, l'alias DT () a été remplacé par list (); en tant que primitive, c'est beaucoup plus rapide, et data.table hérite désormais de data.frame donc il fonctionne avec des packages qui niquement acceptent data.frame tels que ggplot et lattice, sans aucune conversion requise (plus rapide et plus pratique ).
Est-il possible de s'abonner à la balise data.table pour que je reçoive un e-mail lorsque quelqu'un poste une question avec cette balise? La liste d'aide datatable est passée à environ 30 à 40 messages par mois, mais je suis heureux de répondre ici aussi si je peux recevoir une sorte de notification.
Matthieu
Je pense qu'en utilisant le base::merge
la fonction n'est pas nécessaire, car l'utilisation de data.table
les jointures peuvent être beaucoup plus rapides. Par exemple. voir ce qui suit. Je crée x
et y
data.tables 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 fusionnez les deux avec base:merge
et data.table
se joint 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, car ce dernier a 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 de gros problèmes :)
Je pense que f3lix est correct et que la documentation est un peu trompeuse. L'avantage est d'effectuer une jointure rapide pour sous-définir les données. Vous devez finalement utiliser la fonction merge
par la suite comme dans votre exemple ci-dessus.
Vous verrez dans la présentation de Josh sur l'utilisation de data.table que c'est ainsi que son exemple fonctionne. Il sous-ensemble d'abord l'un des data.tables, puis fait 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')]