Visualisation interactive de résultats d’ACP et d’ACM avec R et explor

explor est un package récent pour R dont l’objectif est de faciliter la visualisation et l’exploration de résultats d’analyses en composantes principales (ACP) ou d’analyses des correspondances (ACM).

Son utilisation est très simple : vous effectuez votre analyse à l’aide des fonctions dont vous avez l’habitude (actuellement sont supportées les fonctions des packages ade4 et FactoMineR) et vous appliquez simplement la fonction explor() à l’objet résultat.

Voici un exemple très simple reprenant un jeu de données de FactoMineR :

library(FactoMineR)
library(explor)

data(hobbies)
res.mca <- MCA(hobbies,quali.sup=19:22,quanti.sup=23)
explor(res.mca)

Une interface devrait alors se lancer (dans RStudio si vous utilisez cet environnement, sinon dans votre navigateur Web) et qui devrait ressembler vaguement à ceci :

 

 

L’interface change selon le type d’analyse, mais l’organisation globale reste la même : un barre d’onglets en haut de page vous permet de naviguer entre l’histogramme des valeurs propres, les tableaux de résultats et les graphiques représentant variables ou individus.

L’interface présente plusieurs fonctionnalités « interactives » :

  • Vous pouvez à tout moment modifier le ou les axes représentés
  • Les tableaux de résultats sont triables et filtrables dynamiquement
  • Vous pouvez sélectionner les points à afficher selon différents critères, leur opacité, leur taille
  • Vous pouvez associer couleur, symbole ou taille des points à différentes caractéristiques

Les graphiques eux-mêmes sont interactifs :

  • Vous pouvez zoomer avec la molette de la souris et vous déplacer dans le graphique en cliquant-déplaçant
  • Des tooltips apparaissent au survol des points avec les données correspondantes
  • Vous pouvez déplacer les étiquettes avec la souris pour les repositionner
  • Le survol des éléments de légende met en valeur les éléments correspondants

Les graphiques sont « dynamiques », c’est-à-dire que les changements d’axes, de taille, de couleur ou de points affichés s’effectuent sous forme d’animations qui peuvent faciliter la visualisation.

Enfin, vous pouvez à tout moment exporter le graphique actuellement affiché au format SVG.

explor supporte pour le moment les fonctions CA, MCA et PCA du package FactoMineR, et les fonctions dudi.coa, dudi.acm et dudi.pca du package ade4. Si vous souhaitez l’essayer c’est très simple, il vous suffit de l’installer avec :

install.packages("explor")

Pour plus d’informations vous pouvez consulter :

Le projet est assez jeune, donc n’hésitez pas à faire remonter bugs ou suggestions dans les commentaires, sur GitHub ou sur la liste r-soc.

Qu’est-ce qu’un diagramme de Lexis ? Représenter trois dimensions sur un plan.

Le diagramme de Lexis est un instrument graphique utilisé principalement par les démographes : les manuels de démographie débutent souvent par des explications sur ce type de représentation 1 et leur insistance sur cette question incite à penser que les étudiants ont des difficultés à la comprendre.

Commençons par la présentation qui en est faite dans un manuel de référence en trois volumes édité dans les collections de l’Ined 2. Elle débute par un rappel historique qui explique le nom donné à ce diagramme à la suite de sa présentation par Lexis 3, présentation modernisée par Roland Pressat dans son Analyse démographique de 1961 et qui s’est imposée. Puis vient la présentation :

« Le principe en est très simple. Il s’agit d’un système cartésien dont le premier axe mesure le temps absolu (le calendrier civil) et le second, le temps relatif (l’âge) » (p.95)

Pour bien comprendre, appliquons immédiatement ce principe d’un système cartésien à deux dimensions à des données démographiques : à titre d’exemple (non-fictif) prenons le carnet d’un quotidien à une date récente où l’on peut repérer six personnes pour lesquelles on dispose de l’année de naissance et de l’âge au décès :

A 1947 67 ans
B 1930 84 ans
C 1944 70 ans
D 1936 78 ans
E 1925 89 ans
F 1931 83 ans

En mettant l’année de naissance en abscisse et l’âge en ordonnée, on a le graphique suivant :

Carnet1Graphique 1

On constate immédiatement que sur ce graphique, les coordonnées des six personnes décédées sont alignées : les données sont en effet liées par une relation linéaire très simple car si on ajoute l’année de naissance et l’âge au décès, on trouve toujours 2014, année du décès où se situe l’observation. L’oblique sur le graphique manifeste une dimension complémentaire, l’année de décès.

Pour visualiser mieux cette dimension complémentaire, ajoutons des individus fictifs décédés les deux premiers en 2010 et les deux derniers en 2020 :

G 1933 77 ans
H 1945 65 ans
I 1933 87 ans
J 1945 75 ans

Carnet2Graphique 2

On a ajouté sur ce graphique des obliques qui correspondent à l’année de décès, la droite E-A précédente correspondant à l’année 2014. Il s’agit bien ici d’une troisième dimension, rendue possible sur un graphique plan par le fait de la relation linéaire entre les trois dimensions.

***

Le graphique à trois dimensions représentable dans un plan du fait de la contrainte linéaire qui  les lie est bien connu dans la littérature sous le nom de graphique triangulaire. Son utilisation la plus fréquente concerne la représentation, par un point, de pourcentages en trois catégories dont la somme fait évidemment toujours 100.

À titre d’illustration, utilisons l’enquête 1997 sur les pratiques culturelles des français 4 où l’on avait posé la question de savoir si un auteur était « connu » et s’il l’était, s’il était « aimé », « non aimé » ou si la personne n’avait pas d’opinion à ce sujet. Voici le graphique triangulaire de la répartition des opinions à propos de Mozart :

MOZARTGraphique 3

On voit que, en 1997, Mozart est aimé par 79% des enquêtés, que 16% ne l’aiment pas et que seuls 5% ne le connaissent pas ou n’ont pas d’opinion à son sujet 5. On notera que la progression de Mozart vers le pôle « aime » a été forte par rapport à la précédente enquête (peut-être des suites du film Amadeus), les opposants étant du même ordre et la baisse des sans opinion correspondant à l’accroissement de son niveau d’appréciation.

On peut faire une représentation triangulaire analogue du graphique des dix personnes décédées de façon à rendre les trois dimensions équivalentes du point de vue graphique :

Carnet3Graphique 4

Le graphique à trois dimensions précédent et le graphique triangulaire ci-dessus donnent strictement la même information mais la dimension « année du décès » qui semblait perturber le graphique cartésien prend dans le graphique triangulaire une dimension analogue aux autres. On peut donc dire que les diagrammes de Lexis sont des graphiques triangulaires dont une des dimensions est plus ou moins éclipsée.

Prenons un auteur, Christophe Vanderschrick, qui a beaucoup travaillé sur le diagramme de Lexis puisqu’il a fait sa thèse sur le sujet 6 ainsi qu’un article dans Population 7. Dans son article de Population, l’auteur manifeste qu’il est bien conscient que les trois coordonnées d’un diagramme de Lexis,  temps, moment de naissance et âge, « présentent la caractéristique d’être parfaitement corrélées : si deux coordonnées sont connues, il est possible d’en déduire la troisième » (p. 1241). Avec un tel principe, on attendrait que l’auteur se tourne vers le graphique triangulaire mais il n’en est rien puisqu’il ajoute que « dans ces conditions, construire un diagramme bi-dimensionné (« diagramme en abscisse et ordonnée ») revient à privilégier deux des trois coordonnées, c’est-à-dire à leur réserver un axe » (p. 1241), ce qui veut dire que la troisième dimension est occultée.

À l’origine de l’usage actuel du diagramme de Lexis se trouve L’Analyse démographique de Roland Pressat 8, où sont bien précisées les significations d’un graphique à deux dimensions : en abscisse sont portées les « dates du calendrier » et en ordonnée « les durées relatives » 9. De ce fait, la présentation standard d’un diagramme de Lexis se présente de la façon suivante :

Lexis3bGraphique 5

Une génération (par exemple celle née en 1989) est représentée comme une bande diagonale et ne semble pas représenter une dimension du graphique alors que dans une représentation triangulaire des mêmes données, la génération apparait bien comme une des trois dimensions. On y voit aussi que l’année et la génération ont maintenant un rôle symétrique.

 Lexis4Graphique 6

On résout ainsi une difficulté de compréhension des divers types d’analyse.

Pour voir ce qu’apporte la représentation triangulaire par rapport au diagramme traditionnel, prenons à titre d’exemple un cas proposé dans un manuel d’exercices de démographie 10.

Il s’agit d’un exercice (noté N3) destiné à étudier la primo-nuptialité de plusieurs générations en Irlande. Les données de base sont les suivantes : on donne les proportions de célibataires par groupe quinquennal d’âges (pour 1 000 femmes). On suppose que ces proportions sont saisies au 1er janvier des années indiquées.

SujetN3

Il est demandé d’abord de construire le diagramme de Lexis. La solution proposée par les auteurs est la suivante :

ExempleN3bGraphique 7

L’axe horizontal, marqué comme « Date », sert à marquer les dates d’observation mais également les générations qui sont indiquées par des traits obliques.

Pour mieux comprendre la situation, prenons l’effectif le plus en haut et à droite de 157 qui correspond dans les données au groupe d’âge 50-54 ans observé l’année 1981. Pour voir à quelles générations il correspond, faisons un agrandissement en supposant des données annuelles et reportons-les sur un graphique triangulaire. On a le résultat suivant :

ExoGcGraphique 8

On voit que  les générations nées de 1926 à 1930 ont de 50 à 54 ans au 1er janvier 1981 (date marquée par un trait rouge).

Représentons, en utilisant les générations quinquennales suggérées dans le graphique d’origine, le diagramme de Lexis sous forme de graphique triangulaire.

Exo2cGraphique 9

Les proportions observées sont situées sur le côté rouge du triangle, celui qui correspond au 1er janvier de l’année.

***

Concluons : les démographes utilisent le terme de « diagramme » pour désigner leur représentation graphique des données. En utilisant ce terme plutôt que celui de « graphique », ils manifestent que le diagramme de Lexis, où une même coordonnée sert à plusieurs choses (date d’observation et génération), n’est pas un graphique où tous les éléments doivent être significatif, comme dans le graphique cartésien ou le graphique triangulaire. C’est un diagramme où les conventions d’écriture sont nombreuses comme quand l’auteur se sert d’une surface pour rendre compte d’un organigramme ou d’un raisonnement logique. En représentant le diagramme de Lexis sous forme d’un graphique triangulaire, on retrouve l’avantage d’une expression graphique standardisée.

On notera que proposer un diagramme triangulaire pour représenter trois dimensions en liaison linéaire a déjà été fait par le démographe américain Norman Ryder à propos d’une question de cohortes de mariages 11.

RyderGraphique 10

Les ébauches des coordonnées horizontales de durée sont indiquées mais non leur continuation à l’intérieur du graphique : ceci s’explique par le fait qu’il ne s’agit pas d’un graphique notant des observations mais d’un diagramme cherchant à montrer qu’il vaut mieux comparer des cohortes de mariages du point de vue de leur durée plutôt que de la date du calendrier.

Les démographes américains sont d’ailleurs réputés pour ne pas utiliser le diagramme de Lexis qui semble utilisé principalement par l’École française de démographie. Pour qu’il soit utilisé partout, il suffirait peut-être de lui retirer son aspect de diagramme avec ses règles spécifiques d’orientation et son abscisse qui exprime deux réalités différentes, et de l’inclure dans le monde des graphiques triangulaires, graphiques d’ailleurs antérieurs au diagramme de Lexis puisqu’ils avaient déjà été utilisés par d’Alembert 12.

Annexe : comment réaliser un graphique de Lexis triangulaire

Le logiciel Trideux permet de réaliser des graphiques triangulaires : bien qu’il ait été conçu pour représenter des profils de pourcentages répartis en trois nombres dont la somme fait cent, il est facile de le détourner pour ne conserver que « quadrillage » triangulaire pour ensuite introduire dans le graphique les éléments propres au graphique de Lexis.

On utilisera plutôt la version TrideuxOri51 ou TrideuxOri52 car certaines options graphiques sont inopérantes dans la version Trideux51 13. L’option « Graphique triangulaire » du menu déroulant « Tris » nécessite la présence d’un fichier de nom générique choisi par l’utilisateur et d’extension .TRG. Ce fichier texte peut être réalisé en dehors de Trideux. Il est composé de la façon suivante  (documentation en ligne) :

ligne 1 : titre général
ligne 2 : titre du pôle 1
ligne 3 : titre du pôle 2
ligne 4 : titre du pôle 3
lignes suivantes : nom en 4 caractères et trois valeurs numériques interprétables sur 5 caractères. Au moins une ligne de description d’un point est requise.

Par exemple le fichier suivant :

Titre général
Titre pôle 1
Titre pôle 2
Titre pôle 3
CNTR 33.3 33.3 33.3
POL1  90    2    8

donne le graphique suivant :

Essai1

Si l’on veut ne conserver que le quadrillage, il est possible de déplacer tous les points et les intitulés en dehors du graphique en les capturant avec le clic gauche de la souris et en les déplaçant avec la souris. On supprimera la trace rouge laissée en modifiant le paramètre de la couleur du trait. Une copie d’écran et son insertion dans un logiciel graphique, même simple comme l’utilitaire « Paint » de Windows, permet d’effacer ces points et de ne conserver que le quadrillage dont on pourra modifier les intitulés et afficher tous les effectifs dans les triangles voulus.

Exemple de réalisation du graphique 6.

On part du cas précédent : il suffit pour n’avoir plus que six éléments par axe d’agir sur les flèches (à droite du graphique) « déplacements des côtés ». Les touches externes augmentent le nombre de côtés, les touches internes les réduisent. En utilisant la touche du côté horizontal, on réduit à six le nombre d’éléments. Une copie d’écran et une recopie sur Paint permettent d’ajouter ce qu’il faut pour obtenir le graphique 6 :

Essai1bOn peut aussi obtenir le graphique 5 en commençant par utiliser (sous « déplacements des côtés ») l’option « Réinitialisation angulaire du graphique » avec les options « Angle droit » et « 3e coordonnée affichée ». On augmente le nombre de côtés pour pouvoir disposer d’un carré de 6 sur 6 complet :

Essai2

