2017-05-25 5 views
2

J'essaie d'exécuter une analyse en composantes principales, mais je reçois l'erreur: Erreur dans colMeans (x , na.rm = TRUE): « x » doit être numériqueAnalyse des composants principaux: Erreur dans colMeans (x, na.rm = TRUE): 'x' doit être numérique

Je sais que toutes les colonnes doivent être numériques, mais la façon de gérer lorsque vous avez des objets de caractère dans le jeu de données? Par exemple:

data(birth.death.rates.1966) 
data2 <- birth.death.rates.1966 
princ <- prcomp(data2) 
  • données2 exemple des données ci-dessous:

enter image description here

Dois-je ajouter une nouvelle colonne renvoyant le nom du pays à un code numérique? Si oui, comment le faire en R?

Répondre

3

Vous pouvez convertir un vecteur de caractères à des valeurs numériques en passant par factor. Ensuite, chaque valeur unique obtient un code entier unique. Dans cet exemple, il y a quatre valeurs pour que les chiffres sont 1 à 4, par ordre alphabétique, je pense:

> d = data.frame(country=c("foo","bar","baz","qux"),x=runif(4),y=runif(4)) 
> d 
    country   x   y 
1  foo 0.84435112 0.7022875 
2  bar 0.01343424 0.5019794 
3  baz 0.09815888 0.5832612 
4  qux 0.18397525 0.8049514 
> d$country = as.numeric(as.factor(d$country)) 
> d 
    country   x   y 
1  3 0.84435112 0.7022875 
2  1 0.01343424 0.5019794 
3  2 0.09815888 0.5832612 
4  4 0.18397525 0.8049514 

Vous pouvez ensuite exécuter prcomp:

> prcomp(d) 
Standard deviations: 
[1] 1.308665216 0.339983614 0.009141194 

Rotation: 
       PC1   PC2   PC3 
country -0.9858920 0.132948161 -0.101694168 
x  -0.1331795 -0.991081523 -0.004541179 
y  -0.1013910 0.009066471 0.994805345 

Que ce sens pour votre application est dépend de vous. Peut-être que vous voulez juste laisser tomber la première colonne: prcomp(d[,-1]) et travailler avec les données numériques, ce qui semble être ce que les autres «réponses» tentent d'atteindre.

1

La première colonne de la trame de données est caractère. Ainsi, vous pouvez recoder à la ligne des noms comme:

library(tidyverse) 
data2 %>% remove_rownames %>% column_to_rownames(var="country") 
princ <- prcomp(data2) 

En variante, comme:

data2 <- data2[,-1] 
rownames(data2) <- data2[,1] 
princ <- prcomp(data2) 
+3

Veuillez prendre la deuxième option. La solution tidyverse est à la fois plus longue et plus longue. Tout n'est pas un clou qui demande un bon battement par le marteau tidyverse. Gardez celui-là pour la manipulation de données plus complexe, où cela vous donne un avantage. –

+0

Correctement dit @JorisMeys, _tidyverse_ est plus approprié pour les données complexes – parth

+1

* et * cela ne répond pas à la question de la conversion des caractères en nombres. – Spacedman