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
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"))
4 Réponses :
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
É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(.))))
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_))
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
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.