J'ai dataframe DF
:
library("plyr") as.data.frame(lapply(DF, function(x) { revalue(x, c("No"="X")) }))
Je veux changer les valeurs "No"
dans les variables V1
, V2
, V3
et V4
- mais pas Location
- en "X"
. Je peux facilement modifier les noms des niveaux manuellement dans chaque colonne, mais cela prend du temps dans un grand ensemble de données. Cependant, si j'utilise revalue
, tous les "No"
, y compris ceux de Location
, que je souhaite conserver inchangés, sont remplacés par "X"
:
DF <- data.frame(V1 = factor(c("Yes", "No", "Yes", "No", "No")), V2 = factor(c("Yes", "No", "No", "Yes", "No")), Location = factor(c("London", "Paris", "No", "Dallas", "No")), V3 = factor(c("No", "Yes", "No", "No", "No")), V4 = factor(c("No", "Yes", "No", "No", "No")))
Existe-t-il un moyen de spécifier les variables en fonction de leur position dans l'ensemble de données (ici colonnes 1: 2 et 4: 5) auxquelles le changement de nom s'applique?
4 Réponses :
Peut-être que quelqu'un peut suggérer une solution plus élégante, mais une solution qui fonctionne (sans changer manuellement chaque variable) est la suivante:
change.vec = c("V1", "V2", "V3", "V4") for(i in 1:length(change.vec)) { levels(DF[,change.vec[i]]) = c("X", "Yes") } >DF V1 V2 Location V3 V4 1 Yes Yes London X X 2 X X Paris Yes Yes 3 Yes X No X X 4 X Yes Dallas X X 5 X X No X X
Spécifiez simplement les numéros de colonne auxquels vous souhaitez appliquer la fonction de revalue
:
cols_to_update <- c(1:2,4:5) DF[, cols_to_update] <- lapply(DF[,cols_to_update], function(x) plyr::revalue(x, c("No"="X")))
Vous pouvez également le faire en utilisant l'approche tidyverse:
library(dplyr) #> #> Attaching package: 'dplyr' #> The following objects are masked from 'package:stats': #> #> filter, lag #> The following objects are masked from 'package:base': #> #> intersect, setdiff, setequal, union library(plyr) #> ------------------------------------------------------------------------- #> You have loaded plyr after dplyr - this is likely to cause problems. #> If you need functions from both plyr and dplyr, please load plyr first, then dplyr: #> library(plyr); library(dplyr) #> ------------------------------------------------------------------------- #> #> Attaching package: 'plyr' #> The following objects are masked from 'package:dplyr': #> #> arrange, count, desc, failwith, id, mutate, rename, summarise, #> summarize DF <- data.frame(V1 = factor(c("Yes", "No", "Yes", "No", "No")), V2 = factor(c("Yes", "No", "No", "Yes", "No")), Location = factor(c("London", "Paris", "No", "Dallas", "No")), V3 = factor(c("No", "Yes", "No", "No", "No")), V4 = factor(c("No", "Yes", "No", "No", "No"))) (DF <- DF %>% mutate_at(.vars = vars(-Location), .funs = function(t) revalue(x = t, replace = c("No" = "X")))) #> V1 V2 Location V3 V4 #> 1 Yes Yes London X X #> 2 X X Paris Yes Yes #> 3 Yes X No X X #> 4 X Yes Dallas X X #> 5 X X No X X
Créé le 17/03/2019 par le package reprex (v0.2.1)
Encore une autre solution utilisant dplyrs quosure style lambda ~ fun(.)
.funs
argument .funs
combiné avec forcats :: fct_recode:
DF %>% mutate(across((!Location), ~fct_recode(., "X" = "No"))) DF %>% mutate(across(c(1:2,4:5), ~fct_recode(., "X" = "No")))
Mise à jour pour dplyr 1.0:
Le nouveau across()
remplace la famille des "variantes de portée" comme mutate_at
. across()
facilite l'application de la même transformation à plusieurs colonnes, vous permettant d'utiliser la sémantique select () à l'intérieur de summary () et mutate ()
Appliqué à la question ici, voici 2 variantes pour y parvenir:
library("dplyr") library("forcats") (DF <- DF %>% mutate_at(vars(-Location), ~fct_recode(., "X" = "No"))) # V1 V2 Location V3 V4 # 1 Yes Yes London X X # 2 X X Paris Yes Yes # 3 Yes X No X X # 4 X Yes Dallas X X # 5 X X No X X
Juste une note:
data.frame
convertit notoirement les chaînes en facteurs par défaut, donc la partiefactor()
de votre exemple est redondante.