2013-06-20 6 views
1

J'ai une question plutôt basique. J'ai plusieurs valeurs dans une colonne que je voudrais remplacer pour un seul, par exemple:remplacer plusieurs valeurs dans une colonne pour un seul

a<-data.frame(T=LETTERS[5:20],V=rnorm(16,10,1))

et je voudrais changer tout « E », « S », « T » en T pour « AB », alors j'ai essayé

a[a$T==c("E","S","T")]<-"AB" 

et il me donne plusieurs avertissements, et finit par remplacer tous « AB »

Je pense qu'il a quelque chose à voir avec les niveaux et les étiquettes de niveau mais j'étais pas capable de remplacer seulement certaines des valeurs, je devrais ré-étiqueter chaque. Désolé pour le problème, et merci pour toute aide!

Répondre

4

Vous pouvez utiliser la fonction recode() de la bibliothèque car pour modifier également les valeurs pour les facteurs.

library(car) 
a$T<-recode(a$T,"c('E','S','T')='AB'") 

Si vous devez remplacer des valeurs différentes par d'autres valeurs, toutes les instructions peuvent être écrites dans un même appel de fonction.

recode(a$T,"c('E','S','T')='AB';c('F','G','H')='CD'") 
+0

+1 utile pour connaître cette fonction, merci! –

+1

... mais pourquoi une telle interface hostile (ne vous blâme pas @Didzis mais l'auteur). Je lis à propos de 'plyr :: mapvalues' mais je ne peux pas le tester ici sur mon ancienne version R. Je suppose que 'plyr :: mapvalues ​​(niveaux (a $ T), c (" E "," S "," T ")," AB ")' pourrait fonctionner si quelqu'un peut faire un essai. – flodel

+0

@flodel mapvalues ​​fonctionnera avec quelques modifications mapvalues ​​(a $ T, c ("E", "S", "T"), rep ("AB", 3)) –

3

Cela maintiendrait votre structure de données (un facteur comme vous l'aurez deviné):

x <- levels(a$T) 
levels(a$T) <- ifelse(x %in% c("E","S","T"), "AB", x) 

ou

levels(a$T)[levels(a$T) %in% c("E","S","T")] <- "AB" 

Modifier: si vous avez beaucoup de ces remplacements, il est un un peu plus compliqué mais pas impossible:

from <- list(c("E","S","T"), c("J", "K", "L")) 
to <- c("AB", "YZ") 

find.in.list <- function(x, y) match(TRUE, sapply(y, `%in%`, x = x)) 
idx.in.list <- sapply(levels(a$T), find.in.list, from) 
levels(a$T) <- ifelse(is.na(idx.in.list), levels(a$T), to[idx.in.list]) 

a$T 
# [1] AB F G H I YZ YZ YZ M N O P Q R AB AB 
# Levels: AB F G H I YZ M N O P Q R 
+1

+1. C'est la bonne réponse, plutôt que de déconner avec la classe de caractères. –

0

Voulez-vous vraiment des facteurs ici ??? Si ce n'est pas le cas (je pense que vous ne le faites pas) options(stringsAsFactors=FALSE) Donc, c'est beaucoup plus simple que cela ... =>a[a$T %in% c("E","S","T"),"T"]<-"AB"

+0

Si T est un facteur (comme dans le cas présent), cela donnera NA et non AB. –

+0

J'ai pris l'échantillon donné par l'OP ... ça marche juste – statquant

+0

Ohhhh !!! C'est parce que mon 'options() $ stringAsFactors == FALSE', puisque' R' R.2.12.x' 'R' maintenir des tables de hachage pour les chaînes je pense qu'il n'y a pas besoin de facteurs dans ces cas ... – statquant

Questions connexes