Si on veut retrouver l’orientation du graphique 5, il suffit de faire une transformation en miroir et de supprimer ce qui est en trop. On obtient alors le résultat suivant :

Essai3que l’on modifiera avec un logiciel graphique.

  1. Par ex. Léon Gani, Laurence Simmat-Durand, Démographie expliquée, Nathan, 2001 ; Catherine Rollet, Introduction à la démographie, Nathan 1995 []
  2. Graziella Caselli, Jacques Vallin et Guillaume Wunsch, Démographie : analyse et synthèse, INED, 2001. La présentation du diagramme de Lexis se trouve au chapitre 6 du premier volume. []
  3. Wilheim Lexis, La représentation graphique de la mortalité au moyen de points mortuaires, Paris, G.Masson, 1881 (reprise d’un article des Annales de Démographie internationale, 1880). []
  4. Olivier Donnat, Les pratiques culturelles des Français. Enquête 1997, Documentation française, 1998 []
  5. Graphique issu de : Philippe Cibois, « Le nouvel avenir d’un ancien : le graphique triangulaire » in Jean-Pierre Poussou & Isabelle Robin-Romero (dir.), Histoire des familles, de la démographie et des comportements en hommage à Jean-Pierre Bardet, Presses de l’Université Paris-Sorbonne, 2007, p.73-82. Texte en ligne []
  6. Christophe Vanderschrick, Diagramme de Lexis et cohortes : du temporel au non-temporel, Louvain-la-Neuve, Janvier 2005, en ligne. []
  7. Christophe Vanderschrick, « Le diagramme de Lexis revisité », Population, vol. 47, 1992, p. 1241-1262, en ligne. []
  8. Roland Pressat, L’Analyse démographique, Ined, 1961 []
  9. p.76 de l’édition de 1973 []
  10. Alfred Dittgen, Marlène Lamy-Festy, Travaux pratiques d’analyse démographique, Masson, 1988. []
  11. Norman B. Ryder, Fertility Measurement Through Cross-Sectional Surveys, Social Forces, Vol. 54, No. 1 (Sep., 1975), pp 7-35. Graphique signalé dans : Caselli Graziella, Enzo Lombardo, Graphiques et analyse démographique : quelques éléments d’histoire et d’actualité, Population 45, N°2, 1990, p. 407. []
  12. Philippe Cibois, « Le nouvel avenir d’un ancien : le graphique triangulaire » in Jean-Pierre Poussou & Isabelle Robin-Romero (dir.), Histoire des familles, de la démographie et des comportements en hommage à Jean-Pierre Bardet, Presses de l’Université Paris-Sorbonne, p.73-82. Texte en ligne []
  13. Toutes ces options sont disponibles à cette adresse []

Philippe Cibois

Philippe Cibois, né en 1941, est professeur émérite de sociologie de l'université de Versailles - St-Quentin en Yvelines. Il est président du conseil d'administration de l’École nouvelle la Source.

More Posts - Website

Représenter graphiquement les résultats d’une analyse factorielle avec R

Par Anton Perdoncin et Pierre Mercklé1

L’objectif de ce tutoriel est de montrer comment produire avec le logiciel R des représentations graphiques lisibles et démonstratives des résultats d’une analyse géométrique des données (analyse des correspondances multiples, analyse en composantes principales…). C’est en effet l’un des avantages considérables de R par rapport aux autres logiciels de traitement de données quantitatives (SAS, SPSS, Stata, notamment) que de fournir des outils graphiques performants, permettant de produire de manière relativement aisée des présentations agréables.

Les méthodes d’analyse géométrique des données permettent de fournir le meilleur résumé possible de la structure d’un ensemble d’observations effectuées sur un échantillon et enregistrées dans une table de données. Sans entrer ici dans le détail de l’exposé des principes de cette famille de méthodes2, il suffit de dire que l’objectif est de résumer le mieux possible l’information contenue dans la totalité des nombreuses variables d’origine par un nombre réduits de « facteurs » (qu’on représentera ensuite graphiquement par des « axes ») qui correspondent à des combinaisons de ces variables. La dimension graphique fait partie intégrante de ces méthodes et en constitue l’un des instruments de démonstration et d’argumentation les plus forts, puisqu’elle permet d’appréhender rapidement une grande quantité d’information. A condition, évidemment, de mener correctement l’interprétation statistique des axes factoriels… et de produire des graphiques qui soient aisément lisibles ! C’était déjà l’objectif de la macro ACM pour Excel qu’avait développée Olivier Godechot, et c’est un objectif similaire que nous voulons poursuivre ici avec R3.

Nous nous concentrerons ici sur une technique particulière au sein de la famille de l’analyse géométrique des données : l’analyse des correspondances multiples (ACM). Cette technique permet d’analyser un nombre important de variables dites « qualitatives », autrement dit, de variables discrètes qui peuvent prendre un nombre délimité de valeurs possibles : le sexe, la catégorie socioprofessionnelle, le genre musical préféré, etc. ; mais aussi n’importe quelle variable « quantitative », comme l’âge, le revenu, le temps passé devant la télévision, à condition qu’elle soit recodée en tranches.

Dans ce qui suit, nous allons utiliser un exemple délibérément simple, réduit à quelques variables, pour montrer quelques opérations faciles permettant de construire des graphiques d’analyse des correspondances multiple sur-mesure avec R.

1. Réaliser une ACM avec FactoMineR

Le package FactoMineR est l’outil idéal pour mener une analyse géométrique des données avec le logiciel R. Nous nous contenterons, dans ce tutoriel, d’expliquer rapidement comment réaliser une analyse des correspondances multiples (ACM) et comment représenter graphiquement ses résultats. Si vous souhaitez aller plus loin et avoir plus d’informations sur FactoMineR4 et ses diverses fonctionnalités, rendez-vous sur le site internet qui lui est dédié : http://factominer.free.fr.

A. Installer et charger le package FactoMineR

Une première remarque avant de commencer : avant même d’installer FactoMineR, il faut bien sûr d’abord installer R5, ainsi éventuellement qu’une interface graphique permettant d’en rendre l’usage plus aisé. Nous recommandons particulièrement l’interface RStudio6 (logiciel libre et multi-plateformes, tout comme R), qui facilite l’écriture des scripts ainsi que le traitement des sorties graphiques, mais qui nécessite d’écrire les lignes de commande. L’interface RCommander7, elle, propose menus déroulants ou cases à cocher pour activer certaines des fonctionnalités de R, dont celles dédiées à l’ACM ; elle affiche aussi les lignes de commande correspondantes.

Pour toute la suite, vous pouvez évidemment retaper dans R les lignes d’instructions qui jalonnent ce tutoriel, ou bien les « copier-coller ». Mais pour plus de simplicité, nous vous proposons d’utiliser le script d’accompagnement, qui reproduit toutes ces lignes d’instructions. Il se trouve ici, il ne vous reste plus qu’à le télécharger , le décompresser et l’ouvrir dans R (par exemple en double-cliquant dessus) :

http://quanti.hypotheses.org/files/2014/05/quanti-acm-avec-R.zip

L’installation du package FactoMineR vient juste après. Elle ne doit être réalisée qu’une seule fois. La commande library() doit en revanche être exécutée à l’ouverture de chaque nouvelle session de travail :

> install.packages(« FactoMineR »)
> library(FactoMineR)

B. Télécharger et préparer les données

Pour illustrer ce tutoriel, nous allons utiliser l’extrait de données de l’enquête « Histoires de vie » (HDV) réalisée par l’INSEE en 2003, et qui est inclus dans le package questionr8. Il faut donc également installer et charger ce package :

> install.packages(« questionr »)
> library(questionr)

Ensuite, pour charger les données de l’enquête HDV, il suffit d’utiliser la fonction data(), puis d’en faire une copie dans l’objet DONNEES :

> data(hdv2003)
> SOURCE <- hdv2003

La fonction str() vous permet d’avoir un aperçu des variables contenues dans la table DONNEES :

> str(SOURCE)
‘data.frame’: 2000 obs. of 20 variables:
$ id : int 1 2 3 4 5 6 7 8 9 10 …
$ age : int 28 23 59 34 71 35 60 47 20 28 …
$ sexe : Factor w/ 2 levels « Homme », »Femme »: 2 2 1 1 2 2 2 1 2 1 …
$ nivetud : Factor w/ 8 levels « N’a jamais fait d’etudes »,..: 8 NA 3 8 3 6 3 6 NA 7 …
$ poids : num 2634 9738 3994 5732 4329 …
$ occup : Factor w/ 7 levels « Exerce une profession »,..: 1 3 1 1 4 1 6 1 3 1 …
$ qualif : Factor w/ 7 levels « Ouvrier specialise »,..: 6 NA 3 3 6 6 2 2 NA 7 …
$ freres.soeurs: int 8 2 2 1 0 5 1 5 4 2 …
$ clso : Factor w/ 3 levels « Oui », »Non », »Ne sait pas »: 1 1 2 2 1 2 1 2 1 2 …
$ relig : Factor w/ 6 levels « Pratiquant regulier »,..: 4 4 4 3 1 4 3 4 3 2 …
$ trav.imp : Factor w/ 4 levels « Le plus important »,..: 4 NA 2 3 NA 1 NA 4 NA 3 …
$ trav.satisf : Factor w/ 3 levels « Satisfaction »,..: 2 NA 3 1 NA 3 NA 2 NA 1 …
$ hard.rock : Factor w/ 2 levels « Non », »Oui »: 1 1 1 1 1 1 1 1 1 1 …
$ lecture.bd : Factor w/ 2 levels « Non », »Oui »: 1 1 1 1 1 1 1 1 1 1 …
$ peche.chasse : Factor w/ 2 levels « Non », »Oui »: 1 1 1 1 1 1 2 2 1 1 …
$ cuisine : Factor w/ 2 levels « Non », »Oui »: 2 1 1 2 1 1 2 2 1 1 …
$ bricol : Factor w/ 2 levels « Non », »Oui »: 1 1 1 2 1 1 1 2 1 1 …
$ cinema : Factor w/ 2 levels « Non », »Oui »: 1 2 1 2 1 2 1 1 2 2 …
$ sport : Factor w/ 2 levels « Non », »Oui »: 1 2 2 2 1 2 1 1 1 2 …
$ heures.tv : num 0 1 0 2 3 2 2.9 1 2 2 …

Le jeu de données comporte 2000 individus, et 20 variables parmi lesquelles : d’une part des variables décrivant les caractéristiques socio-démographiques des individus (age, sexe, nivetud, etc.), et d’autre part des variables décrivant leurs pratiques de loisirs (hard.rock, lecture.bd, peche.chasse, etc.). Ces dernières sont bien des variables « qualitatives », toutes de type « Factor » (indispensable pour mener l’ACM9), et comportant deux modalités : « Oui » ou « Non » selon que l’activité est pratiquée ou non.

Pour l’analyse qui suit, on ne conserve que les 7 variables qui décrivent les loisirs, qui vont être les variables « actives » de l’ACM, et 3 variables socio-démographiques, qui vont être les variables « supplémentaires » ou « illustratives » :

> DONNEES <- subset(SOURCE, select=c(« hard.rock », « lecture.bd », « peche.chasse », « cuisine », « bricol », « cinema », « sport », « age », « sexe », « qualif »))

On a vu dans le préambule que l’analyse des correspondances multiples s’appliquait aux variables qualitatives. C’est le cas de presque toutes les variables que nous avons sélectionnées, sauf de l’âge. Nous allons donc recoder la variable age en 4 tranches d’effectifs à peu près égaux, en utilisant les fonction cut() et quantile() de R :

> DONNEES$age <- cut(DONNEES$age, breaks=quantile(DONNEES$age))

On peut jeter un nouveau un œil à nos données pour vérifier qu’elles se présentent bien comme voulu :

> str(DONNEES)
‘data.frame’: 2000 obs. of 12 variables:
$ hard.rock : Factor w/ 2 levels « Non », »Oui »: 1 1 1 1 1 1 1 1 1 1 …
$ lecture.bd : Factor w/ 2 levels « Non », »Oui »: 1 1 1 1 1 1 1 1 1 1 …
$ peche.chasse: Factor w/ 2 levels « Non », »Oui »: 1 1 1 1 1 1 2 2 1 1 …
$ cuisine : Factor w/ 2 levels « Non », »Oui »: 2 1 1 2 1 1 2 2 1 1 …
$ bricol : Factor w/ 2 levels « Non », »Oui »: 1 1 1 2 1 1 1 2 1 1 …
$ cinema : Factor w/ 2 levels « Non », »Oui »: 1 2 1 2 1 2 1 1 2 2 …
$ sport : Factor w/ 2 levels « Non », »Oui »: 1 2 2 2 1 2 1 1 1 2 …
$ age : Factor w/ 4 levels « (18,35] », »(35,48] »,..: 1 1 3 1 4 1 3 2 1 1 …
$ sexe : Factor w/ 2 levels « Homme », »Femme »: 2 2 1 1 2 2 2 1 2 1 …
$ qualif : Factor w/ 7 levels « Ouvrier specialise »,..: 6 NA 3 3 6 6 2 2 NA 7 …

C. Réaliser l’ACM et stocker les résultats

On réalise l’ACM grâce à la fonction MCA() du package FactoMineR. On stocke les résultats de l’ACM dans un objet que l’on appelle resultats :

resultats <- MCA(DONNEES, ncp=5, quali.sup=8:10, graph=FALSE)

Dans l’instruction ci-dessus, on a précisé trois arguments pour la fonction MCA :

  • ncp=5 : nombre d’axes pour lesquels on conserve l’information
  • quali.sup=8:10 : on précise que les variables 8 à 10 (age à qualif) de l’objet DONNEES doivent être considérées comme des variables qualitatives supplémentaires, autrement dit elles ne contribuent pas au calcul des facteurs ni donc à la formation des axes. Mais on pourra tout de même les représenter graphiquement, en les « projetant » sur les plans formés par les axes factoriels calculés à partir des seules variables « actives » (ici donc, les 7 variables décrivant les loisirs, de hard.rock à sport).
  • graph=FALSE : on ne souhaite pas que les graphiques soient produits. Par défaut, la fonction MCA génère une série de graphiques, souvent illisibles et dont l’interprétation peut être très trompeuse car le tri n’y est pas fait entre modalités contributives et non contributives (voir infra pour la visualisation des graphiques par défaut de FactoMineR).

Qu’y a-t-il dans l’objet resultats ?

