3
votes

Comment utiliser une fonction pour convertir plusieurs colonnes avec une valeur de caractère en numérique binaire dans un énorme data.frame?

J'ai un énorme data.frame avec des chiffres, des caractères et des valeurs manquantes. Comment convertir tous les "True" et "False" (valeurs de caractères) en 1 et 0, tout en préservant les valeurs manquantes?

J'ai essayé d'utiliser la fonction de recodage de dplyr, mais cela ne s'applique pas à l'objet de la classe data.frame.

> df2
  Var1 Var2 Var3 Var4 Var99
1  150    1      1116      
2  151    1    1 1117     1
3  152         1 1118      
4  153    0    0 1119     0
5  154    1    1 1120     1
> df
  Var1  Var2  Var3 Var4 Var99
1  150  True       1116      
2  151  True  True 1117  True
3  152        True 1118      
4  153 False False 1119 False
5  154  True  True 1120  True

et ma sortie serait:

df <- data.frame(Var1 = 150:154 , Var2 = c("True","True","","False","True"), 
Var3 = c("","True","True","False","True"), 
Var4 = 1116:1120, Var99 = c("","True","","False","True"))

r

0 commentaires

4 Réponses :


1
votes

Une option serait mutate_if et recoder les valeurs à 1, 0 avec fct_recode de forcats

df %>%
     mutate_if(is.factor,  list( ~ match(., c("False", "True")) - 1))

REMARQUE: les colonnes n'étaient pas logiques ( TRUE / FALSE ) au lieu de cela ( True / False ). Donc, en gardant l'objet du jeu de données tel quel et sans aucune autre hypothèse

NOTE2: ne changera pas les types de colonne après la transformation


Pour passer en numérique, cela peut être fait avec match

library(dplyr)
library(forcats)
df %>% 
   mutate_if(is.factor, list(~ fct_recode(.,  "1" = "True", "0" = "False" )))
#    Var1 Var2 Var3 Var4 Var99
#1  150    1      1116      
#2  151    1    1 1117     1
#3  152         1 1118      
#4  153    0    0 1119     0
#5  154    1    1 1120     1


0 commentaires

1
votes

Étant donné que toutes les colonnes avec True / False sont des facteurs, vous pouvez essayer cette solution dplyr (cependant, regardez également les notes fournies par @akrun):

df %>%
 mutate_if(is.factor, list(~ as.numeric(as.logical(.))))


0 commentaires

2
votes

Vous pouvez utiliser les fonctions dplyr mutate_if et case_when . Pour plus de simplicité, définissez stringsAsFactors sur FALSE lors de la création du data.frame.

df <- data.frame(Var1 = 150:154 , Var2 = c("True","True","","False","True"), 
                 Var3 = c("","True","True","False","True"), 
                 Var4 = 1116:1120, Var99 = c("","True","","False","True"), stringsAsFactors = FALSE)

df %>% 
    mutate_if(is.character, ~case_when(. == "True" ~ 1L, 
                                       . == "False" ~ 0L, 
                                       . == "" ~ NA_integer_))


0 commentaires

2
votes

Une approche de base R avec as.logical et as.numeric:

> vars_logic <- sapply(df, function(x) {all(x %in% c('True', 'False', ''))})
> 
> df[vars_logic] <- lapply(df[vars_logic], function(x){
+   as.numeric(as.logical(x))
+ })
> 
> df
  Var1 Var2 Var3 Var4 Var99
1  150    1   NA 1116    NA
2  151    1    1 1117     1
3  152   NA    1 1118    NA
4  153    0    0 1119     0
5  154    1    1 1120     1

Aussi, comme @IceCreamToucan l'a dit, si vous ne voulez pas taper de noms variables, utilisez:

> df[c("Var2", "Var3", "Var99")] <- lapply(df[c("Var2", "Var3", "Var99")], function(x){
+   as.numeric(as.logical(x))
+ })
> df
  Var1 Var2 Var3 Var4 Var99
1  150    1   NA 1116    NA
2  151    1    1 1117     1
3  152   NA    1 1118    NA
4  153    0    0 1119     0
5  154    1    1 1120     1


2 commentaires

Et si vous ne voulez pas taper les noms des variables, vous pouvez utiliser quelque chose comme sapply (df, is.factor) ou sapply (df, function (x) all (x% dans% c ('True', 'False', ''))) à la place de c ("Var2", "Var3", "Var99")


@IceCreamToucan j'aime ça! Si cela ne vous dérange pas, je l'ajoute.