2
votes

Renommer les niveaux dans plusieurs facteurs spécifiques dans une trame de données

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?


1 commentaires

Juste une note: data.frame convertit notoirement les chaînes en facteurs par défaut, donc la partie factor() de votre exemple est redondante.


4 Réponses :


1
votes

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


0 commentaires

1
votes

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")))


0 commentaires

1
votes

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)


0 commentaires

2
votes

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


0 commentaires