3
votes

Correspondance partielle de deux colonnes par chaîne dans dataframe

J'ai un dataframe avec Name1 (10 observations) et Name2 , avec 3 observations. J'ai l'exemple de jouet suivant:

   Name1                            Name2           Is_Matched
Acadian Hospitals                 Wellington           TRUE
Bridgewater Trust Associates      Zeus                 FALSE
Concordia Consulting              Acadian              FALSE
Wellington Corporation LLC          .                  TRUE
Wellington Wealth Management        .                  TRUE
Prime Acadian Charity               .                  TRUE

Si Name1 est capable de faire correspondre une partie de sa chaîne dans Name2 , je veux la sortie dans la colonne 3 pour être TRUE . Actuellement, mon code ne fonctionne que dans l'autre sens, en utilisant pmatch

Ma sortie finale devrait ressembler à ceci:

   Name1                            Name2         
Acadian Hospitals                 Wellington      
Bridgewater Trust Associates      Zeus        
Concordia Consulting              Acadian
Wellington Corporation LLC          .
Wellington Wealth Management        .
Prime Acadian Charity

p >

r

4 commentaires

Les périodes sont-elles intentionnellement TRUE , indiquent-elles des données manquantes ou sont-elles accidentellement vraies dans Is_Matched ?


Aussi, pourquoi Acadian FALSE dans la colonne Is_Matched?


Les points vrai et faux indiquent que Name1 est présent dans Name2, et non l'inverse. Les périodes sont des valeurs manquantes et ont été encodées comme telles dans mon dataframe


Je vois! J'ai posté une modification ci-dessous mais il semble que vous l'avez déjà compris. Bien joué!!


3 Réponses :


2
votes

Vous pouvez utiliser sapply . Sans un exemple, je pense que quelque chose comme ça devrait fonctionner. Je vais vérifier un exemple dans une seconde.

df $ Is_Matched

EDIT:

La création d'un exemple de dataframe a aidé. sapply exportait une matrice avec chaque mot de Name2 ayant sa propre colonne. Ainsi, vous pouvez tester pour voir si une ligne contient un vrai en utilisant rowSums (true = 1, false = 0). Faites-moi savoir si vous rencontrez des problèmes avec cela.

> df <- data.frame(
+   Name1 = c("Acadian Hospitals", "Bridgewater Trust Associates",
+             "Concordia Consulting", "Wellington Corporation LLC",
+             "Wellington Wealth Management", "Prime Acadian Charity"),
+   Name2 = c("Wellington", "Zeus", "Acadian", NA, NA, NA),
+   stringsAsFactors = FALSE
+ )
> 
> match_me <- na.omit(df$Name2)
> df$Is_Matched <- rowSums(sapply(match_me, function(x) grepl(x, df$Name1))) > 0
> df
                         Name1      Name2 Is_Matched
1            Acadian Hospitals Wellington       TRUE
2 Bridgewater Trust Associates       Zeus      FALSE
3         Concordia Consulting    Acadian      FALSE
4   Wellington Corporation LLC       <NA>       TRUE
5 Wellington Wealth Management       <NA>       TRUE
6        Prime Acadian Charity       <NA>       TRUE


0 commentaires

4
votes

On dirait que Name2 n'est en réalité qu'un ensemble de valeurs de recherche. Dans ce cas, vous pouvez créer une recherche en collant toutes les valeurs ensemble, puis effectuer une simple recherche grepl sur l'ensemble de df $ Name2 :

df$Is_Matched <- grepl(paste(df$Name2[df$Name2 == "."], collapse = "|"), df$Name1)
#                         Name1      Name2 Is_Matched
#1            Acadian Hospitals Wellington       TRUE
#2 Bridgewater Trust Associates       Zeus      FALSE
#3         Concordia Consulting    Acadian      FALSE
#4   Wellington Corporation LLC          .       TRUE
#5 Wellington Wealth Management          .       TRUE
#6        Prime Acadian Charity          .       TRUE

Notez que cela suppose que les valeurs manquantes dans Name2 sont codées comme "." plutôt que NA . Il serait assez facile de passer à tout autre codage des valeurs manquantes.


2 commentaires

votre indice sur grepl avec de la pâte a certainement aidé, mais j'ai trouvé un moyen sans le "." titulaire de placement.


existe-t-il un moyen de l'utiliser pour de très grands ensembles de données?



2
votes

Avec l'aide de Mike H.:

Name1 = c("Bridgewater Trust Associates", "Acadian Wealth Management", "Wellington Wealth Trust", "Concordia University", "Southern Zeus College", "Parametric Modeling", "Wellington City Corporation", "Hotel Zanzibar") 
Name2 = c("Acadian", "Wellington", "Zeus")

max.len = max(length(Name1), length(Name2))
Name1 = c(Name1, rep(NA, max.len - length(Name1)))
Name2 = c(Name2, rep(NA, max.len - length(Name2)))
column3 <- grepl(paste(Name2, collapse = "|"), Name1)

df <- data.frame(Name1, Name2, column3, stringsAsFactors = FALSE)


0 commentaires