> print(resultats)
**Results of the Multiple Correspondence Analysis (MCA)**
The analysis was performed on 2000 individuals, described by 12 variables
*The results are available in the following objects:
name description
1 « $eig » « eigenvalues »
2 « $var » « results for the variables »
3 « $var$coord » « coord. of the categories »
4 « $var$cos2 » « cos2 for the categories »
5 « $var$contrib » « contributions of the categories »
6 « $var$v.test » « v-test for the categories »
7 « $ind » « results for the individuals »
8 « $ind$coord » « coord. for the individuals »
9 « $ind$cos2 » « cos2 for the individuals »
10 « $ind$contrib » « contributions of the individuals »
11 « $quali.sup » « results for the supplementary categorical variables »
12 « $quali.sup$coord » « coord. for the supplementary categories »
13 « $quali.sup$cos2 » « cos2 for the supplementary categories »
14 « $quali.sup$v.test » « v-test for the supplementary categories »
15 « $call » « intermediate results »
16 « $call$marge.col » « weights of columns »
17 « $call$marge.li » « weights of rows »

Nous allons nous intéresser principalement aux objets 1 (valeurs propres), 3 (coordonnées des modalités actives), 5 (contributions des modalités actives), 8 (coordonnées des individus), et 12 (coordonnées des modalités qualitatives supplémentaires). On peut avoir du reste un premier aperçu des contenus de ces différents objets avec la classique commande summary(resultats).

Commençons par les valeurs propres. Tout le propos de l’analyse des correspondances multiples consiste à résumer un nombre élevé de variables (ici, les 7 variables décrivant les loisirs) par un nombre plus faible de « facteurs ». On parle aussi de dimensions ou d’axes.

Pour comprendre comment sont calculés ces facteurs, il faut se faire une idée, même approximative, de la logique de l’algorithme de l’ACM, autrement dit de la logique de ce que l’on appelle la « décomposition factorielle » : le premier facteur calculé par l’algorithme de l’ACM est toujours celui qui permet de conserver la plus grande part possible des variations de l’information contenue dans le tableau des variables actives. Une fois ce premier facteur trouvé, on recalcule le tableau des variables actives en n’y conservant que le reste, autrement dit que la part des variations qui n’a pas été expliquée par le premier facteur. Le deuxième facteur est ensuite calculé de la même façon sur ce reste, donc de telle façon qu’il conserve la plus grande part possible des variations de l’information contenue dans ce « reste »… Et ainsi de suite, jusqu’à ce que l’on ait absorbé la totalité des variations à expliquer. Dans le cas où les variables actives sont dichotomiques comme ici (elles ne peuvent prendre que les valeurs « Oui » ou « Non »), le nombre de facteurs ainsi calculés sera nécessairement inférieur ou égal au nombre de variables (dans le cas général, il sera toujours inférieur à nombre de modalités actives – nombre de variables actives).

2. Combien de facteurs faut-il retenir ? L’histogramme des valeurs propres

Dans notre exemple, on va donc obtenir au maximum 7 facteurs, classés du plus important au moins important (ou du plus explicatif au moins explicatif) et à chacun de ces 7 facteurs va être associée une « valeur propre » qui traduit la quantité d’information expliquée par le facteur :

> print(resultats$eig)
eigenvalue                          percentage of variance       cumulative percentage of variance
dim 1    0.2121854                       21.21854                       21.21854
dim 2    0.1542803                       15.42803                       36.64657
dim 3    0.1468192                       14.68192                       51.32849
dim 4    0.1387719                       13.87719                       65.20568
dim 5    0.1349671                       13.49671                       78.70239
dim 6    0.1192865                       11.92865                       90.63104
dim 7    0.0936896                       9.36896                       100.00000

On traduit en général cette information sous la forme d’un « pourcentage d’inertie », contenu ici dans la deuxième colonne de resultat$eig, et correspondant donc à la proportion des variations totales des variables originales expliquées par chaque facteur.

Faut-il analyser tous les facteurs ? Non, évidemment, puisque le but de la démarche est de rendre compte de la plus grande partie possible de l’information originale, avec le nombre le plus petit possible de « variables ». Combien en retenir ? C’est l’examen de l’histogramme des valeurs propres qui va permettre de choisir. On trace cet histogramme de la façon suivante, avec la fonction barplot(), en y faisant figurer le pourcentage d’inertie en ordonnée :

> barplot(resultats$eig[, 2], main= »Histogramme des valeurs propres », names.arg=rownames(resultats$eig), xlab= »Axes », ylab= »Pourcentage d’inertie », cex.axis=0.8, font.lab=3, col= »orange »)

1-HISTOVP

A chaque fois que l’on rajoute un facteur à l’analyse on gagne en inertie totale expliquée, mais on perd en parcimonie. L’idée est donc de n’ajouter des facteurs à l’analyse que si le gain en inertie reste avantageux par rapport à la perte en parcimonie. On peut utiliser l’histogramme des valeurs propres pour effectuer visuellement cet arbitrage à l’aide du critère du « coude » : ici, on observe un décrochement (coude), suivi d’une décroissance régulière, entre le premier et le deuxième facteur, ce qui pourrait inciter à n’examiner que le premier facteur. Mais ce n’est pas la seule règle possible : un autre critère de choix (appelé « critère de Kaiser ») suggère de garder tous les facteurs dont la valeur propre est supérieure à la valeur propre moyenne (qui vaut par définition 1 divisé par le nombre de facteurs). Ici, le critère de Kaiser incite à retenir les facteurs dont le pourcentage d’inertie est supérieur à (100/7=) 14,3%, autrement dit à retenir les trois premiers facteurs. Pour les besoins de la démonstration d’aujourd’hui, on coupera la poire en deux, et on se contentera d’analyser les deux premiers facteurs, qui cumulent presque 37% de l’inertie totale (21,2% pour le premier facteur et 15,4% pour le deuxième facteur).

3. Essayer les fonctionnalités graphiques du package FactoMineR

Par défaut, sauf si l’on a ajouté l’argument plot=FALSE comme précédemment, l’exécution de la fonction MCA() entraîne la production d’un certain nombre de graphiques : ensemble des modalités actives et supplémentaires, individus, variables seules.

On peut également demander à FactoMineR de tracer des graphiques plus spécifiques, grâce à la fonction plot.MCA. Les différents graphiques (variables, modalités actives, modalités supplémentaires, individus) peuvent être obtenus en jouant avec les valeurs possibles des arguments choix (pour définir le type de graphique) ou invisible (pour définir ce qu’on veut enlever de la représentation graphique). Dans l’exemple ci-dessous, on représente ces quatre graphiques ensemble :

> # Définir la répartition : 2×2
> par(mfrow=c(2, 2))
> # Variables actives et supplémentaires, avec l’argument choix= »var »
> plot.MCA(resultats, choix= »var », title= »Variables actives et supplémentaires », axes=c(1, 2))
> # Modalités actives
> plot.MCA(resultats, invisible=c(« ind », « quali.sup »), title= »Modalités actives », axes=c(1, 2))
> # Modalités supplémentaires
> plot.MCA(resultats, invisible=c(« ind », « var »), title= »Modalités supplémentaires », axes=c(1, 2))
> # Individus
> plot.MCA(resultats, invisible=c(« quali.sup », « var »), title= »Nuage des individus », axes=c(1, 2))

2-PLOTMCA

Ces graphiques de base peuvent rapidement devenir illisibles, si le nombre de modalités est important (ce qui est fréquent). De plus, ils ne permettent pas de distinguer entre les modalités qui contribuent le plus fortement et celles qui ne contribuent pas aux axes représentés, ce qui peut induire le sociologue et son lecteur en erreur.

Le module graphique de FactoMineR a été récemment amélioré afin de répondre à ces problèmes. De nombreuses options peuvent ainsi être spécifiées dans la fonction plot.MCA, que l’on trouvera aisément en exécutant ?plot.MCA. Il est notamment possible de sélectionner les modalités que l’on souhaite représenter ou omettre selon certains critères, d’augmenter ou de diminuer la taille des points, de modifier les couleurs, etc.

Pour une présentation synthétique des diverses fonctionnalités graphiques de FactoMineR, des vidéos ont été réalisées par François Husson, l’un des créateurs du package, et sont disponibles sur internet. Voyez notamment la vidéo consacrée à l’ACM et au module graphique de FactoMineR, à cette adresse : http://goo.gl/Pfymh0.

4. Réaliser soi-même un graphique sur-mesure

Malgré ces améliorations très appréciables et utiles du module graphique de FactoMineR, certains utilisateurs peuvent souhaiter réaliser eux-mêmes leurs graphiques afin de sélectionner à leur guise les points représentés, choisir les symboles, les couleurs, établir une légende lisible… Tout cela est possible, et même assez facile en se servant des fonctions graphiques habituelles de R…

A. Quelles modalités représenter ?

La première étape est de déterminer quelles sont les modalités actives que l’on souhaite représenter sur le graphique. Dans le cas où elles sont peu nombreuses, on peut choisir de toutes les représenter. Dans le cas où elles sont très nombreuses, on peut se servir de leur contribution aux facteurs représentés pour sélectionner celles qui ont justement les contributions les plus importantes. Un critère possible est de ne retenir que les modalités dont la contribution est supérieure à deux fois la contribution moyenne (Cibois, 1986, 1997). Ce seuil est évidemment arbitraire, et rien n’empêche de retenir un seuil plus élevé ou plus faible, suivant le nombre de modalités qu’on veut représenter. Dans notre cas, le nombre de modalités actives étant faible, on peut garder celles dont la contribution à l’un ou l’autre des deux premiers facteurs est simplement supérieure à la contribution moyenne.

La contribution moyenne est l’inverse du nombre de modalités actives. Dans notre cas, les 7 variables actives se décomposent en un total de 14 modalités. La contribution moyenne est donc égale à 100/14 = 7.1%). On ne retiendra donc dans l’interprétation des deux premiers axes de notre ACM que les modalités dont la contribution est supérieure à 7,1%. Pour savoir quelles sont ces modalités, on peut examiner le tableau des contributions des modalités actives aux deux premiers facteurs :

> round(resultats$var$contrib[,1:2], 1)
Ce qui donne le résultat suivant :
Dim 1 Dim 2
hard.rock_Non 0.0 0.0
hard.rock_Oui 1.0 0.1
lecture.bd_Non 0.1 0.0
lecture.bd_Oui 3.2 1.1
peche.chasse_Non 0.1 7.1
peche.chasse_Oui 0.7 56.2
cuisine_Non 4.2 0.8
cuisine_Oui 5.3 1.0
bricol_Non 6.9 8.9
bricol_Oui 9.3 12.0
cinema_Non 14.0 4.4
cinema_Oui 19.9 6.3
sport_Non 12.8 0.7
sport_Oui 22.6 1.3

On peut voir que les contributions les plus fortes à l’axe 1 viennent du cinéma et du sport, puis du bricolage (modalités actives 9 à 14), et que sur l’axe 2 elles sont dues essentiellement à ceux qui pratiquent la pêche et la chasse (6) puis également au bricolage. On peut donc retenir toutes ces modalités actives qui contribuent le plus fortement à l’un ou l’autre des deux premiers axes, qui sont ceux que nous avons retenus.

On crée ensuite un vecteur moda qui stocke les numéros de ces modalités, afin de pouvoir les appeler automatiquement dans les graphiques. On peut le faire « à la main » en indiquant les numéros de ces modalités. En l’occurrence, elles sont donc placées dans les positions suivantes : 6, 9, 10, 11, 12, 13 et 14:

> moda <- c(6, 9 :14)

Pour les plus habiles avec R et ses multiples fonctions, on aurait aussi pu écrire une petite condition qui sélectionne automatiquement les numéros des modalités dont la contribution est supérieure à la contribution moyenne :

> seuil <- 100/nrow(resultats$var$contrib)
> moda <- which(resultats$var$contrib[, 1]>seuil | resultats$var$contrib[, 2]>seuil)

On peut alors visualiser les coordonnées des modalités sélectionnées, sur les deux premiers axes :

> round(resultats$var$coord[moda, 1:2], 2)
Dim 1 Dim 2
peche.chasse_Oui 0.31 2.33
bricol_Non -0.42 -0.41
bricol_Oui 0.57 0.55
cinema_Non -0.60 0.29
cinema_Oui 0.85 -0.41
sport_Non -0.55 0.11
sport_Oui 0.96 -0.20

B. Le graphique des modalités pas à pas

Le principe est le suivant : on trace un graphique simple, on sélectionne les modalités que l’on souhaite représenter, on définit le style et la taille des symboles, on nomme les labels des points, et on précise leurs positions.

Les fonctions graphiques utilisées sont les suivantes :

  • plot : fonction graphique de base dans R, pour tracer le cadre et l’arrière-fond du graphique ;
  • abline : pour ajouter des lignes verticales et horizontales ;
  • points : pour tracer les points, leur donner une couleur, une forme… ;
  • text : pour donner des labels aux points et les positionner
  • lines : pour relier des points entre eux
  • legend : pour configurer et positionner la légende du graphique.

a. Créer le cadre et l’arrière-plan du graphique

C’est le point de départ : il s’agit de créer la fenêtre graphique adaptée pour représenter les modalités sélectionnées.

> windows(7, 10)
> par(mfrow=c(1,1))
> plot(resultats$var$coord[moda, 1:2]*1.2, type= »n », xlab=paste0(« Axe 1 (« , round(resultats$eig[1,2], 1), « %) »), ylab=paste0(« Axe 2 (« , round(resultats$eig[2,2], 1), « %) »), main= »Premier plan factoriel », cex.main=1, cex.axis=0.8, cex.lab=0.7, font.lab=3)
> abline(h=0, v=0, col= »grey », lty=3, lwd=1)

La fonction windows() permet d’ouvrir une nouvelle fenêtre graphique, dont on a indiqué ici la largeur et la hauteur en pouces. Attention, cette fonction ne fonctionnera que sous Windows, sous Linux il faudra utiliser x11(), et quartz() sous OSX.. L’instruction par(mfrow=c(1,1)) permet d’afficher un seul graphique (une seule ligne, une seule colonne) dans la totalité de la fenêtre ouverte. En suite, dans la fonction plot(), on commence par préciser l’objet à partir duquel le graphique est construit. Ici, il s’agit des coordonnées des modalités actives pour les axes 1 et 2. Le principe est d’ajuster une fenêtre graphique un peu plus grande que les données (x1.2), afin de ne pas avoir de marges blanches inutilement grandes, mais en évitant de tronquer les libellés des modalités qui seront sur les bords du graphique. La multiplication par 1.2 permet d’avoir une marge de 20% autour des modalités les plus marginales.

