2010-08-28 5 views
3

Je dois fusionner avec des trames de données dans R. Les deux trames de données partagent une variable d'ID commune, le nom du sujet. Cependant, les noms d'une trame de données sont en partie capitalisés, tandis que dans l'autre, ils sont en minuscules. De plus, les noms apparaissent dans l'ordre inverse. Voici un échantillon des trames de données:Transformation de chaînes de caractères dans R

DataFrame1$Name: 
"Van Brempt Kathleen" 
"Gräßle Ingeborg" 
"Gauzès Jean-Paul" 
"Winkler Iuliu" 

DataFrame2$Name: 
"Kathleen VAN BREMPT" 
"Ingeborg GRÄSSLE" 
"Jean-Paul GAUZÈS" 
"Iuliu WINKLER" 

est-il un moyen de R pour rendre ces deux variables utilisables comme identificateur pour la fusion des trames de données?

Best, Thomas

Répondre

2

est ici une solution complète qui combine les deux méthodes partielles proposées jusqu'à présent (et surmonte les craintes exprimées par Spacedman au sujet "correspondant à Grassle avec GRÄßLE"):

DataFrame2$revname <- gsub("([^\\s]*)\\s(.*)","\\2 \\1",DataFrame2$Name,perl=TRUE) 
DataFrame2$agnum <-sapply(tolower(DataFrame2$revname), agrep, tolower(DataFrame1$Name)) 
DataFrame1$num <-1:nrow(DataFrame1) 
merge(DataFrame1, DataFrame2, by.x="num", by.y="agnum") 

sortie:

num    Name.x    Name.y    revname 

1 1 Van Brempt Kathleen Kathleen VAN BREMPT VAN BREMPT Kathleen 
2 2  Gräßle Ingeborg Ingeborg GRÄSSLE GRÄSSLE Ingeborg 
3 3 Gauzès Jean-Paul Jean-Paul GAUZÈS GAUZÈS Jean-Paul 
4 4  Winkler Iuliu  Iuliu WINKLER  WINKLER Iuliu 

La troisième étape ne serait pas nécessaire si DatFrame1 avait rownames qui étaient encore Sequ entièrement numérotés (comme ils le seraient par défaut). La déclaration de fusion serait alors:

merge(DataFrame1, DataFrame2, by.x="row.names", by.y="agnum") 

- David.

0

Pouvez-vous ajouter une colonne/variable supplémentaire à chaque trame de données qui est une version minuscule du nom d'origine:

DataFrame1$NameLower <- tolower(DataFrame1$Name) 
DataFrame2$NameLower <- tolower(DataFrame2$Name) 

Effectuez ensuite une fusion sur ce point:

MergedDataFrame <- merge(DataFrame1, DataFrame2, by="NameLower") 
+0

désolé - J'ai également manqué le sujet de la commande inversée, vous devrez écrire une fonction personnalisée pour déplacer tout le texte en majuscule au début d'un nom, et en minuscules. – Joel

+0

Merci Joel, as-tu une idée de comment écrire une telle fonction? –

3

Vous pouvez utiliser gsub pour convertir les noms autour de:

> names 
[1] "Kathleen VAN BREMPT" "jean-paul GAULTIER" 
> gsub("([^\\s]*)\\s(.*)","\\2 \\1",names,perl=TRUE) 
[1] "VAN BREMPT Kathleen" "GAULTIER jean-paul" 
> 

Ceci fonctionne en faisant correspondre tout d'abord quelque chose jusqu'au premier espace, puis tout ce qui suit et en les inversant. Ajoutez ensuite tolower() ou toupper() si vous le souhaitez et utilisez match() pour joindre vos trames de données.

Bonne chance correspondant à Grassle avec Graßle si. Beaucoup d'autres choses vont probablement vous mordre aussi, comme les gens avec deux prénoms séparés par l'espace, ou quelqu'un avec un titre!

Barry

+0

Merci Barry, vous avez raison, ce n'est pas sans problème, et je vais probablement devoir faire quelques trucs à la main, mais j'espère que cela va réduire la charge de travail un peu :) –

0

En plus de la réponse à l'aide gsub pour réorganiser les noms, vous pouvez aussi regarder la fonction agrep, cette recherche des correspondances approximatives. Vous pouvez l'utiliser avec sapply pour trouver les lignes correspondantes d'une trame de données à l'autre, par exemple:

> sapply(c('newyork', 'NEWJersey', 'Vormont'), agrep, x=state.name, ignore.case=TRUE) 
    newyork NEWJersey Vormont 
     32  30  45 
Questions connexes