Dans la trame de données R codée ci-dessous, je voudrais remplacer toutes les heures qui B
apparaissent par b
.
junk <- data.frame(x <- rep(LETTERS[1:4], 3), y <- letters[1:12])
colnames(junk) <- c("nm", "val")
cela fournit:
nm val
1 A a
2 B b
3 C c
4 D d
5 A e
6 B f
7 C g
8 D h
9 A i
10 B j
11 C k
12 D l
Ma première tentative était d'utiliser des instructions for
et if
comme ceci:
for(i in junk$nm) if(i %in% "B") junk$nm <- "b"
mais comme je suis sûr que vous pouvez le voir, cela remplace TOUTES les valeurs de junk$nm
avec b
. Je peux voir pourquoi cela fait cela, mais je n'arrive pas à le faire remplacer uniquement les cas de junk $ nm où la valeur d'origine était B
.
REMARQUE: j'ai réussi à résoudre le problème avec, gsub
mais dans l'intérêt de l'apprentissage, je voudrais toujours savoir comment faire fonctionner mon approche originale (si cela est possible)
Réponses:
Plus facile à convertir nm en caractères, puis à effectuer le changement:
EDIT: Et si en effet vous avez besoin de maintenir nm comme facteurs, ajoutez ceci à la fin:
la source
un autre moyen utile de remplacer les valeurs
la source
La réponse courte est:
Jetez un œil aux vecteurs d'index dans R Introduction (si vous ne l'avez pas encore lu).
ÉDITER. Comme remarqué dans les commentaires, cette solution fonctionne pour les vecteurs de caractères, donc échouez sur vos données.
Pour le facteur le meilleur moyen est de changer de niveau:
la source
c("B","C")
. Fairejunk$nm[junk$nm == "B"]
est la meilleure façon.b
de facteur au facteur nm. La version de diliop est en fait la meilleure si vous voulez travailler avec des personnages, pas des facteurs. (Pensez toujours au type de vos variables en premier!)%in%
et==
est laNA
manipulation:c(1,2,NA)==1
donneTRUE, FALSE, NA
maisc(1,2,NA) %in% 1
donneTRUE, FALSE, FALSE
. Et oui j'ai oublié de vérifier si ce travail: /Comme les données que vous montrez sont des facteurs, cela complique un peu les choses. La réponse de @ diliop aborde le problème en se convertissant
nm
en une variable caractère. Pour revenir aux facteurs d'origine, une étape supplémentaire est nécessaire.Une alternative consiste à manipuler les niveaux du facteur en place.
C'est assez simple et j'oublie souvent qu'il existe une fonction de remplacement pour
levels()
.Edit: Comme indiqué par @Seth dans les commentaires, cela peut être fait en une seule ligne, sans perte de clarté:
la source
levels()
. Que diriez-vous de la doublure uniquejunk <- within(junk, levels(nm)[levels(nm)=="B"] <- "b")
?Le moyen le plus simple de le faire en une seule commande est d'utiliser la
which
commande et de ne pas avoir besoin de changer les facteurs en caractère en faisant ceci:la source
Vous avez créé une variable de facteur dans
nm
, vous devez donc soit éviter de le faire, soit ajouter un niveau supplémentaire aux attributs de facteur. Vous devez également éviter d'utiliser<-
dans les arguments de data.frame ()Option 1:
Option 2:
la source
data.frame
?b
un niveau, il suffit de changer le niveau qui estB
àb
.a <- data.frame(x<-1:10)
. Son nom de colonne n'est pasx
mais plutôt désordonnéx....1.10
. Mieux vaut utiliser data.frame (x = 1: 10). Ensuite, vous savez quel est le nom de votre colonne.predict()
qui se plaindra si les niveaux de facteurs dans les nouvelles données ne correspondent pas à ceux utilisés pour s'adapter au modèle. Plus propre à long terme pour que les données soient formatées comme vous le souhaitez, correctement, que de compter sur des raccourcis. Je suis d'accord qu'il serait peut-être plus facile de ne pas en faire un facteur, mais si c'est déjà un facteur, ou s'il doit en être un pour un exercice de modélisation ...Si vous travaillez avec des variables de caractères (notez que
stringsAsFactors
c'est faux ici), vous pouvez utiliser replace:la source
Appelez cette fonction en utilisant la ligne ci-dessous.
la source