J'aime remplacer mes niveaux dog1 ... dog4 et cat1 ... cat4 par seulement deux niveaux DOG et CAT, mais si j'utilise grepl, ma sortie n'est que NA.
Dans mon code:
head(d) x y 1 DOG 0.906357739138289 2 DOG 0.974674552504268 3 DOG 0.664045049199848 4 DOG 0.911777985232099 5 CAT 0.246575548162824 6 CAT 0.758069789161901
Message d'avertissement: Dans
[ (
* tmp *
, grepl ("dog", d $ x), value = c (NA, NA, NA,: niveau de facteur non valide, NA généré
d$x[grepl("cat", d$x)] <- "CAT" Warning message: In `[<-.factor`(`*tmp*`, grepl("cat", d$x), value = c(NA_integer_, : invalid factor level, NA generated head(d) x y 1 <NA> 0.906357739138289 2 <NA> 0.974674552504268 3 <NA> 0.664045049199848 4 <NA> 0.911777985232099 5 <NA> 0.246575548162824 6 <NA> 0.758069789161901
Ma sortie souhaitable si le code fonctionne correctement est:
x <- (rep(c("dog1","dog2","dog3","dog4","cat1","cat2","cat3","cat4"),2)) #Levels y<-rnorm(16) d<-data.frame(cbind(x,y)) head(d) x y 1 dog1 0.906357739138289 2 dog2 0.974674552504268 3 dog3 0.664045049199848 4 dog4 0.911777985232099 5 cat1 0.246575548162824 6 cat2 0.758069789161901 d$x[grepl("dog", d$x)] <- "DOG"
3 Réponses :
Vous pouvez essayer de créer le bloc de données avec des chaînes comme facteurs faux:
d <- data.frame(cbind(x,y), stringsAsFactors=FALSE) d$x[grepl("dog", d$x)] <- "DOG" d$x[grepl("cat", d$x)] <- "CAT"
La clé ici (comme Tim l'a laissé entendre) est de comprendre comment les variables factor
, bien que similaires en surface, sont en réalité complètement différentes des variables character
.
Voici une façon d'accéder et de mettre à jour les niveaux de votre facteur:
levels(d$x) # [1] "cat1" "cat2" "cat3" "cat4" "dog1" "dog2" "dog3" "dog4" levels(d$x)[grepl("dog", levels(d$x))] <- "DOG" levels(d$x)[grepl("cat", levels(d$x))] <- "CAT" head(d) # x y # 1 DOG -0.0489713202962167 # 2 DOG -0.548503649991368 # 3 DOG 0.460493884654479 # 4 DOG 0.143044665735075 # 5 CAT -2.13008189672678 # 6 CAT -0.136767747543626 levels(d$x) [1] "CAT" "DOG"
Encore une autre version mais utilisant regex ici. Nous capturons tout jusqu'à ce qu'un chiffre soit trouvé et le transformons en majuscules. ( \\ U
).
d$x <- sub("(.*)\\d+", "\\U\\1", d$x, perl = TRUE) d$x #[1] "DOG" "DOG" "DOG" "DOG" "CAT" "CAT" "CAT" "CAT" "DOG" "DOG" "DOG" "DOG" # "CAT" "CAT" "CAT" "CAT"