Lorsque je convertis un facteur en numérique ou en entier, j'obtiens les codes de niveau sous-jacents, pas les valeurs sous forme de nombres.
f <- factor(sample(runif(5), 20, replace = TRUE))
## [1] 0.0248644019011408 0.0248644019011408 0.179684827337041
## [4] 0.0284090070053935 0.363644931698218 0.363644931698218
## [7] 0.179684827337041 0.249704354675487 0.249704354675487
## [10] 0.0248644019011408 0.249704354675487 0.0284090070053935
## [13] 0.179684827337041 0.0248644019011408 0.179684827337041
## [16] 0.363644931698218 0.249704354675487 0.363644931698218
## [19] 0.179684827337041 0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218
as.numeric(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
as.integer(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
Je dois y recourir paste
pour obtenir les vraies valeurs:
as.numeric(paste(f))
## [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
## [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901
Existe-t-il une meilleure façon de convertir un facteur en numérique?
attributes(f)
), donc je ne pense pas qu'il y ait un problème avecas.numeric(paste(f))
. Peut-être serait-il préférable de penser pourquoi (dans le contexte spécifique) vous obtenez un facteur en premier lieu, et essayez d'arrêter cela. Par exemple, l'dec
argumentread.table
est-il correctement défini?df %>% convert(num(column))
. Ou si vous avez un vecteur de facteur que vous pouvez utiliseras_reliable_num(factor_vector)
Réponses:
Voir la section Avertissement de
?factor
:La FAQ sur R contient des conseils similaires .
Pourquoi est
as.numeric(levels(f))[f]
plus efficace queas.numeric(as.character(f))
?as.numeric(as.character(f))
est efficaceas.numeric(levels(f)[f])
, vous effectuez donc la conversion en numérique sur deslength(x)
valeurs plutôt que sur desnlevels(x)
valeurs. La différence de vitesse sera plus apparente pour les vecteurs longs avec peu de niveaux. Si les valeurs sont pour la plupart uniques, il n'y aura pas beaucoup de différence de vitesse. Quelle que soit la façon dont vous effectuez la conversion, il est peu probable que cette opération soit le goulot d'étranglement dans votre code, alors ne vous en faites pas trop.Quelques horaires
la source
R a un certain nombre de fonctions pratiques (non documentées) pour convertir les facteurs:
as.character.factor
as.data.frame.factor
as.Date.factor
as.list.factor
as.vector.factor
Mais ennuyeux, il n'y a rien pour gérer le facteur -> conversion numérique . Dans le prolongement de la réponse de Joshua Ulrich, je suggère de surmonter cette omission avec la définition de votre propre fonction idiomatique:
que vous pouvez stocker au début de votre script, ou mieux encore dans votre
.Rprofile
fichier.la source
as.integer(factor)
renvoie les codes entiers sous-jacents (comme indiqué dans la section des exemples de?factor
). Il est probablement correct de définir cette fonction dans votre environnement global, mais vous pouvez provoquer des problèmes si vous l'enregistrez réellement en tant que méthode S3.factor->numeric
conversion encombrante beaucoup avant de réaliser qu'il s'agit en fait d'une lacune de R: une fonction de commodité devrait être disponible ... L'appeler a duas.numeric.factor
sens pour moi, mais YMMV.v=NA;as.numeric.factor(v)
ouv='something';as.numeric.factor(v)
alors il le faudrait, sinon vous avez quelque chose de bizarre qui se passe quelque part.La façon la plus simple serait d'utiliser la
unfactor
fonction du package varhandleCet exemple peut être un démarrage rapide:
la source
unfactor
fonction est d'abord convertie en type de données de caractères, puis reconvertie en numérique. Tapezunfactor
sur la console et vous pouvez le voir au milieu de la fonction. Par conséquent, cela ne donne pas vraiment une meilleure solution que ce que le demandeur avait déjà.unfactor
fonction s'occupe des choses qui ne peuvent pas être converties en numérique. Consultez les exemples danshelp("unfactor")
library("varhandle")
) (comme je l'ai mentionné dans la première ligne de ma réponse !!)as.numeric()
etas.character()
dans un mauvais ordre;) Ce que fait votre bloc de code est de transformer l'index de niveau du facteur en une matrice de caractères, donc ce que vous aurez au et est un vecteur de caractères qui contient des nombres qui ont été attribués à un certain niveau de votre facteur. Les fonctions de ce package sont là pour éviter ces confusionsRemarque: cette réponse particulière n'est pas pour convertir des facteurs à valeur numérique en chiffres, c'est pour convertir des facteurs catégoriels en leurs numéros de niveau correspondants.
Chaque réponse dans ce post n'a pas généré de résultats pour moi, les NA étaient générées.
Ce qui a fonctionné pour moi, c'est ceci -
la source
y<-factor(c("5","15","20","2")); unclass(y) %>% as.numeric
Cela renvoie 4,1,3,2, pas 5,15,20,2. Cela ressemble à des informations incorrectes.as.numeric(y)
aurait dû très bien fonctionner, pas besoin deunclass()
. Mais encore une fois, ce n'est pas de cela qu'il s'agissait. Cette réponse n'est pas appropriée ici.C'est possible seulement dans le cas où les étiquettes de facteurs correspondent aux valeurs d'origine. Je vais l'expliquer avec un exemple.
Supposons que les données soient vectorielles
x
:Je vais maintenant créer un facteur avec quatre étiquettes:
1)
x
est de type double,f
est de type entier. Il s'agit de la première perte inévitable d'informations. Les facteurs sont toujours stockés sous forme d'entiers.2) Il n'est pas possible de revenir aux valeurs d'origine (10, 20, 30, 40) ayant uniquement
f
disponible. Nous pouvons voir quef
ne contient que les valeurs entières 1, 2, 3, 4 et deux attributs - la liste des étiquettes ("A", "B", "C", "D") et l'attribut de classe "facteur". Rien de plus.Pour revenir aux valeurs d'origine, nous devons connaître les valeurs des niveaux utilisés pour créer le facteur. Dans ce cas
c(10, 20, 30, 40)
. Si nous connaissons les niveaux d'origine (dans le bon ordre), nous pouvons revenir aux valeurs d'origine.Et cela ne fonctionnera que si des étiquettes ont été définies pour toutes les valeurs possibles dans les données d'origine.
Donc, si vous avez besoin des valeurs d'origine, vous devez les conserver. Sinon, il y a de fortes chances qu'il ne soit pas possible d'y revenir uniquement à partir d'un facteur.
la source
Vous pouvez utiliser
hablar::convert
si vous avez un bloc de données. La syntaxe est simple:Exemple df
Solution
vous donne:
Ou si vous voulez qu'une colonne soit un entier et un numérique:
résulte en:
la source
On dirait que la solution as.numeric (levels (f)) [f] ne fonctionne plus avec R 4.0.
Solution alternative:
la source
D'après les nombreuses réponses que j'ai pu lire, la seule façon donnée était d'augmenter le nombre de variables en fonction du nombre de facteurs. Si vous avez une variable "animal de compagnie" avec les niveaux "chien" et "chat", vous vous retrouvez avec pet_dog et pet_cat.
Dans mon cas, je voulais rester avec le même nombre de variables, en traduisant simplement la variable facteur en une variable numérique, d'une manière qui peut s'appliquer à de nombreuses variables à plusieurs niveaux, de sorte que cat = 1 et dog = 0 par exemple.
Veuillez trouver la solution correspondante ci-dessous:
la source
tard dans le jeu, par accident, j'ai trouvé
trimws()
peut se convertirfactor(3:5)
enc("3","4","5")
. Ensuite, vous pouvez appeleras.numeric()
. C'est:la source
trimws
Overas.character
comme décrit dans la réponse acceptée? Il me semble que, sauf si vous aviez réellement un espace à supprimer, voustrimws
allez simplement faire un tas de travaux d'expression régulière inutiles pour retourner le même résultat.