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"