Question
J'ai un cadre de données avec plusieurs colonnes de facteurs contenant NaN
c'est que je voudrais me convertir NA
's (le NaN
Semble être un problème pour l'utilisation d'objets de régression linéaire pour prédire sur de nouvelles données).
> tester1 <- c("2", "2", "3", "4", "2", "3", NaN)
> tester1
[1] "2" "2" "3" "4" "2" "3" "NaN"
> tester1[is.nan(tester1)] = NA
> tester1
[1] "2" "2" "3" "4" "2" "3" "NaN"
> tester1[is.nan(tester1)] = "NA"
> tester1
[1] "2" "2" "3" "4" "2" "3" "NaN"
La solution
Voici le problème: votre vecteur est le caractère en mode, donc bien sûr, ce n'est pas un nombre ". Ce dernier élément a été interprété comme la chaîne "nan". Utilisant is.nan
ne sera logique que si le vecteur est numérique. Si vous souhaitez faire manquer une valeur dans un vecteur de caractères (afin qu'il soit correctement géré par les fonctions de régression), utilisez (sans aucun devis), NA_character_
.
> tester1 <- c("2", "2", "3", "4", "2", "3", NA_character_)
> tester1
[1] "2" "2" "3" "4" "2" "3" NA
> is.na(tester1)
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Ni "na" ni "nan" ne manquent vraiment dans les vecteurs de caractère. Si pour une raison quelconque, il y avait des valeurs dans une variable de facteur qui étaient "nan", vous auriez pu utiliser simplement l'indexation logique:
tester1[tester1 == "NaN"] = "NA"
# but that would not really be a missing value either
# and it might screw up a factor variable anyway.
tester1[tester1=="NaN"] <- "NA"
Warning message:
In `[<-.factor`(`*tmp*`, tester1 == "NaN", value = "NA") :
invalid factor level, NAs generated
##########
tester1 <- factor(c("2", "2", "3", "4", "2", "3", NaN))
> tester1[tester1 =="NaN"] <- NA_character_
> tester1
[1] 2 2 3 4 2 3 <NA>
Levels: 2 3 4 NaN
Ce dernier résultat pourrait être surprenant. Il y a un niveau "nan" restant mais aucun des éléments n'est "nan". Au lieu de cela, l'élément qui était "nan" est désormais une véritable valeur manquante signifiée en imprimé.
Autres conseils
Tu ne peux pas avoir NaN
Dans un vecteur de caractère, c'est ce que vous avez ici:
> tester1 <- c("2", "2", "3", "4", "2", "3", NaN)
> is.nan(tester1)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> tester1
[1] "2" "2" "3" "4" "2" "3" "NaN"
Remarquez comment R pense que c'est une chaîne de caractères.
Vous pouvez créer NaN
Dans un vecteur numérique:
> tester1 <- c("2", "2", "3", "4", "2", "3", NaN)
> as.numeric(tester1)
[1] 2 2 3 4 2 3 NaN
> is.nan(as.numeric(tester1))
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Ensuite, bien sûr, R peut se convertir NaN
à NA
Selon votre code:
> foo <- as.numeric(tester1)
> foo[is.nan(foo)] <- NA
> foo
[1] 2 2 3 4 2 3 NA
ÉDITER:
Gavin Simpson dans les commentaires me rappelle que, dans votre situation, il existe des moyens beaucoup plus faciles de convertir ce qui est vraiment un "nan" en "NA":
tester1 <- gsub("NaN", "NA", tester1)
tester1
# [1] "2" "2" "3" "4" "2" "3" "NA"
La solution:
Pour détecter quels éléments du vecteur de caractère sont NaN
, vous devez convertir le vecteur en un vecteur numérique:
tester1[is.nan(as.numeric(tester1))] <- "NA"
tester1
[1] "2" "2" "3" "4" "2" "3" "NA"
Explication:
Il y a quelques raisons que cela ne fonctionne pas comme vous vous y attendez.
Premièrement, bien que NaN
signifie "pas un nombre", il a une classe "numeric"
, et n'a du sens à l'intérieur d'un vecteur numérique.
Deuxièmement, lorsqu'il est inclus dans un vecteur de caractère, le symbole NaN
est silencieusement converti en chaîne de caractères "NaN"
. Lorsque vous le testez ensuite pour nan
-ness, la chaîne de caractères renvoie FALSE
:
class(NaN)
# [1] "numeric"
c("1", NaN)
# [1] "1" "NaN"
is.nan(c("1", NaN))
# [1] FALSE FALSE