49 votes

Comment faire une opération de fusion data.table

remarque: cette question et les réponses suivantes se référer à des données.tableau des versions < 1.5.3; v. 1.5.3 a été publié en Février 2011 pour résoudre ce problème. voir plus récentes de traitement (03-2012): la Traduction des jointures SQL sur les clés étrangères pour R des données.syntaxe de tableau


J'ai été fouiller dans la documentation pour les données.tableau paquet (un remplaçant pour les données.cadre qui est beaucoup plus efficace pour certaines opérations), y compris Josh Reich présentation sur SQL et des données.table à NYC R Meetup (pdf), mais ne peut pas trouver cela totalement banale opération de l'extérieur.

> 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 docs disent que "Lorsque [le premier argument] est lui-même un ensemble de données.table, une jointure est invoquée similaire à la base: fusion, mais utilise les binaires de recherche sur le tri de la clé." Clairement, ce n'est pas le cas. Puis-je obtenir de l'autre les colonnes de y dans la suite de x[y] avec les données.les tables? Il semble que c'est juste de prendre les lignes de x, où la clé correspondant à la clé de y, mais en ignorant le reste de y tout à fait...

29voto

f3lix Points 13634

Vous citez la mauvaise partie de la documentation. Si vous avez un coup d'oeil à la doc de l' [.data.table vous lire:

Quand je est un ensemble de données.tableau, x doit avoir un clé, sens de jointure de i à x et retour les lignes de x qui correspondent. Une équi-jointure est effectué entre chaque colonne, je pour chaque colonne de x-clés dans l'ordre. Ceci est similaire à la base de R la fonctionnalité de sous - paramètre une matrice par un 2-colonne de la matrice, et en plus dimensions subsetting un n-dimensionnelle tableau par un n-colonne de la matrice

J'avoue que la description de l'ensemble (la partie que vous avez cité) est un peu déroutant, car il semble dire que le "["-opération peut être utilisé à la place de fusion. Mais je pense que ce qu'il dit est: si x et y sont données.des tableaux, nous utilisons une jointure sur un indice (qui est invoquée comme la fusion) au lieu de binaire de recherche.


Une chose de plus:

Les données.la table de la bibliothèque, j'ai installé via install.packages manquait l' merge.data.table method, donc à l'aide d' merge appellerais merge.data.frame. Après avoir installé le package de R-Forge R utilisé le plus rapide merge.data.table méthode.

Vous pouvez vérifier si vous avez de la fusion.les données.tableau par la méthode de vérification de la sortie de:

methods(generic.function="merge")

EDIT [Réponse n'est plus valide]: Cette réponse fait référence à des données.le tableau de la version 1.3. Dans la version 1.5.3 le comportement de données.tableau changé et x[y] renvoie les résultats attendus. Merci Matthieu Dowle, auteur de données.table, pour le signaler dans les commentaires.

14voto

Matt Dowle Points 20936

Merci pour les réponses. J'ai raté ce fil quand il a été posté. les données.table a déménagé depuis le mois de février. 1.4.1 a été publié à CRAN il y a un moment et 1.5 est bientôt. Par exemple, le DT() alias a été remplacé par liste(); comme une primitive est beaucoup plus rapide, et de données.table maintenant hérite de données.image de sorte qu'il fonctionne avec les packages seulement accepter des données.cadre comme ggplot et treillis, sans aucune conversion nécessaire (plus rapide et plus pratique).

Est-il possible de s'abonner à des données.balise table si je reçois un e-mail lorsque quelqu'un poste une question avec cette balise? La datatable-l'aide de la liste a augmenté d'environ 30 à 40 messages par mois, mais je suis heureux de répondre ici aussi, si je peux obtenir une sorte de notification.

Matthieu

11voto

daroczig Points 11126

Je pense que l'aide de l' base::merge fonction n'est pas nécessaire, que l'utilisation d' data.table jointures peuvent être beaucoup plus rapide. E. g. voir le suivant. Je fais x et y données.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 de fusionner les deux avec base:merge et data.table des jointures pour voir la vitesse d'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, que 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

Qui ne pouvait pas faire un gros souci :)

3voto

Shane Points 40885

Je pense que f3lix est correcte et que la documentation est un peu trompeuse. L'avantage est de faire un jeûne rejoindre pour créer un sous-ensemble de données. Vous avez encore le besoin d'utiliser l' merge de la fonction par la suite, comme dans votre exemple ci-dessus.

Vous verrez dans de Josh présentation sur l'utilisation des données.tableau , c'est ainsi que son exemple s'exécute. Il a d'abord l'un des sous-ensembles de données.les tables, puis en 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')]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X