2014-09-12 3 views
1

J'essaie d'analyser un grand nombre de données. Je ne peux donc pas utiliser les boucles pour rechercher des ID d'un bloc de données sur l'autre et remplacer le texte.Recherche et remplacement entre deux trames de données avec la famille Apply

Fondamentalement, la première trame de données est avec des ID et sans noms. Les noms sont dans l'autre trame de données.

(Edit) Entrée dfs

(Edit) DF1

 
ID------Name 
1,2,3---NA 
4,5-----NA 
6-------NA 

(Edit) DF2

 
ID------Name 
1-------John 
2-------John 
3-------John 
4-------Stacy 
5-------Stacy 
6-------Alice 

(Edit) sortie attendue df

 
ID------Name 
1,2,3---John 
4,5-----Stacy 
6-------Alice 

(Edit) S'il vous plaît noter que ceci est une version très simplifiée. df1 a en réalité 63 colonnes et 8551 lignes, df2 a 5 colonnes et 37291 lignes.

Je peux rechercher les ID et obtenir des noms sur la deuxième trame de données comme ceci. C'est super rapide!

namer <- function(df2, ids) { 
    ids <- gsub(',', '|', ids); 
    names <- df2[which(apply(df2, 1, function(x) any(grepl(ids, x)))),][['Name']]; 
    if (length(names) != 0) { 
    return(names[[1]]); 
    } else { 
    return(NA); 
    } 
} 

Mais, je ne peux pas remplacer en utilisant des familles d'application. Je sais le faire avec des boucles for et c'est super lent parce que j'ai environ 8500 lignes dans la première trame de données.

for (k in 1:nrow(df1)) { 
    df1$Name[k] <- namer(df2, df1$ID[k]); 
} 

Pouvez-vous s'il vous plait aider à convertir des boucles en fonctions applicatives et à accélérer le processus?

Merci à l'avance

+1

Quelle est la sortie attendue? S'il vous plaît clarifier l'entrée df et la sortie df? – zx8754

+0

J'ai ajouté la sortie attendue et l'entrée dfs s'il vous plaît regardez-les avec des marqueurs (Edit). @Andreas Je suppose que je ne peux pas les fusionner car ils ne sont pas similaires dans les lignes parce que df1 a plusieurs ID dans sa colonne ID. Mais ça l'a fait pour la partie recherche. Je le faisais aussi avec pour boucle et regardé sur Internet et découvert de cette façon. –

+1

@Gungor, Peut-être je suis mal compris, mais ne pouvez-vous pas utiliser 'aggregate (ID ~., Df2, I)' – akrun

Répondre

2

Vous pouvez

df1$Name <- sapply(as.character(df1$ID), 
     function(x) paste(unique(df2[match(strsplit(x, ",")[[1]], df2$ID), "Name"]), collapse = ",")) 
df1 
#  ID Name 
# 1 1,2,3 John 
# 2 4,5 Stacy 
# 3  6 Alice 

Bien que je doute sapply sera plus rapide qu'une boucle for. J'ai également ajouté paste fonction ici au cas où vous avez plus d'un nom correspondant dans df1$ID

+0

Croyez-moi c'est beaucoup plus rapide que pour la boucle, il en a résulté en pas de temps. Oui, j'ai réalisé que vous collez des noms supplémentaires possibles, je suppose que je n'en ai pas mais bon pour l'analyser comme ça. Cela a fonctionné comme prévu. Merci beaucoup! –

Questions connexes