Puis on spécifie un certain nombre d’arguments :

  • type= »n » signifie que rien n’est tracé dans le graphique (on tracera les points séparément dans un second temps).
  • xlab et ylab permettent de donner un nom aux axes x et y. Ici on y ajoute entre parenthèses les pourcentages d’inertie conservés par chacun des axes.
  • main permet de donner un titre au graphique.
  • cex.main, cex.axis et cex.lab permettent de fixer la taille de la police respectivement du titre, des graduations sur les axes et des labels des axes : 1 est la valeur par défaut, une valeur supérieure à 1 augmente la taille, une valeur inférieure à la diminue
  • font.lab permet de déterminer le style de police (1 : normal ; 2 : gras ; 3 : italiques ; 4 : gras italiques).

La fonction abline permet d’ajouter des lignes sur un graphique. Elle prend également des arguments :

  • h=a coordonnée de la ligne horizontale.
  • v=b coordonnée de la ligne verticale.
  • col : couleur du trait, avec une infinité ou presque de couleurs possibles, qu’on peut désigner soit par leur nom en anglais, soit avec la fonction colors() et des numéros de code, par exemple colors()[8] donnera « aquamarine » : voir ici la charte des couleurs de R).
  • lty : type de trait (1=plein, 2=tirets courts, 3=points, 4=tirets+points, 5=tirets longs, 6=deux tirets).
  • ltw : épaisseur du trait. Comme pour les arguments de type cex une valeur supérieure à 1 augmente l’épaisseur, une valeur inférieure à la diminue.

On obtient donc un graphique vide, mais de la bonne taille pour accueillir nos données (cliquer sur l’image pour la voir en taille réelle) :

b. Représenter les points et les étiquettes des modalités actives

C’est la seconde étape importante : il s’agit de faire en sorte que dans l’ensemble le graphique soit lisible, tout en utilisant les fonctionnalités graphiques de R pour représenter visuellement toutes les informations importantes pour l’analyse. Commençons par dessiner les points des modalités actives :

> points(resultats$var$coord[moda, 1:2], col= »black », pch=c(15, 16, 16, 17, 17, 6, 6), cex=1.5)

Dans cet exemple, on ne va representer que les modalités actives qui contribuent plus que la moyenne, avec la condition [moda, 1:2] (1:2 pour sélectionner les coordonnées sur les deux premiers axes) ; l’argument pch permet de choisir la forme du point10, etc. L’argument cex fixe la taille des points : pour des raisons de lisibilité du graphique, on multiplie par 1.5 la taille par défaut. Il serait également possible de proportionner la taille des points à la contribution de chaque modalité, en affectant à cex la moyenne des contributions sur les deux premiers axes par exemple…

On positionne ensuite les étiquettes des modalités actives. Pour récupérer ces étiquettes, on peut utiliser rownames(resultats$var$coord) par exemple :

> etiquettes <- rownames(resultats$var$coord)
> print(etiquettes)
[1] « hard.rock_Non » « hard.rock_Oui » « lecture.bd_Non » « lecture.bd_Oui » « peche.chasse_Non »
[6] « peche.chasse_Oui » « cuisine_Non » « cuisine_Oui » « bricol_Non » « bricol_Oui »
[11] « cinema_Non » « cinema_Oui » « sport_Non » « sport_Oui »

Si l’on indexe le vecteur lab avec les valeurs de moda, on obtient automatiquement les labels des dix modalités actives les plus contributives, qu’on va afficher avec la fonction text() :

> text(resultats$var$coord[moda,1:2], labels=etiquettes[moda], col= »black », cex=1, pos=4)

La fonction text() prend tout d’abord deux valeurs x et y qui permettent de positionner le texte. Ici, on fournit pour x les coordonnées de nos modalités sur le premier axe, et pour y les coordonnées de nos modalités sur le deuxième axe. L’argument labels permet de préciser le texte à écrire : ici, les noms des modalités actives, avec les mêmes couleurs que pour les points. L’argument pos permet de fixer la position du label par rapport à sa coordonnée afin de faire en sorte que les labels ne se chevauchent pas : 1/ dessous ; 2/ à gauche ; 3/ dessus ; 4/ à droite. Ici, on a choisi de les afficher à droite des points.

Nuage des modalités actives

c. Ajout des modalités supplémentaires

On s’intéresse désormais à l’objet resultats$quali.sup$coord, qui stocke les coordonnées des variables qualitatives supplémentaires. On se rappelle qu’on a ajouté 5 variables supplémentaires dans le modèle : age (groupé en quartiles), sexe, nivetud et qualif. Les coordonnées des modalités de ces variables supplémentaires, qui correspondent aux « centres de gravité » des individus qui portent les propriétés correspondantes, peuvent être utilisées pour « projeter » ces modalités sur le plan factoriel structuré par les variables actives.

> print(resultats$quali.sup$coord[, 1:2])

Pour y parvenir, on va cette fois utiliser seulement la fonction text(), pour alléger le graphique et distinguer encore plus clairement les modalités supplémentaires des modalités actives.

> text(resultats$quali.sup$coord[c(1:4, 6:7, 9:13), 1:2]*1.2, labels=rownames(resultats$quali.sup$coord[c(1:4, 6:7, 9:13), ]), cex=0.8, col= »blue », font=3)

On remarquera dans l’instruction ci-dessus qu’on a multiplié les coordonnées des variables supplémentaires par un coefficient de 1.2, ce qui permet de dilater un peu leur représentation pour en faciliter la lecture. Cette pratique, qui peut prêter à discussion, doit être signalée en légende du graphique : on indiquera par exemple ici que « les coordonnées des modalités supplémentaires ont été éloignées du centre du graphique dans un rapport de 120% pour faciliter la lecture ».

Enfin, il peut être utile de relier les points d’une même variable entre eux afin de mieux mettre en évidence l’ordonnancement de ses modalités sur l’un ou l’autre des axes, en particulier dans le cas de variables ordinales (dont les modalités peuvent être hiérarchisées). C’est le cas ici des tranches d’âge, qu’on va donc relier par une ligne bleue :

> lines(resultats$quali.sup$coord[1:4,1:2]*1.2, col= »blue », lty=4)

La fonction lines() prend comme deux premiers arguments les coordonnées des points à relier. Ici, on a relié les points de la variable d’âge, soit les quatre premières modalités de l’objet resultats$quali.sup$coord pour le premier et le second axe. L’argument lty permet de définir le type de ligne, ici des pointillés.

Et voici le résultat :

Nuage des modalités actives et supp

d. Ajout d’une légende avec les noms des variables.

On peut enfin souhaiter ajouter une légende qui synthétise les noms des variables représentées sur le graphique, en reprenant le code de couleurs et de symboles. On utilise pour cela la fonction legend :

legend(« topleft », legend=c(« Pêche et chasse », « Bricolage », « Cinéma », « Sport », « Supplémentaires »), bty= »y », bg= »white », text.col=c(1,1,1,1, »blue »), col=c(1,1,1,1, »blue »), pch=c(15,16,17,6,0), cex=0.8, pt.cex=c(1,1,1,1,0))

Explication des arguments :

  • Le premier argument positionne la légende dans le graphique ; d’autres positions sont possibles : «  »top », « topright », « right », bottomright », « bottom », « bottomleft », « left », « center ».
  • L’argument legend spécifie ce qu’il s’agit d’écrire dans la légende.
  • bty précise si un cadre doit être tracé (bty= »o ») ou non (bty= »n »).
  • bg précise la couleur de fond de la légende.
  • Les arguments text.col, col et pch reprennent les couleurs et les symboles utilisés dans le graphique afin de les affecter non plus aux modalités mais aux types de variables.
  • cex et pt.cex permet d’indiquer la taille du texte et des points. Ici, 0 permet de ne pas afficher de points pour la légende des « modalités supplémentaires ».

Nuage des modalités actives et supplémentaires légende

C. Le nuage des individus pas à pas

Il est souvent très instructif d’observer le nuage des individus. La fonction plot.MCA du package FactoMineR, avec l’argument invisible=c(« var », « quali.sup »), est la plupart du temps suffisante. L’argument habillage permet également de colorer les points des individus selon leur modalité de réponse à telle ou telle question.

Mais dans les cas où le jeu de données comporte un grand nombre d’individus, il arrive que la mémoire du logiciel R soit insuffisante, et qu’il soit impossible de générer un graphique via la fonction plot.MCA. Il arrive également que la légende créée automatiquement ne soit pas bien positionnée et cache en partie le nuage de points. C’est pourquoi on va de nouveau avoir recours aux fonctions graphiques habituelles de R…

a. Représenter le nuage des individus.

On s’intéresse ici à l’objet resultats$ind$coord, qui stocke cette fois les coordonnées des individus sur les différents axes. On représente ici tout simplement les points des individus sur les deux premiers axes avec la fonction points(), après avoir créé un cadre vide comme on a appris à le faire à l’étape précédente :

> windows(7, 10)
> par(mfrow=c(1,1))
> plot(resultats$ind$coord[, 1:2], type= »n », xlab=paste0(« Axe 1 (« , round(resultats$eig[1,2], 1), « %) »), ylab=paste0(« Axe 2 (« , round(resultats$eig[2,2], 1), « %) »), main= »Nuage des individus », cex.main=1, cex.axis=0.8, cex.lab=0.8, font.lab=3)
> abline(h=0, v=0, col= »grey », lty=3, lwd=1)
> points(resultats$ind$coord[, 1:2], col = rgb(0, 0, 0, 0.1), pch = 19)

On remarquera que dans l’instruction points() de la dernière ligne ci-dessus, on a utilisé l’argument col=rgb() pour définir la couleur noire des points : le dernier paramètre à 0.1 nous permet de définir une forte transparence des points, ce qui fait qu’en cas de superposition, la nuance de gris obtenue par superposition donnera une idée du nombre de points superposés…

Nuage des individus

b. Habiller le nuage des individus en fonction du sexe

Si on veut habiller le nuage des individus en fonction du sexe, il suffit de colorer les points avec un vecteur numérique qui prend autant de valeurs qu’il y a de modalités à DONNEES$sexe :

> windows(7, 10)
> par(mfrow=c(1,1))
> plot(resultats$ind$coord[, 1:2], type= »n », xlab=paste0(« Axe 1 (« , round(resultats$eig[1,2], 1), « %) »), ylab=paste0(« Axe 2 (« , round(resultats$eig[2,2], 1), « %) »), main= »Nuage des individus selon le sexe », cex.main=1, cex.axis=0.8, cex.lab=0.8, font.lab=3)
> abline(h=0, v=0, col= »grey », lty=3, lwd=1)
> points(resultats$ind$coord[,1:2], col=as.numeric(DONNEES$sexe), pch=19)
> legend(« topright », legend=levels(DONNEES$sexe), bty= »o », text.col=1:2, col=1:2, pch=19, cex=0.8)

Nuage des individus habillé selon le sexe

Le résultat obtenu permet une identification complémentaire non seulement de la position des individus dans l’espace des loisirs en fonction du genre, mais également de la dispersion plus ou moins grande de chacun des genres dans cet espace. D’autres techniques peuvent évidemment servir à représenter ainsi la localisation et la dispersion, comme le traçage d’ellipses : on se reportera à ce sujet au tutoriel de Claire Lemercier déjà cité plus haut.

c. Pondérer le nuage des individus

Arrivés à ce point du tutoriel, vous savez l’essentiel de ce qu’il faut savoir à propos de l’élaboration avec R de représentations graphiques d’analyses des correspondances multiples. Vous pouvez parfaitement vous arrêter là ! Mais si vous voulez aller plus loin, vous pouvez poursuivre en explorant à la fois les possibilités graphiques presque illimitées offertes par R11, et en explorant également celles offertes par les capacités du logiciel en matière de manipulation des données et de calcul.

Si vous voulez un aperçu d’une utilisation un peu plus complexe de ces capacités, vous pouvez lire ce qui suit, mais c’est sans obligation… On essaie, pour finir ce tutoriel, de résoudre un problème posé par l’analyse du nuage des individus produit ci-dessus. On voit facilement sur les graphiques précédents que le nombre de points représentés est probablement inférieur à une centaine, soit beaucoup moins que les 2000 individus présents dans notre table de données. Cela est dû au fait qu’en raison du faible nombre de modalités actives, de nombreux individus possèdent exactement le même profil de loisirs, et donc occupent exactement la même position dans le plan factoriel. Leurs points, tracés par R les uns après les autres dans l’ordre de la base de données, se superposent donc, et il est impossible de savoir combien il y en a sur chaque position. En outre, sur le dernier graphique, celui du nuage des individus selon le sexe, la couleur des points correspond sur chaque position à la couleur du dernier point tracé par R, et donc rien ne garantit la fiabilité de l’analyse de la distribution des hommes et des femmes dans le premier plan factoriel qui serait faite à partir de ce graphique.

Pour résoudre ce problème, on va dans un premier temps construire un tableau ayant autant de lignes que de couples différents de coordonnées, et dont les colonnes comporteront les informations suivantes : abscisse, ordonnée, nombre d’hommes sur cette position, nombre de femmes sur cette position, nombre total d’individus sur cette position. On calculera enfin une dernière colonne, qui sera égale à 1 si le nombre d’hommes est supérieur au nombre de femmes sur cette position, et à 2 si c’est le contraire. Ce tableau est obtenu avec le script suivant :

> # Choisir la variable split
> split <- DONNEES$sexe
> # Calculer les tableaux du nombre d’invididus par position pour chaque modalité du split
> t <- by(resultats$ind$coord[, 1:2], split, table)
> # Transformer les tableaux en dataframes
> t <- lapply(t, as.data.frame, stringsAsFactors=FALSE)
> # Fusionner les tableaux dans un seul tableau avec autant de colonnes que de modalités de split, contenant le nombre d’individus par position pour chaque modalité du split
> tableau <- data.frame(list(Dim.1= » », Dim.2= » »))[-1,]
> for (i in 1:length(t)) {tableau <- merge(tableau, t[[i]], by=c(« Dim.1 », « Dim.2 »), suffixes=paste0(« . », (i-1):i), all=TRUE)}
> # Ajouter au tableau une variable size calculant le nombre total d’individus par position
> tableau$size <- apply(tableau[, -(1:2)], 1, sum, na.rm=TRUE)
> # Ne garder que les positions sur lesquelles le nombre d’individus est supérieur à 0
> tableau <- tableau[tableau$size>0, ]
> # Chercher ligne par ligne la modalité qui a le plus d’effectifs sur chaque position
> tableau$col <- apply(tableau[,3:(2+length(t))], 1, function(x){which(x==max(x, na.rm=TRUE))[1]})

