Problème avec plot.PCA

487 views
Skip to first unread message

audric...@gmail.com

unread,
Jun 15, 2015, 8:45:14 AM6/15/15
to factomin...@googlegroups.com
Bonjour,

Je suis actuellement entrain d'analyser un jeu de données avec le package vmstools (qui utilise FactoMineR).
Dans vmstools, j'utilise la fonction getTableAfterPCA , où est réalisée une ACP sur le jeu de données datSpecies :

log.pca = PCA(datSpecies, graph = FALSE, ncp = ncol(datSpecies))

Plus tard dans la fonction, les plots sur les premiers axes sont demandés (1&2, 2&3, 1&3, 1&4, 2&4), dont celui-ci (axes 1 et 4) :

plot(log.pca, choix = "var", axes = c(1, 4), new.plot = FALSE, lim.cos2.var = 0.3)

ce qui me renvoie l'erreur suivante :

Erreur dans coord.var[v, 1] : indice hors limites

(je n'ai pas d'erreur pour les 4 autres plots)

Elle vient de la fonction plot.PCA de FactoMineR, au début de cette boucle for :

for (v in 1:nrow(coord.var))

nrow(coord.var) vaut 0, donc forcément ça plante.

J'essaie donc de savoir pourquoi coord.var n'a pas de ligne.
J'ai rajouté 2 lignes dans le script pour sauvegarder des fichiers contenant la table coord.var :
-au moment de sa création (à la première occurence de coord.var dans le script de plot.PCA, coord.var_fichier.csv) : elle contient des lignes, avec des coordonnées pour plusieurs variables, jusque là tout va bien.
-au moment où elle est modifiée en coord.var<-coord.var[which(apply(res.pca$var$cos2[, axes, drop = FALSE], 1, sum, na.rm = TRUE) >= lim.cos2.var),] (coord.var_fichier_avant_boucle_for.csv) : la table est alors vide . Un str(coord.var) me renvoie :

 num[0 , 1:2]
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "Dim.1" "Dim.4"


Normalement, vu ce que je lis dans le script de plot.PCA, coord.var n'aurait pas du être modifiée. Ce que je ne comprends pas, c'est que ce changement sur coord.var n'a lieu que si !is.null(coord.var[which(apply(res.pca$var$cos2[, axes, drop = FALSE], 1, sum, na.rm = TRUE) >= lim.cos2.var),]). Vu le contenu de ma table (des NULL et des noms de colonnes), je pensais que cette condition n'est pas vérifiée...mais pourtant, en demandant un print de cette condition, j'obtiens TRUE. Or cette condition n'est-elle pas une sécurité pour éviter de faire un plot à partir d'une table vide? Etant donné que R considère la condition comme vraie, il essaie ensuite de faire la boucle for sur ma table vide, et logiquement ça coince.

Du coup qu'est-ce qui ne va pas? Mes données à analyser, ou bien l'écriture de la condition ci-dessus (!is.null [.....])?

Bien cordialement,

Audric Vigier
coord.var_fichier.csv
coord.var_fichier_avant_boucle_for.csv

François Husson

unread,
Jun 25, 2015, 11:52:23 AM6/25/15
to factomin...@googlegroups.com, audric...@gmail.com
Bonjour,
Si vous construisez une table vide, il est normal qu'ensuite le graphe n'apparaisse pas et qu'il y ait une erreur.
Je ne comprends pas votre message du coup.
la fonction plot.PCA ne peut pas ne pas avoir de variables et donc il n'y a pas de test.
FH

audric...@gmail.com

unread,
Jun 26, 2015, 8:50:34 AM6/26/15
to factomin...@googlegroups.com, audric...@gmail.com
Bonjour,

Le problème, c'est que la table est non-vide au début de plot.PCA, puis devient vide au milieu de plot.PCA (d'où l'erreur).
En détail dans plot.PCA:
-la table est créée l441 de plot.PCA et contient des coordonnées (coord.var <- res.pca$var$coord[, axes, drop = FALSE]), elle n'est pas vide.
-l488, il y a une boucle if basée, entre autres, sur le contenu de cette table :
        if (!is.null(coord.var[which(apply(res.pca$var$cos2[,axes, drop = FALSE], 1, sum, na.rm = TRUE) >= lim.cos2.var),]) & is.na(test.invisible[1]) & (nrow(coord.var) > 0)) {
            coord.var <- coord.var[which(apply(res.pca$var$cos2[, axes, drop = FALSE], 1, sum, na.rm = TRUE) >= lim.cos2.var), , drop = FALSE]

        [...]
        }

Je la comprends comme : SI (l'ensemble sélectionné dans coord.var est non nul ET d'autres conditions), alors coord.var est réduit à cet ensemble (et un plot est demandé). Le problème, c'est que l'ensemble de coord.var sélectionné est vide (cet ensemble est un tableau de 0 ligne, mais un is.null() de ce tableau renvoie tout de même FALSE), mais que la boucle if est quand même parcourue. Tel que je le comprends, cette boucle if sert de sécurité pour éviter de plotter à partir d'une table vide. Dans mon cas, le contenu de la boucle if ne devrait pas être parcouru et le plot ne doit pas être fait, sans renvoyer d'erreur. Or ce n'est pas le cas... Je voulais donc signaler ce problème, sur lequel je n'ai pas la main.

Cordialement,

Audric Vigier
Reply all
Reply to author
Forward
0 new messages