2010-08-23 6 views
1

J'ai deux data.frames dans R, dont l'une a deux colonnes et l'autre a trois colonnes, et où deux colonnes sont communes entre les deux cadres. Le cadre a le même nombre de lignes. Un exemple des cadres, a et b, est fourni ci-dessous. Ce que je dois faire est de réorganiser les rangées de b en utilisant l'ordre des rangées dans un. Notez que dans l'image b, toute combinaison unique des deux premières colonnes, id et lob, sera associée à une valeur unique dans la colonne val. Les colonnes id et lob données ici sont un facteur et un caractère, mais je voudrais qu'une solution fonctionne pour n'importe quel type de données.Réorganiser un data.frame en utilisant deux colonnes d'un autre data.frame dans R

Notez que si nous devions envisager un cas où cadre juste avait la colonne id et le cadre b avait juste les colonnes id et val, j'accompliraient cela avec quelque chose comme

b[match(a$id,b$id),] 

Malheureusement, je Je ne sais pas comment faire la même chose quand j'ai besoin de commander par deux colonnes.

a:

id lob 
1 1+ X 
2 3 X 
3 2 X 
4 1 X 
5 1 Y 
6 1+ Y 
7 1+ X 
8 3 X 
9 3 X 

b:

id lob val 
1 1+ X 1 
2 1+ Y 9 
3 1+ X 1 
4 3 X 5 
5 3 X 5 
6 3 X 5 
7 2 X 4 
8 1 X 3 
9 1 Y 2 

Je veux obtenir ceci:

id lob val 
1 1+ X 1 
2 3 X 5 
3 2 X 4 
4 1 X 3 
5 1 Y 2 
6 1+ Y 9 
7 1+ X 1 
8 3 X 5 
9 3 X 5 
+0

Est-il encore bien défini? La combinaison (id, lob) ne semble pas définir une ligne de façon unique. – Aniko

+0

Aniko - Il peut y avoir des lignes en double, mais cela ne devrait pas être un problème de la même manière que si vous voulez trier un vecteur de nombres avec des valeurs dupliquées. Notez que pour tout tuple donné (id, lob), il n'y aura qu'une seule valeur pour val; c'est-à-dire que vous ne pouvez pas avoir (1+, X, 5) et (1+, X, 3). Si ce n'était pas le cas, ce serait un problème. – Abiel

Répondre

3

Essayez d'utiliser la pâte à combiner votre identifiant et votre lob au sein de votre appel de fonction de fusion.

b[match(paste(a$id,a$lob), paste(b$id,b$lob)),] 


    id lob val 
1 1+ X 1 
4 3 X 5 
7 2 X 4 
8 1 X 3 
9 1 Y 2 
2 1+ Y 9 
1.1 1+ X 1 
4.1 3 X 5 
4.2 3 X 5 
+2

Il existe un faible risque que vous créiez une fausse connexion. Exemple: a.id = "a b", a.lob = "c", b.id = "a", b.lob = "b c" '. Mais cela ne peut arriver que lorsque vous ne connaissez pas vos données. – Marek

+1

Merci Brian, vous avez résolu mon problème. Pour plus de sécurité, nous pourrions ajouter un séparateur unique pour traiter le cas mentionné par Marek. – Abiel

1

Voici une autre façon aussi longtemps que les appariements en et match b parfaitement:

b[order(b$id,b$lob), ][ order(order(a$id,a$lob)), ] 

La première utilisation de l'ordre trie la trame de données b par identifiant et colonnes LOB, puis la deuxième série (2 commandes) dit réorganiser les rangées de b, de la manière qui désorganiserait un retour à son ordre d'origine après avoir été trié.

Questions connexes