On remarquera que ce petit script fonctionne pour n’importe quelle variable de notre base de données : il suffit d’en changer la première ligne pour ranger dans l’objet split la variable avec laquelle on veut « habiller » le nuage pondéré des positions individuelles. Ensuite, il ne reste plus qu’à tracer le graphique de la façon habituelle :

> windows(7, 10)
> par(mfrow=c(1,1))
> plot(tableau[, 1:2], type= »n », xlab=paste0(« Axe 1 (« , round(resultats$eig[1,2], 1), « %) »), ylab=paste0(« Axe 2 (« , round(resultats$eig[2,2], 1), « %) »), main= »Nuage pondéré des individus selon la CSP », cex.main=1, cex.axis=0.8, cex.lab=0.8, font.lab=3)
> abline(h=0, v=0, col= »grey », lty=3, lwd=1) # lignes horizontales et verticales
> # Représenter le nuage des individus
> points(tableau[, 1:2], pch=19, cex=1+tableau$size*10/max(tableau$size), col=tableau$col)
> legend(« topright », legend=levels(split), bty= »o », text.col=1:length(t), col=1:length(t), pch=20, pt.cex=1.5, inset=-0.01, y.intersp=0.7, cex=0.7)

Nuage des individus pondéré selon le sexe

Et voici le résultat pour le sexe, puis pour la catégorie socioprofessionnelle (qualif) :

plan-12-ind-qualifpondOn pourrait objecter qu’en choisissant les couleurs en fonction de simples différences d’effectifs, on « écrase » les catégories peu nombreuses. Les employés sont nombreux dans notre base de données, et c’est la raison pour laquelle ils sont si visibles sur le graphique ci-dessus, même si sur certaines positions qui leur sont ainsi attribuées, les ouvriers ou au contraire les cadres, moins nombreux, pourraient pourtant être plus nombreux qu’attendu (c’est-à-dire si ces positions dans l’espace des loisirs leur étaient attribuées au hasard). Il faut également être conscient du fait qu’un point de grande taille ne veut pas forcément dire que la modalité représentée soit corrélée à l’axe. Ainsi, la variable « sexe » n’est, comme l’indique le graphique des modalités supplémentaires, pas corrélée à l’axe 1 : les modalités « homme » et « femme » étant projetées très proches du barycentre. On peut d’ailleurs facilement corriger cela, par exemple en divisant les effectifs de chacun par l’effectif total de leur catégorie avant de voir qui est – cette fois proportionnellement à sa catégorie – le plus sur-représenté sur chaque position. Cela étant dit, notre façon très simple de faire ici permet de traduire une réalité sensible du monde social : elle montre qui, à chaque endroit ici de l’espace des loisirs, se sent majoritaire, entouré d’un grand nombre (en valeur absolue donc) d’individus socialement semblables : du côté du cinéma, ce seront indéniablement les cadres.

Conclusion

Pour terminer, il faut redire ce que tutoriel fait, et ce qu’il ne fait pas :

  • Ce qu’il fait : il peut vous aider assez utilement (nous espérons) à construire avec R des représentations graphiques d’analyses factorielles présentables, et visuellement efficaces pour explorer vos données et présenter les résultats de vos enquêtes. Ce faisant, il s’inscrit pleinement, il nous semble, dans la vocation de l’analyse factorielle, qui est justement de permettre au chercheur de s’appuyer sur l’imagination graphique pour rendre compte de façon condensée de la plus grande quantité d’information possible.
  • Ce qu’il ne fait pas : notre propos n’était ni d’expliquer les fondements mathématiques de l’analyse factorielle, ni de fournir une aide détaillée pour l’analyse et l’interprétation des résultats de vos analyses des correspondances multiples. Pour tout cela, encore une fois, nous vous renvoyons à la lecture par exemple des travaux de Philippe Cibois, et en particulier de ses Méthodes d’analyse d’enquêtes (2014), que nous venons de rééditer dans la Bibliothèque idéale des sciences sociales, et qui y sont en accès libre en texte intégral. Pour une aide détaillée à l’interprétation d’une analyse des correspondances multiples, vous pouvez également vous reporter à ce billet de Quanti : « Trideux (2) : Réaliser une analyse factorielle » (Cibois et Mercklé, 2008).

Même si le propos n’était pas de montrer comment analyser et interpréter une analyse des correspondances multiples sur des données réelles, mais de montrer comment la représenter graphiquement, cela ne nous empêche pas, pour conclure, de dire quand même un mot d’analyse de l’exemple que nous avons utilisé tout au long de ce tutoriel. Qu’aurait-il fallu dire des loisirs des Français, au vu de ces données extraites de l’enquête « Histoires de vie » réalisée par l’INSEE en 2003 ? Les quelques indications énumérées ci-dessous vous aideront peut-être pour lire vos propres ACM…

  • L’analyse des contributions des modalités actives montre que le premier facteur oppose dans l’ensemble les pratiquants aux non-pratiquants, ce qui permet de considérer que le premier axe qui structure l’espace des loisirs est celui de la participation, qui augmente quand on se déplace de la gauche vers la droite du premier plan factoriel.
  • Le deuxième facteur, représenté par l’axe des ordonnées du premier plan factoriel, oppose plutôt deux catégories de pratiques, avec d’un côté les pêcheurs et chasseurs (ces pratiquent expliquent plus de la moitié de l’inertie représentée sur l’axe vertical), qui sont aussi les bricoleurs, et de l’autre les amateurs de sport et de cinéma.
  • La projection des modalités supplémentaires et l’analyse du nuages des individus montre que le premier axe, celui de la participation culturelle, correspond très nettement à l’âge : celui-ci augmente quand on se déplace de la droite vers la gauche, et témoigne donc d’un retrait des plus âgés hors de l’espace des loisirs ; quant au second axe, il semble associé à une combinaison du sexe et du milieu social, avec les hommes et les classes populaire du côté de la chasse, la pêche et le bricolage, et les femmes et les cadres du côté du sport et du cinéma.

Et maintenant, à vous de jouer !…

Références bibliographiques

Barnier Julien, 2009, « R pour les sociologues : une introduction au fameux logiciel libre d’analyse des données », Quanti, mis en ligne le 26/01/2009, consulté le 28/03/2014, http://quanti.hypotheses.org/217/.

Barnier Julien, 2013, Introduction à R, Centre Max Weber, https://github.com/juba/intro-r/blob/master/intro.pdf.

Cibois Philippe, 1986, « L’analyse des correspondances : l’indispensable retour aux données », Histoire & Mesure, vol. 1, n° 3-4, pp. 239-247., http://www.persee.fr/web/revues/home/prescript/article/hism_0982-1783_1986_num_1_3_1540.

Cibois Philippe, 1997, « Les pièges de l’analyse des correspondances », Histoire & Mesure, 12 (3/4), pp. 299-320, http://perso.orange.fr/cibois/H&M.pdf.

Cibois Philippe, 2014, Les méthodes d’analyse d’enquête, Lyon, ENS Editions, coll. « Bibliothèque idéale des sciences sociales », préf. Pierre Mercklé, https://books.openedition.org/enseditions/1443.

Cibois Philippe et Mercklé Pierre, 2008, « Trideux (2) : Réaliser une analyse factorielle », Quanti, mis en ligne le 27/11/2008, consulté le 01/04/2014, http://quanti.hypotheses.org/146/.

Escoffier et Pagès, 2008, Analyses factorielles simples et multiples. Objectifs, méthodes et interprétation, PAris, Dunod.

Husson François, 2009, Analyse des données avec R, Rennes, Presses universitaires de Rennes.

