J'essaie de regrouper diverses valeurs en fonction d'un vecteur prédéfini, puis de mettre à jour une colonne.
Exemples de données
ID Type Grouping 1 1 Windows IT 2 2 Windows Server IT 3 3 Cat Animal 4 4 Dog Animal 5 5 Eggs Food
Ce que j'ai essayé mais échoué
df %>% mutate(Grouping = ifelse(Type == "Windows", "IT", ifelse ...))
3 Réponses :
Une option serait de créer une liste
(ou un data.frame
) pour les mappages, puis de faire une left_join
map <- list( it = c("Windows", "Windows Server"), animal = c("Cat", "Dog"), food = c("Eggs")) library(dplyr) df %>% left_join(stack(map), by = c("Type" = "values")) # ID Type ind #1 1 Windows it #2 2 Windows Server it #3 3 Cat animal #4 4 Dog animal #5 5 Eggs food
Merci pour la solution, cela fonctionne parfaitement! Cependant j'ai une question. Savez-vous pourquoi lorsque je définis mes vecteurs en dehors de la liste, la pile (carte)
ne semble pas fonctionner? Il me montre cette erreur: Erreur dans data.frame (values = unlist (unname (x)), ind, stringsAsFactors = FALSE): les arguments impliquent un nombre de lignes différent: 5, 0
@Javier "Savez-vous pourquoi lorsque je définis mes vecteurs en dehors de la liste, la stack (map)
ne semble pas fonctionner?" Je ne sais pas ce que cela moyens? Pourquoi "en dehors de la liste
"? Vous devez définir une liste
avec des éléments nommés. stack
puis rangée les entrées de chaque élément list
dans la colonne values
puis ajoute une colonne ind
pour indiquer de quel élément ils sont venus.
Ah, je ne savais pas que la liste devait avoir des éléments nommés pour que stack
fonctionne. Merci beaucoup!
Créez une liste de vos vecteurs prédéfinis, puis vérifiez quel élément de la liste contient les éléments dans le df$Type
mylist = mget(c("animal", "food", "it")) names(mylist)[max.col(t(sapply(df$Type, function(x) lapply(mylist, function(y) x %in% y))))] #[1] "it" "it" "animal" "animal" "food"
la question telle que publiée n'a pas beaucoup de sens. Plus précisément, avec les exemples de données, il n'est pas plus simple de stocker les vecteurs de type indépendants que de stocker le type en tant qu'attribut de la trame de données initiale. peut-être pourriez-vous ajouter une couleur qui donne plus de détails sur la nature du problème.
Cela dit, en supposant que votre problème est que les vecteurs de recherche sont stockés dans une source différente et doivent être chargés indépendamment, une simple boucle devrait suffire . (J'utilise data.table, car je ne me souviens même plus comment utiliser un data.frame brut):
df <- data.table(ID = 1:5, Type = c("Windows", "Windows Server", "Cat", "Dog", "Eggs")) it <- c("Windows", "Windows Server") animal <- c("Cat", "Dog") food <- c("Eggs") lookup.names <- c("it", "animal", "food") for (z in 1:length(lookup.names) ) { lookup <- get(lookup.names[z]) #maybe need to do some more sophisticated load, like from a file or database df[Type %in% lookup, Grouping := lookup.names[z]] }
Bonjour, la question posée est un exemple édulcoré et reproductible de mon problème. Une boucle n'est peut-être pas aussi efficace que j'ai affaire à un ensemble de données volumineuses; donc utiliser un left_join
tel que fourni par les autres utilisateurs fonctionne mieux
Créer un dataframe et fusionner?
Votre
gsub
échoue car vous fournissez un vecteur comme expression de recherche. Cela fonctionnera si vous faites:gsub (paste (it, collapse = "|"), "IT", c ("Windows", "Windows Server", "Cat", "Dog", "Eggs") )
@PavoDive c'est vraiment utile, merci!