2017-09-04 4 views
0

J'ai un vecteur de texte avec les noms des médicaments déjà enregistrés, et un autre avec les noms des nouveaux médicaments. Je veux savoir si les nouveaux médicaments ressemblent ou non à un médicament déjà existant.Comment ne pas modifier les noms en double avec sapply?

Par exemple, si Supercure est un médicament qui peut être producted soit par firm1 ou firm2 et supercure firm1 1000mg et supercure firm2 500mg sont déjà inscrits, alors supercure firm1 500 mg devrait être associée à deux d'entre eux.

agrep permet de faire une telle correspondance dans R, et sapply permet de le faire pour tous les médicaments dans la nouvelle liste:

new<-c("supercure firm1 500mg","randomcure firm2 1000mg","unknowncure firm2 100mg") 
registered<-c("supercure firm1 1000mg","supercure firm2 500mg","randomcure firm1 1000mg") 
res<-unlist(sapply(new,agrep,x=registered)) 
res 

Comme prévu, Supercure obtient deux matches, randomcure un match et unknowncure aucun match (ce qui est ce que je veux). Cependant, sapply semble avoir modifié les noms afin qu'il n'y ait pas double: supercure firm1 500mg est devenu supercure firm1 500mg1 et supercure firm1 500mg2:

supercure firm1 500mg1 supercure firm1 500mg2 randomcure firm2 1000mg 
        1      2      3 

Ceci est un problème, car il me empêche de sélectionner les médicaments adaptés de la nouvelle liste:

new[new %in% names(res)] attrape uniquement le randomcure (car le nom de supercure a été modifié).

Je peux penser à des moyens de résoudre ce problème par un traitement de texte assez gracieux, mais y a-t-il une façon plus intelligente d'obtenir la liste des nouveaux médicaments qui ont trouvé une correspondance?

La sortie idéale serait:

supercure firm1 500mg supercure firm1 500mg randomcure firm2 1000mg 
        1      2      3 

Répondre

1

sapply n » ai pas t modifier le nom, unlist fait. Cela donne la sortie désirée:

x <- sapply(new,agrep,x=registered) 
setNames(unlist(x),rep(names(x),lengths(x))) 
# supercure firm1 500mg supercure firm1 500mg randomcure firm2 1000mg 
#      1      2      3 
+0

En effet, mon mal. Belle solution ici! – Vincent

1

Vous pouvez essayer de faire une trame de données, stack et utiliser setNames pour en faire un vecteur nommé, à savoir

d1 <- unique(stack(data.frame(Filter(length, sapply(new,agrep,x=registered))))) 
# values      ind 
#1  1 supercure.firm1.500mg 
#2  2 supercure.firm1.500mg 
#3  3 randomcure.firm2.1000mg 

setNames(d1$values, d1$ind) 
# supercure.firm1.500mg supercure.firm1.500mg randomcure.firm2.1000mg 
#      1      2      3 
+0

Cela fonctionne en effet, merci! – Vincent