Lê Sébastien, Josse Julie et Husson François, 2008, « FactoMineR: An R Package for Multivariate Analysis », Journal of Statistical Software, Volume 25, Issue 1, March, http://factominer.free.fr/docs/article_FactoMineR.pdf.

  1. Ce texte a bénéficié des relectures attentives des étudiants du séminaire « Méthode quantitatives en sciences sociales de l’ENS de Lyon », et en particulier de Salomé Fournet-Fayas, Margot de Groot van Emden, Marie Helluin, Lucie Jégat et Quentin Zimmermann. Il a bénéficié également des éclairages de Philippe Cibois, Baptiste Coulmont, Frédéric Lebaron et Claire Lemercier. Le script pour R qui l’accompagne a été corrigé dans le détail par Julien Barnier. []
  2. Pour cela, il faut lire le livre que la Bibliothèque idéale des sciences sociales (Bi2S) vient de rééditer, et qui est disponible en ligne en texte intégral : Cibois Philippe, 2014, Les méthodes d’analyse d’enquête, Lyon, ENS Editions (Bibliothèque idéale des sciences sociales), [en ligne] [URL : https://books.openedition.org/enseditions/1443]. Voir également l’ouvrage rédigé par les créateur du package FactoMineR : Husson et al., 2009, Analyse des données avec R, Rennes, PUR ; ainsi que Jérôme Escoffier et Brigitte Pagès, 2008, Analyses factorielles simples et multiples. Objectifs, méthodes et interprétation, Paris, Dunod. Les travaux de Brigitte Le Roux et Henry Rouanet ont aussi beaucoup contribué au développement et à la diffusion de la méthode, notamment dans sa dimension géométrique : 1993, Analyse des données multidimensionnelles. Statistique en science humaines, Paris, Dunod ; 2009, Multiple Correspondence Analysis, Los Angeles, Sage Publications (Quantitative Applications in the Social Sciences), n˚ 163 ; 2014, Analyse géométrique des données multidimensionnelles, Paris, Dunod. []
  3. Les utilisateurs avertis de R pourront également utiliser les fonctions créées par Joël Gombin, qui permettent de créer des graphs d’ACM selon la logique graphique du package ggplot2 : https://github.com/joelgombin/ggplot.acm. []
  4. Lê Sébastien, Josse Julie et Husson François, 2008, « FactoMineR: An R Package for Multivariate Analysis », Journal of Statistical Software, Volume 25, Issue 1, March, http://factominer.free.fr/docs/article_FactoMineR.pdf. []
  5. Si vous n’êtes pas familier avec le logiciel R, vous pouvez consulter ce tutoriel d’introduction, qui permet de comprendre rapidement comment installer R et réaliser les opérations les plus simples : Barnier Julien, 2009, « R pour les sociologues : une introduction au fameux logiciel libre d’analyse des données », Quanti, mis en ligne le 26/01/2009, consulté le 28/03/2014, http://quanti.hypotheses.org/217/. Pour des usages plus avancés, voir Barnier Julien, 2013, Introduction à R, Centre Max Weber, https://github.com/juba/intro-r/blob/master/intro.pdf. De manière générale, toute question trouve réponse sur les forums dédiés à R… Le charme des logiciels libres… []
  6. Entre autres avantages que nous n’avons pas la possibilité de détailler ici. Pour plus d’informations, et pour télécharger RStudio : https://www.rstudio.com. []
  7. Pour installer l’interface R-Commander, voir http://www.rcommander.com/. Pour utiliser FactoMineR avec R-Commander, voir le tutoriel de Claire Lemercier : http://www.quanti.ihmc.ens.fr/IMG/pdf/Tutoriel_FactomineR_ACM.pdf. []
  8. Sur les nombreuses fonctions du package questionr qui peuvent être très utiles pour les sociologues, voir à nouveau le manuel d’introduction à R de Julien Barnier : Barnier Julien, 2013, Introduction à R, Centre Max Weber, https://github.com/juba/intro-r/blob/master/intro.pdf. []
  9. Si les variables qu’on souhaite utiliser ne sont pas reconnues comme des facteurs par R, alors il faudra les « factoriser », en utilisant simplement la fonction factor(). []
  10. Pour voir les codes des différentes formes de points : http://www.endmemo.com/program/R/pchsymbols.php. []
  11. Pour une présentation plus détaillée des fonctions graphiques de R, voir par exemple le billet d’Arthur Charpentier, « La base des graphiques avec R » ; pour plus d’informations sur l’ajout d’éléments à un graphiques, voir http://www.duclert.org/Aide-memoire-R/Graphiques/Rajout-d-elements.php. []

Cartographier avec le logiciel R

Par Laurent Beauguitte1 et Timothée Giraud2

Ce n’est un secret pour personne, le logiciel R est devenu en quelques années l’un des logiciels de statistiques les plus performants qui soit3. Et les fonctions de cartographie de ce logiciel sont tout à fait capables de rivaliser avec les produits existant sur le marché, qu’ils soient gratuits mais non libres (Philcarto, disponible seulement sous environnement Windows) ou payants (Cartes & Données par exemple).

Mais pourquoi utiliser R et s’embêter à taper du code alors qu’il est si facile, avec ces logiciels, de cliquer à droite, à gauche ? Tout d’abord pour gagner du temps (mais si, mais si). Une fois les fonctions de base maîtrisées, il suffit de préparer des modèles de scripts où seuls les noms des fichiers en entrée (et les titres des cartes) devront être modifiés. Autre argument : R est multiplateforme… Enfin et surtout, en intégrant les fonctions de représentation cartographique à la suite des fonctions de statistiques on limite au maximum les ruptures logicielles (du type, je mets en forme mes données avec un tableur X, je fais mes traitements statistiques avec un logiciel de statistique Y, je retourne dans un tableur pour créer un fichier à cartographier, je cartographie avec un logiciel dédié Z puis je mets en page avec un logiciel de traitement de textes XYZ…). Un court script permettra par exemple, une fois les données importées, de cartographier les résultats de toutes sortes de traitements statistiques, des plus simples aux plus compliqués. Cet avantage est énorme dans un processus d’exploration de données où la carte peut jouer un rôle important dans le processus classique d’allers et de retours entre les traitements, les analyses et les interprétations.

Les modules de R (ou « packages » dans la terminologie du logiciel) permettant de créer des cartes sont nombreux (voir ci-dessous), et ce billet n’a pas la prétention de tous les présenter. Notre objectif est ici beaucoup plus modestement de présenter deux scripts, l’un permettant de créer une carte « choroplète »4, l’autre de créer une carte en « cercles proportionnels ». Nous avons essayé d’écrire des scripts qui soient simultanément concis et clairs. Mais ce ne sont bien entendu que des solutions possibles parmi d’autres.

Les formats

Le fond de carte que nous allons utiliser dans les deux cas est ce qu’on appelle un « shapefile ». Rappelons qu’un shapefile est formé de plusieurs fichiers différents portant tous le même nom. Un shapefile comprend au minimum trois fichiers :

  • un fichier à extension .shp stockant les géométries des entités ;
  • un fichier .bdf nommé  table attributaire ;
  • un fichier .shx stockant l’index de la géométrie des entités.

Il est utile (et recommandé) d’avoir un fichier .prj (lisible avec un éditeur de texte) qui précise le système de projection utilisé.

Si le format « shapefile » est propriétaire (ESRI), autrement dit il n’est pas libre, c’est toutefois le plus couramment utilisé, et tous les logiciels de SIG (système d’information géographique) open source savent le lire ; en outre, et les fonds de carte librement utilisables sont très nombreux en ligne (voir la rubrique ressources).

Quant au format des données elles-mêmes, il importe peu, même s’il est recommandé avec R d’employer les formats .csv ou .txt. De manière générale tout dataframe (importé ou créé dans R) contenant des données numériques et des identifiants pourra être cartographié.

Dans les deux exemples commentés ici, nous allons utiliser deux fichiers de départ :

  1. Un fond de carte de la Martinique provenant de l’IGN : http://professionnels.ign.fr/geofla%20%20professionnels.ign.fr/sites/default/files/GEOFLA_1-1_SHP_UTM20W84_MQ-ED111.tar.gz
  2. Un fichier de données démographiques issues du recensement de la population : http://www.recensement.insee.fr/telechargement/bases-chiffres-cles/BTX_CC_POP_2009.zip

Par ailleurs, nous avons regroupé dans une archive au format .zip tous les fichiers utiles pour vous permettre d’abord de reproduire les cartes détaillées ci-dessous, puis ensuite de réaliser les vôtres en vous inspirant de ces premiers exemples simples. Cette archive est disponible en cliquant sur le lien ci-dessous :

cartographier_avec_R.zip

Elle contient :

  • le fond de carte IGN des communes de la Martinique ;
  • l’extrait du recensement de la population 2009 ;
  • le script intitulé carto_choro.R, détaillé ci-dessous, permettant de réaliser des cartes choroplètes ;
  • le script intitulé carto_prop.R, détaillé ci-dessous, permettant de réaliser des cartes en cercles proportionnels.

Les packages utilisés

Nous utilisons trois packages : maptools, classInt et RcolorBrewer. Le premier est l’un  des modules les plus utiles en cartographie, le second permet de discrétiser des séries quantitatives continues, enfin  le troisième, qui n’est d’ailleurs pas indispensable, permet  de choisir des gammes de couleur.

Etapes, commandes et fonctions

Créer une carte avec R suppose :

  • d’importer les données (fond de carte – readShapeSpatial – et données – read.table) ;
  • de joindre les deux fichiers (merge) grâce à un identifiant commun ;
  • si besoin de discrétiser une variable (classIntervals) ;
  • si besoin, de choisir une gamme de couleurs (brewer.pal) ;
  • cartographier (plot) ;
  • de créer la légende (legend) ;
  • de mettre en page la carte (échelle – SpatialPolygonsRescale -, titre, auteur, source etc.).

Import des données

Le package maptools permet d’importer des objets spatiaux en fonction de leur type (polygone, ligne ou point) : readShapeSpatial, readLineSpatial et readPointSpatial. Même si le .shp comprend un fichier .prj (projection donc), il peut être nécessaire de préciser la projection utilisée – si on en a l’utilité, lors d’un changement de projection par exemple.

Si les deux fichiers comportent chacun une colonne identique (ce qui est nécessaire…) nommée respectivement c1 et c2, la fonction merge(fond_de_carte, données, by.x= »c1″, by.y= »c2″, all.x=TRUE) permettra de joindre les fichiers. La précision all.x=TRUE permet de conserver l’ensemble des données cartographiques, que des données autres y soient associées ou non (données manquantes par exemple).

Dans notre exemple, après avoir importé le jeu de données, nous créons une nouvelle variable représentant le taux d’accroissement de la population entre 1999 et 2009.

Le début du script sera donc :

#chargement des packages nécessaires
library(RColorBrewer)
library(maptools)
library(classInt)

#nettoyage de l’espace de travail / attention, cette commande effacera tous les #objets R créés dans la session courante!
rm(list=ls())

#fermeture de fenêtres graphiques éventuellement ouvertes
dev.off()

#definition du dossier de travail ou se trouvent les données et le fond de carte
setwd("Le_chemin_de_mon_dossier_de_travail")

#import des données à cartographier
dt <- read.csv( "data.csv",header=TRUE,sep=";",dec=",",skip=1)

#création de la variable VAR_POP du taux d’accroissement de la population
dt$VAR_POP <- (dt$P09_POP-dt$P99_POP) / dt$P99_POP

#import du fond de carte
fdc <- readShapeSpatial("COMMUNE")

#Jointure entre le fond de carte et les données
fdc@data <- merge(fdc@data,dt, by.x="INSEE_COM",by.y="CODGEO", all.x=TRUE)

Cartographie choroplète

Un script minimal possible est le suivant :

#discrétisation en 4 classes (quantiles)
distr <- classIntervals(fdc$VAR_POP,4,style="quantile")$brks

#choix d’une gamme de couleurs
#pour voir les palettes disponibles : display.brewer.all()
colours <- brewer.pal(4,"PuOr")

#optionnel - codes des couleurs utilisées
colours

#attribution des couleurs aux régions
colMap <- colours[(findInterval(fdc$VAR_POP,distr,all.inside=TRUE))]

#Affichage de la carte
plot(fdc, col=colMap)

#affichage de la légende
legend("bottomleft", legend=leglabs(distr),
fill=colours, bty="n",
title="Taux d’accroissement\ndémographique de 1999 à 2009")
#l’introduction de la chaine de caractère « \n » entraine un saut de ligne dans #le texte à afficher

#titre et sous titres
title(main="Evolution de la population en Martinique",
sub="auteur: Timothée Giraud, UMS RIATE, 2012\nSource: IGN (fond de carte GEOFLA), INSEE (Recensement de la population)")

Ce script donne le résultat suivant :

 

Le résultat affiché dans la fenêtre graphique est exportable aux formats .emf, .eps, .pdf, .png, .bmp, .tiff, .jpg à l’aide de la fonction savePlot(nom_du_fichier, type= »format »).

Avant d’enrichir ce script pour améliorer le résultat, un mot sur quelques fonctions utilisées ici… classIntervals permet de choisir la discrétisation de la variable cartographiée et plusieurs choix sont possibles, notamment fixed (bornes fixées par l’utilisateur), sd (moyenne et écart-type), equal (amplitude égale), quantile, kmeans, jenks et quelques autres encore. La fonction ne s’applique que sur des données de type numérique. La fonction legend comprend de très nombreux paramètres (position, cadre, couleur de fond, taille des caractères, titre etc.) et le plus simple est sans doute d’étudier les scripts d’exemples disponibles dans l’aide (taper ?legend dans la console).

Propositions d’amélioration

Trois défauts apparaissent en ce qui concerne la légende : trop de décimales, des termes en anglais et enfin, les bornes inférieures et supérieures sont inconnues. Plus de 0.11% certes mais quel est le maximum ?…

Les deux premiers inconvénients sont facilement supprimés avec les modifications suivantes :

legend("bottomleft", legend=round(leglabs(distr), over="Plus de",  under="Moins de"), fill=colours, bty="n",title="Taux d’accroissement\ndémographique de 1999 à 2009")

Obtenir l’affichage du minimum et du maximum est plus compliqué. Il serait bien sûr possible de récupérer les bornes (distr) puis de modifier la légende a posteriori… La solution proposée ici est la suivante : transformer la fonction existante leglabs pour modifier l’affichage des bornes et les arrondir. Traduire over et under devient alors superflu.

Cette fonction est la suivante :

#fonction de calcul des bornes pour la légende
myLeg <- function (vec, arrond) {
x <- vec
lx <- length(x)
if (lx < 3)
stop("pas suffisamment de classes")
res <- character(lx - 1)
res
for (i in 1:(lx - 1))
{res[i] <- paste(round(x[i],arrond), round(x[i + 1],arrond),sep=" - ")
}
res
}

Il suffira alors de remplacer dans l’instruction de création de légende legend=leglabs(distr) par legend=myLeg(distr,2)distr est la variable ou sont stocker les bornes de la distribution et 2 le nombre de chiffres après la virgule désiré à l’affichage. On obtient alors le script et le résultat suivants :

legend("bottomleft", legend=myLeg(distr,2),fill=colours, bty="n", title="Taux d’accroissement\ndémographique de 1999 à 2009")

Dernières étapes utiles : ajouter une échelle et une flèche nord. Dans les deux cas, le premier pas sera de choisir l’emplacement à l’aide de la fonction locator(n) où n est le nombre de points dont on souhaite obtenir les coordonées x,y.  Pour l’échelle, il faudra également indiquer la longueur désirée unités du fond de carte (mètres, kilomètres, degrés ?). Une solution possible est l’extrait de script suivant :

#affichage de l’échelle
l <- locator(n=1)   #cliquer dans la fenêtre graphique à l’endroit choisi
SpatialPolygonsRescale(layout.scale.bar(),offset=c(l$x,l$y),scale=5000,
fill=c("black"),plot.grid=F)
text(l$x+5000/2,l$y,paste("5 km","\n\n",sep=""))

#ajout d’une flèche nord
l <- locator(n=1)   #idem
SpatialPolygonsRescale(layout.north.arrow(2),offset=c(l$x,l$y),scale=5000,
plot.grid=F)

Dans le script téléchargeable nous utilisons le script décrit précédemment en raffinant un peu les fonctions d’affichage (taille et espacement du texte etc.). Et le résultat obtenu est le suivant :

Le script commenté intitulé carto_choro.R inclus dans le .zip téléchargeable  permet d’exécuter – et de personnaliser – chacune des étapes.

Il est encore possible d’améliorer ce script, notamment pour gérer l’affichage des données manquantes ou permettre d’inverser l’ordre d’affichage de la gamme de couleur utilisée.

Cartographie en cercles proportionnels

Cartographier une variable quantitative de stock suppose l’utilisation de la variable taille. Quatre problèmes doivent être résolus pour une cartographie avec R :

  • créer des colonnes x,y correspondant aux coordonnées des centroïdes des polygones ;
  • déterminer la taille maximale des cercles ;
  • éviter les superpositions et, quand elles sont inévitables (ex. Population par communes en Ile de France), veuillez à placer les cercles les plus petits devant les plus gros ;
  • et enfin, construire la légende.

Le problème de la discrétisation ne se pose plus (le package classInt est donc inutile ici), et les autres étapes du script (importation) sont à peu près identiques.

Les coordonnées des centroïdes s’obtiennent avec la fonction coordinates(fond_de_carte) qu’il suffit ensuite de transformer en tableau de données (dataframe). Le début du script sera donc le suivant :

#chargement des packages nécessaires
library(RColorBrewer)
library(maptools)

#nettoyage de l’espace de travail / attention, cette commande est à utiliser
#avec précaution, elle effacera tous les objets R créés dans la session
#courante!
rm(list=ls())

#Fermeture de fenêtres graphiques éventuellement ouvertes
dev.off()

#definition du dossier de travail ou se trouvent les données et le fond de carte
setwd("Le_chemin_de_mon_dossier_de_travail ")

#import des données à cartographier
dt <- read.csv( "data.csv",header=TRUE,sep=";",dec=",",skip=1)

#import du fond de carte
fdc <- readShapeSpatial("COMMUNE")

#création d’un dataframe avec les coordonnées des centroides des communes
pt <- cbind(fdc@data[,"INSEE_COM"],as.data.frame(coordinates(fdc)))

#renommage des colonnes de ce dataframe
colnames(pt) <- c("Code","x","y")

#jointure entre le dataframe des coordonnées des centroides et les données à #cartographier
pt <- merge(pt,dt, by.x="Code",by.y="CODGEO", all.x=TRUE)

Le dataframe pt contient maintenant les coordonnées des centroïdes des communes et les données associées. Les difficultés arrivent : nous voulons cartographier la population communale en 2009 en cercle proportionnels (variable P09_POP). La solution la plus fréquemment proposée est la suivante :

#Affichage de la carte
plot(fdc)
points(pt[,c("x","y")],cex=pt[,"P09_POP"]/5000,pch=21,bg="grey")

L’utilisation de la fonction d’affichage points() pose problème car la déclaration des tailles des cercles (cex=) sera en points de police de caractère. Alors que la représentation en figurés proportionnels suppose une conservation des rapports entre les valeurs de la variable et les surfaces des figurés les représentant sur la carte. L’utilisation de la fonction points() ne garantit absolument pas la conservation de ce rapport.

Par ailleurs, nous divisons les valeurs de la variable P09_POP par 5000 pour permettre l’affichage de cercles de taille raisonnable sur la carte. Mais représenter une autre variable quantitative de stock supposera un autre dénominateur qu’il n’est possible de trouver que par tatonnement.

La solution que nous proposons permet de surmonter ces deux problèmes : d’abord en utilisant une fonction d’affichage de cercles assurant une réelle proportionnalité des figurés ; ensuite en calibrant la surface totale des cercles par la surface totale de la carte (la surface totale des cercles représentera x% de la surface totale de la carte.)5

#extension maximale du fond de carte
#la fonction bbox donne les coordonnées max et min du fond de carte
x1 <- bbox(fdc)[1]
y1 <- bbox(fdc)[2]
x2 <- bbox(fdc)[3]
y2 <- bbox(fdc)[4]

#surface maximale de la carte
sfdc <- (x2-x1)*(y2-y1)

#somme de la variable à cartographier
sc <- sum(pt$P09_POP,na.rm=TRUE)

#création d’une variable contenant les rayons des cercles à représenter
pt$var <- sqrt((pt$P09_POP*0.1*sfdc/sc)/pi) #la somme des surfaces des cercles #représentera ici 10% (0.1) de la surface de la carte

#tri du dataframe de manière à ce que les cercles soient dessiner du plus gros #au plus petit
pt <- pt[order(pt$var,decreasing=TRUE),]

#Affichage de la carte
plot(fdc, border="Grey", col="#FEE08B")
symbols(pt[,c("x","y")],circles=pt$var,add=TRUE,bg="#C7E9C0",inches=FALSE)
#la fonction symbols() dessine des cercles d’un diamètre donné

Restera ensuite à dessiner une légende correspondant aux cercles dessinés :

#Affichage de la légende
rLeg <-  quantile(pt$var,c(1,0.9,0.25,0),type=1)
rVal <- quantile(pt$P09_POP,c(1,0.9,0.25,0),type=1)
l <- NULL
l$x <- x1
l$y <- y1
xinit <- l$x+rLeg[1]
ypos <- l$y+rLeg
symbols(x=rep(xinit,4),y=ypos,circles=rLeg,add=TRUE,bg="#C7E9C0",inches=FALSE)
text(x=rep(xinit,4)+rLeg[1]*1.2,y=(l$y+(2*rLeg)),rVal,cex=0.5,srt=0,adj=0)
for (i in 1:4){
segments (xinit,(l$y+(2*rLeg[i])),xinit+rLeg[1]*1.1,(l$y+(2*rLeg[i])))
}
text(x=xinit-rLeg[1],y=(l$y+(2*rLeg[1])),"Population communale
en 2009\n",adj=c(0,0),cex=0.6)

Puis à ajouter titre, sous-titres, échelle et flèche nord comme dans l’exemple de la carte choroplète ;

#titre et sous titres
title(main="Répartition de la population en Martinique",
sub="Auteur: Timothée Giraud, UMS RIATE, 2012\nSource: IGN (fond de carte GEOFLA), INSEE (Recensement de la population)",
cex.sub=0.7)

#affichage de l’échelle
l <- locator(n=1)   #cliquer dans la fenêtre graphique à l’endroit choisi
SpatialPolygonsRescale(layout.scale.bar(),offset=c(l$x,l$y),scale=5000,
fill=c("black"),plot.grid=F)
text(l$x+5000/2,l$y,paste("5 km","\n\n",sep=""))

#ajout d’une flèche nord
l <- locator(n=1)   #idem
SpatialPolygonsRescale(layout.north.arrow(2),offset=c(l$x,l$y),scale=5000,
plot.grid=F)

Il reste sans aucun doute du travail à faire en ce qui concerne la présentation de la légende et toutes les suggestions sont les bienvenues!

Pour conclure (provisoirement)

Nous ne prétendons évidemment pas que les solutions proposées ici sont les meilleures et les plus parcimonieuses qui soient. Notre objectif était autre : fournir clés en main deux exemples permettant d’apprivoiser la cartographie avec R.

N’hésitez surtout pas à nous faire part de vos commentaires, suggestions, remarques et critiques. Nous adorons progresser en R!

Autres packages utiles

La liste ci-dessous ne prétend pas à l’exhaustivité. Les packages sont classés par ordre alphabétique.

  • animation : représentations (carto)graphiques animées.
  • mapproj : conversion de coordonnées géographiques en coordonnées projetées.
  • maps : dessin des cartes vectorielles.
  • raster : manipulation des fichiers raster.
  • rgdal : importation de nombreux formats de données spatiales, raster et vectorielles.
  • rgeos : manipulation de la géométrie des objets.
  • rgrs : cartographies choroplètes et en figurés proportionnels.
  • sp : la base de tous les autres packages spatiaux, dans lequel sont définis les classes d’objets spatiaux.
  • spdep : analyse spatiale

Ressources en ligne

Tous ces sites ont été visités en août 2012.

Les ressources en français sont moins nombreuses mais signalons le blog FL\tauR comprenant plusieurs billets sur la cartographie (https://fltaur.wordpress.com/), le tutoriel de Julien Barnier (un chapitre sur la cartographie avec le package rgrs – http://alea.fr.eu.org/pages/intro-R), le blog de Baptiste Coulmont (http://coulmont.com/blog/).

En ce qui concerne les fichiers .shp disponibles en ligne, signalons notamment :

Lectures recommandées

Pour aller (beaucoup) plus loin, l’ouvrage de Bivand et al. est une mine d’or. Oui, il est cher et commence à dater… mais on trouve tous les scripts commentés à l’adresse http://www.asdar-book.org/.

Bivand, Roger S., Pebesma, Edzer J., Gómez-Rubio, Virgilio, 2008, Applied Spatial Data Analysis with R, Springer.

Une autre manière de faire des cercles proportionnels intégrant une discussion sur la perception des symboles proportionnels :

Tanimura, S., Kuroiwa, C., and Mizota, T. (2006) Proportional symbol mapping in R. Journal of Statistical Software 15(5). http://www.jstatsoft.org/v15/i05/paper

 

  1. UMR IDEES []
  2. UMS RIATE []
  3. Muenchen Robert A., The Popularity of Data Analysis Software: http://r4stats.com/articles/popularity/. []
  4. Une carte choroplète est une carte thématique composée par la juxtaposition d’aplats de couleurs. []
  5. D’autre solutions sont possibles, voir notamment celle de Tanimura et al. (2006) utilisant d’autres packages. []

L’analyse de séquences : une introduction avec le logiciel R et le package TraMineR

Par Nicolas Robette1

Depuis les années 1980, l’étude quantitative des trajectoires biographiques (life course analysis) a pris une ampleur considérable dans le champ des sciences sociales. Les collectes de données micro-individuelles longitudinales se sont développées, principalement sous la forme de panels ou d’enquêtes rétrospectives. Parallèlement à cette multiplication des données disponibles, la méthodologie statistique a connu de profondes évolutions. L’analyse des biographies (event history analysis) – qui ajoute une dimension diachronique aux modèles économétriques mainstream – s’est rapidement imposée comme l’approche dominante : il s’agit de modéliser la durée des situations ou le risque d’occurrence des événements.

L’analyse de séquences

Cependant, ces dernières années ont vu la diffusion d’un large corpus de méthodes descriptives d’analyse de séquences, au sein desquelles l’appariement optimal (optimal matching) occupe une place centrale2. L’objectif principal de ces méthodes est d’identifier – dans la diversité d’un corpus de séquences constituées de séries d’états successifs – les régularités, les ressemblances, puis le plus souvent de construire des typologies de « séquences-types ». L’analyse de séquences constitue donc un moyen de décrire mais aussi de mieux comprendre le déroulement de divers processus.

La majeure partie des applications de l’analyse de séquences traite de trajectoires biographiques ou de carrières professionnelles. Dans ces cas, chaque trajectoire ou chaque carrière est décrite par une séquence, autrement dit par une suite chronologiquement ordonnée de « moments » élémentaires, chaque moment correspondant à un « état » déterminé de la trajectoire (par exemple, pour les carrières professionnelles : être en emploi, au chômage ou en inactivité). Mais on peut bien sûr imaginer des types de séquences plus originaux : Andrew Abbott, le sociologue américain qui a introduit l’optimal matching dans les sciences sociales dans les années 1980, s’en est par exemple servi pour étudier la structure rhétorique d’articles scientifiques ou des séquences de pas de danses traditionnelles.

En France, les premiers travaux utilisant l’appariement optimal sont ceux de Claire Lemercier sur les carrières des membres des institutions consulaires parisiennes au XIXe siècle (Lemercier, 2005), et de Laurent Lesnard sur les emplois du temps (Lesnard, 2008). Mais dès les années 1980, les chercheurs du Céreq construisaient des typologies de trajectoires d’insertion à l’aide des méthodes d’analyse des données « à la française » (analyse des correspondances, etc.)3. Au final, on dénombre maintenant plus d’une centaine d’articles de sciences sociales contenant ou discutant des techniques empruntées à l’analyse de séquences.

Pour une présentation des différentes méthodes d’analyse de séquences disponibles et de leur mise en œuvre pratique, il existe un petit manuel en français, publié l’année dernière aux éditions du Ceped (collection « Les clefs pour ») et disponible en pdf (Robette, 2011). De plus, un article récemment publié dans le Bulletin de Méthodologie Sociologique compare de manière systématique les résultats obtenus par les principales méthodes d’analyse de séquences (Robette & Bry, 2012). La conclusion en est qu’avec des données empiriques aussi structurées que celles que l’on utilise en sciences sociales, l’approche est robuste, c’est-à-dire qu’un changement de méthode aura peu d’influence sur les principaux résultats. Cependant, l’article tente aussi de décrire les spécificités de chaque méthode et les différences marginales qu’elles font apparaître, afin de permettre aux chercheurs de mieux adapter leurs choix méthodologiques à leur question de recherche.

Afin d’illustrer la démarche de l’analyse de séquences, nous allons procéder ici à la description « pas à pas » d’un corpus de carrières professionnelles, issues de l’enquête Biographies et entourage (INED, 2000)4. Et pour ce faire, on va utiliser le logiciel R, qui propose la solution actuellement la plus complète et la plus puissante en matière d’analyse de séquences.. Les méthodes d’analyse de séquences par analyses factorielles ou de correspondances ne nécessitent pas de logiciel spécifique : tous les logiciels de statistiques généralistes peuvent être utilisés (SAS, SPSS, STATA, R, etc.). En revanche, il n’existe pas de fonctions pour l’appariement optimal dans SAS ou SPSS. Certains logiciels gratuits implémentent l’appariement optimal (comme Chesa ou TDA) mais il faut alors recourir à d’autres programmes pour dérouler l’ensemble de l’analyse (classification, représentation graphique). STATA propose le module « sq », qui dispose d’un éventail de fonctions intéressantes. Mais c’est R et le package « TraMineR », développé par des collègues de l’Université de Genève (Gabadinho et al, 2011), qui fournit la solution la plus complète et la plus puissante à ce jour : on y trouve l’appariement optimal mais aussi d’autres algorithmes alternatifs, ainsi que de nombreuses fonctions de description des séquences et de représentation graphique. Le fait que R fonctionne avec un langage de programmation peut sembler dissuasif a priori, mais il existe des tutoriels très pédagogiques (voir notamment le billet de Julien Barnier sur ce même blog) et au final, quelques lignes de codes permettent de réaliser une analyse de séquences de sa première à sa dernière étape, d’en modifier les « réglages » et de recommencer presque instantanément, ce qui fait gagner beaucoup de temps. C’est ce que tente d’illustrer l’exemple qui suit.

 

Installer « TraMineR » et récupérer les données

Tout d’abord, à quoi ressemblent nos données ? On a reconstruit à partir de l’enquête les carrières de 1000 hommes. Pour chacune, on connaît la position professionnelle chaque année, de l’âge de 14 ans jusqu’à 50 ans. Cette position est codée de la manière suivante : les codes 1 à 6 correspondent aux groupes socioprofessionnels de la nomenclature des PCS de l’INSEE (agriculteurs exploitants ; artisans, commerçants et chefs d’entreprise ; cadres et professions intellectuelles supérieures ; professions intermédiaires ;  employés ; ouvriers) ; on y a ajouté « études » (code 7), « inactivité » (code 8) et « service militaire » (code 9). Le fichier de données comporte une ligne par individu et une colonne par année : la variable 1 correspond à la position à 14 ans, la variable 2 à la position à 15 ans, etc. Par ailleurs, les enquêtés étant tous nés entre 1930 et 1950, on ajoute à notre base une variable « génération » à trois modalités, prenant les valeurs suivantes : 1=1930-1938 ; 2=1939-1945 ; 3=1946-1950. Au final, la base est constituée de 500 lignes et de 37+1=38 colonnes et se présente sous la forme d’un fichier texte au format .csv (téléchargeable ici).

Une fois R ouvert, on commence par installer les bibliothèques de fonctions (packages) nécessaires à ce programme (opération à ne réaliser que lors de leur première utilisation) et par les charger en mémoire5. Le package « TraMineR » propose de nombreuses fonctions pour l’analyse de séquences. Le package « cluster » comprend un certain nombre de méthodes de classification automatique.

> install.packages(c('TraMineR'))
> library(TraMineR)
> library(cluster)

On met en mémoire les paramètres graphiques par défaut :

> par.def <- par()

On importe ensuite les données, on recode la variable « génération » pour lui donner des labels plus explicites et on jette un coup d’œil à la structure du tableau de données :

> donnees<-read.csv("http://nicolas.robette.free.fr/Docs/trajpro.csv",header=T)
> donnees$generation <- factor(donnees$generation,labels=c('1930-38', '1939-45', '1946-50'))
> str(donnees)

On a bien 1000 observations et 38 variables. On définit maintenant des labels pour les différents états qui composent les séquences et on crée un objet « séquence » :

> labels <- c("agric","acce","cadr","pint","empl","ouvr","etud","inact","smil")
> seq <- seqdef(donnees[,1:37], states=labels)

Ces étapes préalables achevées, on peut comparer les séquences en calculant les dissimilarités entre paires de séquences. On va ici utiliser la méthode la plus répandue, l’appariement optimal (optimal matching). Cette méthode consiste, pour chaque paire de séquences, à compter le nombre minimal de modifications (substitutions, suppressions, insertions) qu’il faut faire subir à l’une des séquences pour obtenir l’autre. On peut considérer que chaque modification est équivalente, mais il est aussi possible de prendre en compte le fait que les « distances » entre les différents états n’ont pas toutes la même « valeur » (par exemple, la distance sociale entre emploi à temps plein et chômage est plus grande qu’entre emploi à temps plein et emploi à temps partiel), en assignant aux différentes modifications des « coûts » distincts. Dans notre exemple, on va créer une « matrice des coûts de substitution » dans laquelle tous les coûts sont constants et égaux à 26 :

> couts <- seqsubm(seq,method="CONSTANT", cval=2)

Ensuite, on calcule la matrice de distance entre les séquences (i.e contenant les « dissimilarités » entre les séquences), avec un coût d’insertion/suppression (indel)  que l’on fixe ici à 1.1 :

> seq.om <- seqdist(seq, method="OM", indel=1.1, sm=couts)

Cette matrice des distances ou des dissimilarités entre séquences peut ensuite être utilisée pour une classification ascendante hiérarchique (CAH), qui permet de regrouper les séquences en un certain nombre de « classes » en fonction de leur proximité :

> seq.agnes <- agnes(as.dist(seq.om), method="ward", keep.diss=FALSE)

Avec la fonction plot, il est possible de tracer l’arbre de la classification (dendrogramme) :

> par(par.def)

> plot(as.dendrogram(seq.agnes), leaflab= »none »

L’observation, sur ce dendogramme ou sur la courbe des sauts d’inertie présentée ci-dessous, des sauts d’inertie des dernières étapes de la classification peut servir de guide pour déterminer le nombre de classes que l’on va retenir pour la suite des analyses :

> par(par.def)
> plot(sort(seq.agnes$height, decreasing=TRUE)[1:20], type=‘s’, xlab="nb de classes", ylab="inertie")

Une première inflexion dans la courbe des sauts d’inertie apparaît au niveau d’une partition en 5 classes (indiquée en rouge sur les deux graphiques précédents). On voit aussi une seconde inflexion assez nette à 7 classes (indiquée en vert). Mais il faut garder en tête le fait que ces outils ne sont que des guides, le choix devant avant tout se faire après différents essais, en fonction de l’intérêt des résultats par rapport à la question de recherche et en arbitrant entre exhaustivité et parcimonie.

On fait ici le choix d’une partition en 5 classes :

> nbcl <- 5
> seq.part <- cutree(seq.agnes, nbcl)
> seq.part <- factor(seq.part,labels=paste('classe',1:nbcl,sep='.'))

Pour se faire une première idée de la nature des classes de la typologie, il existe un certain nombre de représentations graphiques. Les chronogrammes (state distribution plots) présentent une série de coupes transversales : pour chaque âge, on a les proportions d’individus de la classe dans les différentes situations (agriculteur, étudiant, etc.).

> seqdplot(seq, group=seq.part, xtlab=14:50, border=NA, withlegend=T)

Chacune des classes semble caractérisée par un groupe professionnel principal : profession intermédiaire pour la classe 1, ouvrier pour la 2, employé pour la 3, cadre pour la 4 et indépendant pour la 5. Cependant, on aperçoit aussi des « couches » d’autres couleurs, indiquant que l’ensemble des carrières ne sont probablement pas stables.

Les « tapis » (index plots) permettent de mieux visualiser la dimension individuelle des séquences. Chaque segment horizontal représente une séquence, découpée en sous-segments correspondant aux aux différents états successifs qui composent la séquence.

> seqiplot(seq, group=seq.part, xtlab=14:50, tlim=0, space=0, border=NA, withlegend=T, yaxis=FALSE)

Il est possible de trier les séquences pour rendre les tapis plus lisibles (on trie ici par multidimensional scaling) :

> ordre <- cmdscale(as.dist(seq.om),k=1)
> seqiplot(seq, group=seq.part, sortv=ordre, xtlab=14:50, tlim=0, space=0, border=NA, withlegend=T, yaxis=FALSE)

On voit mieux apparaître ainsi l’hétérogénéité de certaines classes. Les classes 1, 3 et 4, par exemple, semblent regrouper des carrières relativement stables (respectivement de professions intermédiaires, d’employés et de cadres) et des carrières plus « mobiles » commencées comme ouvrier (classes 1 et 3, en orange) ou comme profession intermédiaire (classe 4, en rouge). De même, la majorité des membres de la dernière classe commencent leur carrière dans un groupe professionnel distinct de celui qu’ils occuperont par la suite (indépendants). Ces distinctions apparaissent d’ailleurs si on relance le programme avec un nombre plus élevé de classes (en remplaçant le « 5 » de la ligne « nbcl <- 5 » par « 7 », seconde inflexion de la courbe des sauts d’inertie, et en exécutant de nouveau le programme à partir de cette ligne) : les stables et les mobiles se trouvent alors dans des classes distinctes.

La distance moyenne des séquences d’une classe au centre de cette classe permet de mesurer plus précisément l’homogénéité des classes :

> round(aggregate(disscenter(as.dist(seq.om), group=seq.part), list(seq.part),mean)[,-1],1)
13.1  8.9  15.6  9.7  16.5

Cela nous confirme que les classes 1, 3 et 5 sont nettement plus hétérogènes que les autres, alors qua la classe 2 est la plus homogène.

D’autres représentations graphiques existent pour poursuivre l’examen de la typologie. On peut visualiser les 10 séquences les plus fréquentes de chaque classe :

> seqfplot(seq, group=seq.part, withlegend=T)

On peut aussi visualiser l’état modal (celui qui correspond au plus grand nombre de séquences de la classe) à chaque âge :

> seqmsplot(seq, group=seq.part, xtlab=14:50, withlegend=T, title="classe")

On peut également représenter les durées moyennes passées dans les différents états :

> seqmtplot(seq, group=seq.part, withlegend=T)

Enfin, l’entropie transversale décrit l’évolution de l’homogénéité de la classe. Pour un âge donné, une entropie proche de 0 signifie que tous les individus de la classe (ou presque) sont dans la même situation. A l’inverse, l’entropie est de 1 si les individus sont dispersés dans toutes les situations. Ce type de graphique peut être pratique pour localiser les moments de transition, l’insertion professionnelle ou une mobilité sociale ascendante, par exemple :

> seqHtplot(seq, group=seq.part, xtlab=14:50, withlegend=T)

On souhaite maintenant connaître la distribution de la typologie (en effectifs et en pourcentages) :

> distri.eff <- table(seq.part)
> distri.eff
> round(distri.eff/sum(distri.eff)*100,1)
seq.part

classe.1 classe.2 classe.3 classe.4 classe.5

     280      199      114      341       66

seq.part

classe.1 classe.2 classe.3 classe.4 classe.5

    28.0     19.9     11.4     34.1      6.6

On poursuit ensuite la description des classes en croisant la typologie avec la variable « generation » :

> round(100*prop.table(table(seq.part,donnees$generation),2),1)
> chisq.test(table(seq.part,donnees$generation))
seq.part   1930-38 1939-45 1946-50
  classe.1    25.6    27.1    31.0
  classe.2    20.9    20.0    18.9
  classe.3     7.9    13.6    12.9
  classe.4    38.2    31.9    32.1
  classe.5     7.4     7.5     5.2
     Pearson’s Chi-squared test
data:  table(seq.part, donnees$generation[1:1000])
X-squared = 12.0319, df = 8, p-value = 0.1498

Le lien entre le fait d’avoir un certain type de carrières et la cohorte de naissance est significatif à un seuil de 15%. On constate par exemple l’augmentation continue de la proportion de carrières de type « professions intermédiaires » (classe 1) et, entre les deux cohortes les plus anciennes, l’augmentation de la part des carrières de type « employés » (classe 3) et la baisse de la part des carrières de type « cadres » (classe 4).

Bien d’autres analyses sont envisageables : croiser la typologie avec d’autres variables (origine sociale, etc.), construire l’espace des carrières possibles, étudier les interactions entre trajectoires familiales et professionnelles, analyser la variance des dissimilarités entre séquences en fonction de plusieurs variables « explicatives »7 … Mais l’exemple proposé est sans doute bien suffisant pour une première introduction !

Bibliographie

Abbott A., 2001, Time matters. On theory and method, The University of Chicago Press.

Abbott A., Hrycak A., 1990, « Measuring ressemblance in sequence data : an optimal matching analysis of musicians’ careers », American journal of sociology, (96), p.144-185. sur jstor

Abbott A., Tsay A., 2000, « Sequence analysis and optimal matching methods in sociology: Review and prospect », Sociological methods & research, 29(1), p.3-33. sur Sage

Gabadinho, A., Ritschard, G., Müller, N.S. & Studer, M., 2011, « Analyzing and visualizing state sequences in R with TraMineR », Journal of Statistical Software, 40(4), p.1-37. lien

Grelet Y., 2002, « Des typologies de parcours. Méthodes et usages », Document Génération 92, (20), 47 p. lien

Lelièvre É., Vivier G., 2001, « Évaluation d’une collecte à la croisée du quantitatif et du qualitatif : l’enquête Biographies et entourage », Population, (6), p.1043-1073. sur Persée

Lemercier C., 2005, « Les carrières des membres des institutions consulaires parisiennes au XIXe siècle », Histoire et mesure, XX (1-2), p.59-95. sur revues.org

Lesnard L., 2008, « Off-Scheduling within Dual-Earner Couples: An Unequal and Negative Externality for Family Time », American Journal of Sociology, 114(2), p.447-490. lien

Lesnard L., Saint Pol T. (de), 2006, « Introduction aux Méthodes d’Appariement Optimal (Optimal Matching Analysis) » Bulletin de Méthodologie Sociologique, 90, p.5-25. sur revues.org

Robette N., 2011, Explorer et décrire les parcours de vie: les typologies de trajectoires, CEPED (Les Clefs pour), 86 p. lien

Robette N., 2012, « Du prosélytisme à la sécularisation. Le processus de diffusion de l’Optimal Matching Analysis », document de travail. lien

Robette N., Bry X., 2012, « Harpoon or bait? A comparison of various metrics to fish for life course patterns », Bulletin de Méthodologie Sociologique, 116, p.5-24. sur Sage (draft disponible ici)

Robette N., Thibault N., 2008, « L’analyse exploratoire de trajectoires professionnelles: analyse harmonique qualitative ou appariement optimal? », Population-F, 64(3), p.621-646. sur Cairn

Savage M., 2009, « Contemporary Sociology and the Challenge of Descriptive Assemblage », European Journal of Social Theory, 12(1), p.155-174. sur Sage

 

  1. Maître de conférences à l’Université de Versailles Saint-Quentin-en-Yvelines. Adresse électronique : nicolas.robette[arobase]uvsq.fr. []
  2. Pour une analyse des conditions sociales de la diffusion de l’analyse de séquences dans le champ des sciences sociales, voir Robette, 2012. []
  3. Voir par exemple l’article d’Yvette Grelet (2002). []
  4. Pour une analyse plus poussée de ces données, avec deux méthodes différentes, voir Robette & Thibault, 2008. Pour une présentation de l’enquête, voir Lelièvre & Vivier, 2001. []
  5. Le programme R avec lensemble des lignes de code présentées dans cet exemple est disponible ici. []
  6. le fonctionnement de l’algorithme d’appariement optimal – et notamment le choix des coûts – est décrit dans le chapitre 3 du manuel. []
  7. L’articulation entre méthodes « descriptives » et méthodes « explicatives » est un prolongement possible de l’analyse de séquences, ce que j’avais d’ailleurs écrit dans la conclusion du manuel. Cependant, l’analyse de séquences était envisagée par Abbott comme une alternative à la sociologie quantitative mainstream, i.e le « paradigme des variables » et ses hypothèses implicites souvent difficilement tenables (Abbott, 2001), et je souscris maintenant totalement au fait qu’une bonne description solidement fondée théoriquement vaut bien des « modèles explicatifs » (Savage, 2009). []

Spatial analysis, un blog (anglophone) sur l’analyse spatiale

Spatial Analysis est un blog en anglais édité par James Cheshire, un doctorant au Centre for Advanced Spatial Analysis de l’University College de Londres :

http://spatialanalysis.co.uk/

Le blog contient une série de billets très accessibles sur les représentations cartographiques et l’analyse spatiale. Parmi les billets intéressants on pourra noter :

Une partie du blog s’intéresse plus particulièrement à la cartographie avec le logiciel R :

Le site fait partie des blogs référencés sur l’aggrégateur R-bloggers, très utile pour suivre l’actualité de ce langage libre de manipulation et d’analyse de données.

Flowing Data, un blog en anglais consacré aux statistiques et à leur visualisation

Je viens de découvrir (enfin, pas tout seul, merci à Emma Bester) le blog de Nathan Yau, intitulé « Flowing Data« . Il est consacré aux statistiques et à leur visualisation, et présente des outils, des développements et des innovations dans ces domaines. C’est une excellente façon de découvrir les travaux des statisticiens, des programmeurs, des infographes anglo-saxons dans le domaine de l’analyse et de la représentation des données quantitatives.

Pour preuve, ce billet récent consacré à une façon originale de représenter les frises chronologiques non pas de façon linéaire, mais… circulaire !

Ce graphique est le résultat du travail de Rachel Mercer, et vous pouvez le découvrir plus en détail sur son site, à l’adresse suivante : http://portfolio.rachelmercer.org/projects/2666196

Ce n’est évidemment qu’un exemple parmi d’autres de tout ce que vous pourrez découvrir sur le blog de Nathan Yau… le reste, c’est ici : http://flowingdata.com

Bonne lecture !

R pour les sociologues : une introduction au fameux logiciel libre d’analyse des données

Pendant longtemps, les sociologues désireux de mettre en oeuvre des outils quantitatifs d’analyse des données avaient le choix entre des outils simples et conviviaux (comme Sphinx ou Modalisa), mais peu puissants, et des outils puissants (comme SAS, SPSS, etc.), mais complexes à mettre en oeuvre, et… payants. Et puis est arrivé… R ! Son nom est bizarre, il appartient plutôt à la seconde catégorie, mais… il est gratuit ! R est en effet issu du monde des logiciels libres, et c’est une très bonne raison de l’adopter. L’autre très bonne raison, c’est sa puissance impressionnante, et son évolutivité : vous verrez, à l’usage, que R n’a rien à envier à SAS ou SPSS. QUANTI a donc choisi d’en faciliter l’accès à toutes celles et tous ceux qui veulent utiliser des méthodes quantitatives en sciences sociales, en publiant ici le « mode d’emploi » de R écrit par Julien Barnier à destination des sociologues.

Lire la suite

Ce que dit un graphique et ce qu’on en dit

Je regardais hier soir d’un oeil un peu distrait le journal télévisé de David Pujadas sur France 2, quand une image fugace, à peine entrevue déjà disparue, a attrapé mon regard, presque contre mon gré : un graphique avait présenté, pendant 13 secondes, la diminution spectaculaire des taux directeurs de la Banque centrale européenne qui venait d’être annoncée. Et ce fut trop rapide pour que je puisse immédiatement comprendre ce qui n’allait pas, mais pas assez cependant pour ne pas s’en apercevoir : quelque chose clochait dans ce graphique… L’objectif de ce carnet est bien de mettre en valeur les façons de « bien » utiliser les méthodes quantitatives en sciences sociales, mais de temps en temps, quand l’occasion s’en présente, on peut y arriver aussi en pointant quelques façons de « mal » les utiliser : essayons donc de comprendre ce qui cloche ici…

Lire la suite