2009-08-19 11 views
4

Note:J'ai changé l'exemple depuis ma première publication. Mon premier exemple était trop simplifié pour capturer le vrai problème.Mixte Fusionner dans une solution R - Indice?

J'ai deux trames de données qui sont triées différemment dans une colonne. Je veux faire correspondre une colonne, puis fusionner dans la valeur de la deuxième colonne. La deuxième colonne doit rester dans le même ordre.

J'ai donc ceci:

state<-c("IA","IA","IA","IL","IL","IL") 
value1<-c(1,2,3,4,5,6) 
s1<-data.frame(state,value1) 
state<-c("IL","IL","IL","IA","IA","IA") 
value2<-c(3,4,5,6,7,8) 
s2<-data.frame(state,value2) 

s1 
s2 

qui renvoie ceci:

> s1 
    state value1 
1 IA  1 
2 IA  2 
3 IA  3 
4 IL  4 
5 IL  5 
6 IL  6 
> s2 
    state value2 
1 IL  3 
2 IL  4 
3 IL  5 
4 IA  6 
5 IA  7 
6 IA  8 

et je veux ceci:

state value1 value2 
1 IA  1  6 
2 IA  2  7 
3 IA  3  8 
4 IL  4  3 
5 IL  5  4 
6 IL  6  5 

Je suis sur le point de me conduire à essayer stupide de résoudre ce. On dirait que ce devrait être un problème d'indice simple.

+1

Comment jouet est cet exemple? Par exemple, dans ce cas, les identifiants d'état correspondent toujours à la même valeur1 (IA == 2, IL == 1), donc peu importe l'ordre exact dans lequel ils se trouvent tant que les ID d'état sont triés dans le même était comme dans s1. Si value1 était de 1: 6, c'est complètement différent. – geoffjentry

+0

Très bon point. J'ai sur simplifié mon exemple. IA ne fait pas toujours == 2 ce qui le rend trop simple. Je vais éditer ma question. –

Répondre

3

Il y a plusieurs façons de faire cela (c'est R, après tout) mais je pense que le plus clair est de créer un index. Nous avons besoin d'une fonction qui crée un index séquentiel (commençant à un et se terminant par le nombre d'observations).

seq_len(3) 
> [1] 1 2 3 

Mais nous devons calculer cet indice dans chaque variable de regroupement (état). Pour cela, nous pouvons utiliser la fonction ave de R. Il faut un numérique comme premier argument, puis les facteurs de regroupement, et enfin la fonction à appliquer dans chaque groupe.

s1$index <- with(s1,ave(value1,state,FUN=seq_len)) 
s2$index <- with(s2,ave(value2,state,FUN=seq_len)) 

(Notez l'utilisation de with, qui indique R pour rechercher les variables dans l'environnement/dataframe. C'est une meilleure pratique que d'utiliser s1 value1 $, s2 value2 $, etc.)

maintenant on peut simplement fusionner (joindre) les deux trames de données (par les variables présentes dans les deux trames de données: état et index).

merge(s1,s2) 

qui donne

state index value1 value2 
1 IA  1  1  6 
2 IA  2  2  7 
3 IA  3  3  8 
4 IL  1  4  3 
5 IL  2  5  4 
6 IL  3  6  5 

Pour que cela fonctionne, il devrait y avoir le même nombre d'observations par l'Etat dans chacune des trames de données.

[Edit:. A commenté le code pour plus de clarté] [Edit: USED seq_len au lieu de créer une nouvelle fonction comme suggéré par hadley.]

+1

étant donné un nombre infini de singes et un nombre infini d'ordinateurs, je ne pouvais toujours pas arriver à cela.Merci beaucoup! –

+0

Que se passe-t-il dans ces 3 lignes? Pouvez-vous élaborer un peu? –

+1

Vous pouvez remplacer 'FUN = fonction (x) 1: longueur (x))' par 'seq_len' – hadley

0

NOTE: Vérifiez le 5ème commentaire sur la réponse ci-dessus. La solution doit être

s1$index <- with(s1,ave(value1,state,FUN=seq_along)) 
s2$index <- with(s2,ave(value2,state,FUN=seq_along)) 

Testé et fonctionnel.