La semaine dernière on a vu qu’il y a deux types de variable. Les variables qualitatives comme les questions à choix unique ou les échelles de likert et les variables quantitatives qui dénombrent ou mesurent. Aujourd’hui on va voir les principes les plus importants à respecter ou à rechercher lorsque l’on fait un graphique puis, en détail comment représenter des données avec R.

Deux types de représentation

Il existe deux situations de production de graphiques très différentes: lors de l’analyse des données et lors de leur publication.

Lorsque l’on fouille les données on produit des graphiques et des représentations. Dans cette situation les graphiques ne sont pas produits pour être comuniqués mais seulement pour être consultés de façon informelle. Dans ce cas il y a peu d’exigence de forme, il reste des exigences de fidélité aux données et de rigueur. Dans cette situation on s’autorise des représentations complexes et récentes : tout est permis. Souvent ces représentations sont difficiles à lire. Il faut garder à l’esprit que les publier nécéssitera un travail conséquent d’explication autour de la représentation.

La deuxième situation est de représenter des données pour présenter des résultats, ou communiquer des informations. Dans ce cas on fait le plus souvent appel à des graphiques simples, lisibles facilement. En outre, pour favoriser la compréhension de la représentation il y a un certain nombre d’éléments éditoriaux qui doivent figurer sur chaque illustration :

Les erreures à éviter

Les questions d’échelles sont cruciales1. Deux graphiques peuvent par exemple représenter différement les mêmes données, voici un exemple avec deux diagrammes en barres présentant des données sur le prix de l’immobilier au Royaume-Unis :

La même chose avec un nuage de points et la température corporelle humaine :

Poussée à l’absurde voici une représentation des données sur les risques d’attaques d’ursidés :

Le problème des camemberts

Les représentations en camembert sont à utiliser avec modération c’est à dire uniquement lorsqu’il y a peu de modalités à représenter. Le problème vient du fait que les proportions ne sont pas très visibles avec des camemberts. Le graphique ci-dessous montre sur la première ligne des données représentées en camembert et sur la deuxième ligne une représentation en diagramme barres pour les mêmes données.

On voit assez bien les différences entre A, B et C avec les diagrammes en barres et pas vraiment avec les camemberts.

Les représentations matricielles

Dans les années 60 un géographe nommé Jacques Bertin a élaboré une théorie de la représentation des données, nommée Sémiologie graphique, qui est devenue extrémement importante et utile pour représenter des données. On en trouvera une présentation ici : https://visionscarto.net/la-semiologie-graphique-a-50-ans ou là : http://www.persee.fr/doc/colan_0336-1500_1975_num_28_1_4248.

Un des éléments clé assez peu employé c’est de représenter des graphiques en tableau. Dans un exemple issu de l’article Théorie matricielle de la graphique, Jacques Bertin illustre comment représenter les données figurant dans le tableau ci-dessous qui recensent les proportions de production de viandes dans 4 “pays” d’Europe en 1966 :

Il est très fréquent que ce soient les camemberts qui soient convoqués pour représenter ces données et cela va donner le graphique suivant :

Les camemberts ne montrent que des informations élémentaires : la France est le pays qui produit le plus de viande à l’exception du porc qui est plus produit par l’Allemagne. “On y voit par exemple que 69 % des ovins sont en France, ou encore que la France produit plus que la Belgique! Etait-il besoin de faire un dessin pour savoir que la France est plus grande que la Belgique ?” (p.65). En réalisant une représentation matricielle, c’est à dire un tableau de graphiques, comme sur l’illustration ci-dessous on va voir plus de choses :

“La construction [ci-dessus] par contre fait apparaître le contenu réel du tableau des données, et il est d’importance : l’Allemagne et les Pays-Bas ont la même structure de production fondée sur le porc et le bœuf. Ces deux pays forment donc un groupe (4), opposé à un autre groupe, celui de la France et de l’Italie, caractérisé par une structure inverse (6). Enfin la structure de production de l’Union Belgo-Luxembourgeoise (5) est différente des deux précédentes.” (p. 65)

On voit assez bien ici l’importance que peut avoir une représentaiton de données travaillée et soignée : une production de sens dans des données inintéligibles.

Les représentations classiques

Du point de vue pratique les choses sont plus dificilles à mettre en oeuvre. Voici une liste qui recense les représentations les plus simples et les plus habituelles :

Type de variables Représentations intitulé dans R
1 variable qualitative Diagramme en barres, Camembert barplot, pie
1 variable quantitative Boite à moustahces boxplot
2 variables quantitatives nuage de points plot
2 variables qualitatives diagramme en barres ou en mosaïque barplot, mosaic plot
1 quantitative et 1 qualitative Série de boite à moustaches, Diagramme en barres boxplot, barplot

Nous allons voir comment réaliser chacune de ces représentations dans R avec les données du questionnaire telles qu’elles se présentaient le 15 décembre avec 68 réponses au total.

Export et import des données dans R

Depuis limesurvey il y a deux fichiers à récuperer. Le premier contient le fichier de syntaxe (les questions) et le second les réponses au questionnaire au format csv. Pour les obtenir après être allé dans “réponses et statistiques” cliquer sur l’icône R :

Une fois que ces deux fichiers sont téléchargés il faut les mettre dans le dossier de travail de R (utilisez getwd() dans la console de commande de R pour savoir quel est ce repertoire). Une fois que les deux fichiers se trouvent dans le repertoire de travail de R executez la commande suivante :

source("survey_78242_R_syntax_file.R", encoding = "UTF-8")

Les données figurent maintenant dans l’objet “data”. L’objet data est un grand tableau dans lequel figurent en colonne les variables et en ligne les réponses. Pour vous en convaincre vous pouvez executer la commande : View(data) qui, dans R, va ouvrir un petit tableur dans un nouvel onglet.

Dans R on peut avoir un résumé de ce grand tableau grâce à la fonction summary()2.

summary(data)

Voici un extrait de quelque chose qui ressemble à ce que doit renvoyer R :

##    Q1_SQ001           Q1_SQ002           Q1_SQ003        
##  Length:68          Length:68          Length:68         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##    Q1_SQ004              Q2                            Q3_SQ001 
##  Length:68          Length:68          OUI                 :21  
##  Class :character   Class :character   NON                 :22  
##  Mode  :character   Mode  :character   Je ne le connais pas:18  
##                                        NA's                : 7  
##                  Q3_SQ002                  Q3_SQ003 
##  OUI                 :43   OUI                 :31  
##  NON                 :14   NON                 :27  
##  Je ne le connais pas: 4   Je ne le connais pas: 2  
##  NA's                : 7   NA's                : 8  
##                  Q3_SQ004                  Q3_SQ005 
##  OUI                 :20   OUI                 :59  
##  NON                 :16   NON                 : 4  
##  Je ne le connais pas:20   Je ne le connais pas: 1  
##  NA's                :12   NA's                : 4  
##                  Q3_SQ006 
##  OUI                 :34  
##  NON                 :27  
##  Je ne le connais pas: 0  
##  NA's                : 7

Ce que l’on voit ici c’est une synthèse de chaque colonne du grand tableau (les réponses aux questions). Les questions ne sont pas indiquées, seulement les codes des questions qui ont été saisis dans limesurvey lors de la conception du questionnaire : Q1, Q2… Comme chaque question peut être constituée de plusieurs variables, limesurvey a ajouté des éléments pour les distinguer SQ001, SQ002

Par la commande summary() on a donc accès à des tris à plats. Une autre commande utile est str() qui va indiquer la nature (character pour question ouverte, numeric pour variable quantitative, factor pour variable qualitative) de chaque colonne et les premières valeurs.

Les différents types de variable pour R

Si pour nous qui avons fait le questionnaire la nature des questions est claire (qualitative, quantitative ou ouverte) pour une machine les choses le sont moins. Un logiciel ne connaît pas ces différences mais distingue les lettres des nombres et les modalités à choix unique. En revanche il ne distingue pas les cas particuliers et se trompe assez souvent. Dans notre cas limesurvey a fait en sorte que chaque variable soit identifiée par R de la même façon que par limesurvey c’est à dire tel que défini lors de la saisit des questions.

Les questions ouvertes : class character

La première question du questionnaire (qui a été codée Q1) était “[] Ecrivez 4 mots clés qui vous viennent à l’esprit à propos d’un réseau social sur internet.” limesurvey a distingué chacun des 4 champs à remplir par SQ_001, SQ_002

Avec la commande summary(data) la première question du questionnaire s’affiche ainsi :

Q1_SQ001
length: 68
Class : character
Mode : character

Ceci signifie que R recconnaît que la première réponse (SQ_001) à la question codée Q1, a 68 réponses et est composé de texte (character), c’est à dire une question ouverte.

Les variables qualitatives : class factor

La troisième question du questionnaire portait sur les “skyblog” : “[Skyblog] Pensez-vous que les sites suivants sont des réseaux sociaux ?”

Q3_SQ001
OUI : 21
NON : 22
Je ne le connais pas : 18
NA’S : 7

On voit que la question Q3 est recconnue par R comme une variable à choix unique pour laquelle il y a 21 réponses à la modalité “OUI”, 22 à “NON”, 18 pour “Je ne le connais pas” et 7 non-réponses indiquées par “NA” (qui signifie “Non Available”). Dans R les variables qualitatives sont nommées : factor

Les variables quantitatives : class numeric

La question sur l’âge était intitulée ainsi : “Quel âge avez-vous ?” Il s’agit de la 89ème variable dans notre base et figure à la fin. Elle avait été codée : “q_2” et s’affiche ainsi dans le résumé :

q_2 Min. : 12.00 1st Qu. : 24.75 Median :32.00 Mean :34.65 3rd Qu.:42.25 Max. :99.00 NA’s :8

Il s’agit d’une variable quantitative pour laquelle R renvoie le minimum (Min.), le premier quartile (1st Qu.), la médiane (Median), la moyenne (Mean), le troisième quartile (3rd Qu.), le maximum (Max.) et le nombre de non-réponses (NA). Dans R les variables quantitatives sont de type numeric (il existe deux autres types dont on ne parlera pas).

Afficher les intitulés des questions

Le codage des questions ne facilite pas leur lecture, il est préférable de coder les questions avec un texte signifiant. Par exemple “genre” pour la question “Quel est votre genre ?” ou “age” pour “Quel est votre âge ?”. Pour ratrapper un peu, on peut appeller les intitulés des questions grâce à la commande suivante un peu compliquée : attributes(data)$variable.labels.

##  [1] "[] Ecrivez 4 mots clés qui vous viennent à l'esprit à propos d'un réseau social sur internet."
##  [2] "[] Ecrivez 4 mots clés qui vous viennent à l'esprit à propos d'un réseau social sur internet."
##  [3] "[] Ecrivez 4 mots clés qui vous viennent à l'esprit à propos d'un réseau social sur internet."
##  [4] "[] Ecrivez 4 mots clés qui vous viennent à l'esprit à propos d'un réseau social sur internet."
##  [5] "En quelques mots quelle définition donneriez vous d'un réseau social sur internet ?"          
##  [6] "[Skyblog] Pensez-vous que les sites suivants sont des réseaux sociaux ?"                      
##  [7] "[Copains d'avant] Pensez-vous que les sites suivants sont des réseaux sociaux ?"              
##  [8] "[Pinterest] Pensez-vous que les sites suivants sont des réseaux sociaux ?"                    
##  [9] "[Flickr] Pensez-vous que les sites suivants sont des réseaux sociaux ?"                       
## [10] "[Instagram] Pensez-vous que les sites suivants sont des réseaux sociaux ?"                    
## [11] "[meetic] Pensez-vous que les sites suivants sont des réseaux sociaux ?"

Par cette commande on voit chaque variable avec son intitulé tel qu’il a été présenté aux répondants.

Représentation d’une variable qualitative

Comme on l’a vu la semaine dernière on peut représenter une variable qualitative par un diagramme bâton appellé barplot dans R ou par un diagramme en camembert appellé pie. On va utiliser la question sur “Skyblog” de notre questionnaire pour faire ces deux graphiques. Pour distinguer une variable dans notre questionnaire il y a plusieurs façons de faire, une des plus simple consiste à utiliser le signe $. Notre base est dans l’objet data et la question sur les skyblog est codée Q3_SQ001 on peut afficher la colonne ainsi : data$Q3_SQ001.

data$Q3_SQ001
##  [1] Je ne le connais pas OUI                  NON                 
##  [4] NON                  Je ne le connais pas NON                 
##  [7] OUI                  NON                  OUI                 
## [10] Je ne le connais pas Je ne le connais pas NON                 
## [13] <NA>                 NON                  OUI                 
## [16] NON                  NON                  NON                 
## [19] OUI                  OUI                  NON                 
## [22] OUI                  NON                  OUI                 
## [25] NON                  Je ne le connais pas NON                 
## [28] Je ne le connais pas OUI                  NON                 
## [31] OUI                  <NA>                 Je ne le connais pas
## [34] Je ne le connais pas NON                  Je ne le connais pas
## [37] Je ne le connais pas NON                  Je ne le connais pas
## [40] Je ne le connais pas Je ne le connais pas <NA>                
## [43] <NA>                 NON                  Je ne le connais pas
## [46] OUI                  OUI                  OUI                 
## [49] OUI                  OUI                  NON                 
## [52] NON                  OUI                  OUI                 
## [55] OUI                  Je ne le connais pas NON                 
## [58] Je ne le connais pas <NA>                 OUI                 
## [61] OUI                  Je ne le connais pas <NA>                
## [64] <NA>                 NON                  OUI                 
## [67] NON                  Je ne le connais pas
## Levels: OUI NON Je ne le connais pas

En appliquant la commande table() on fait un tableau :

table(data$Q3_SQ001)
## 
##                  OUI                  NON Je ne le connais pas 
##                   21                   22                   18

Remarquez que par défaut les non-réponses n’ont pas été prises en compte dans le tableau. On pourrait les ajouter en précisant l’option :

table(data$Q3_SQ001, useNA = "ifany")
## 
##                  OUI                  NON Je ne le connais pas 
##                   21                   22                   18 
##                 <NA> 
##                    7

On peut mettre ce tableau (sans les non-réponses) dans un objet :

tabskyblog<-table(data$Q3_SQ001)

En appliquant la commande barplot() on obtient un diagramme bâton :

barplot(tabskyblog)

Pour obetnir un graphe en camembert on applique la commande pie :

pie(tabskyblog)

Une variable quantitative

La seule variable quantitative dont nous disposons est l’âge des répondants. On va la recoder c’est à dire on va remplacer sont nom abrégé actuel (“q_2”) par “age” avec le script ci-dessous qu’il n’est pas nécéssaire de comprendre pour le moment :

names(data)[which(attributes(data)$variable.labels == "Quel âge avez-vous ?")]<-"age"

Je peux maintenant afficher cette variable ainsi :

data$age
##  [1] 43 38 35 29 33 30 49 30 32 58 57 49 NA 20 19 21 NA 20 21 NA 21 NA 21
## [24] 19 19 47 53 52 52 NA 40 49 47 17 37 45 24 57 32 99 46 NA NA 40 42 35
## [47] 24 26 31 41 32 33 35 41 27 27 28 38 25 25 16 12 34 NA 25 24 25 32

Je peux faire une boite à moustache avec la commande boxplot :

boxplot(data$age)

Un histogramme avec la commande hist:

hist(data$age)

On voit tout de suite que quelqu’un a répondu une valeur très différente des autres (“99 ans”), il s’agit probablement d’une erreur. Il faudra aller voir soigneusement les réponses de cet individu à toutes les questions et éventuellement remplacer la valeur 99 par une non réponse. Si il est avéré que toutes ces réponses sont improbables ou fantaisistes, on pourra supprimer la ligne entière.

Représentation de 2 variables quantitatives

Comme on ne dispose que d’une seule vraie variable quantitative, pour l’exemple, on va utiliser la variable id qui est un numéro attribué à chaque questionnaire dans l’ordre d’arrivée des réponses. On va voir, bien que cela n’ait aucun autre intérêt que de montrer comment représenter deux variables quantitatives avec R, l’âge des répondants en fonction de l’ordre des réponses.

Pour faire un nuage de points il suffit d’appliquer la commande plot() sur les deux variables :

plot(data$id , data$age)

Remarquez que l’ordre compte si on avait interverti les deux variables on aurait obtenu quelque chose de beaucoup moins lisible :

plot(data$age , data$id)

Représentation simultanée d’1 variable qualitative et d’1 quantitative

Si on veut représenter l’âge (une variable quantitative) en fonction du genre (une variable qualitative) un graphique qui représente les deux est très parlant pour comparer la répartition de la variable quantitative en fonction de chaque modalité de la variable qualitative. Faire ceci dans R est assez simple en utilisant le signe ~, tilde3.

plot(age ~ genre , data = data)

On voit tout de suite qu’il y a une différence entre les hommes et les femmes. Si la médiane des deux boxplot (gros segment noir) est à peu près la même, les premier et troisième quartiles sont beaucoup plus rapprochés pour les femmes. C’est peut-être dû au fait que l’on a peu de données. À vérifier avec la base finale.

À noter que la variable quantitative doit figurer la première sinon on obtient un graphique différent.

plot(genre ~ age , data = data)

Comme on peut toujours transformer une variable quantitative en variable qualitative (en construisant des classes c’est ce que l’on a vu la semaine dernière) il est toujours possible de représenter graphiquement une variable quantitative comme une variable qualitative.

Représentation de 2 variables qualitatives

Le mosaic plot

Pour représenter deux variables qualitatives sur un même graphique la première solution est de laisser R faire ce qui produit un diagramme mosaïque4 :

plot(genre ~ skyblog , data = data)

On voit sur ce graphique la répartition entre les hommes et les femmes et leurs réponses aux questions sur les skyblog. On voit qu’il y a plus d’hommes qui ont répondu “non” que “oui”. Remarquez qu’il ne s’agit pas d’effectifs qui sont représentés sur cette figure mais de proportions, de pourcentages, indiquées sur l’échelle de droite de 0 à 1 (0.0 0.2 0.4...). Il nous faut regarder les mêmes informations en effectif, le nombre d’observations, pour cela on va faire un tableau croisé, comme tout à l’heure on va utiliser la commande table mais cette fois avec deux variables qualitatives au lieu d’une seule :

table(data$genre , data$skyblog)
##            
##             OUI NON Je ne le connais pas
##   Une femme  15  13                   15
##   Un homme    4   6                    3

On voit grâce au tableau qu’il y a seulement 6 hommes qui ont répondu “non” et 4 qui ont répondu “oui”. On a donc seulement 2 hommes de plus ce qui est très peu et qui peut changer si le questionnaire se remplit encore.

Le barplot avec deux variables

Il serait surement mieux de représenter ce tableau avec un diagramme en barres on va donc appliquer la fonction barplot() sur le tableau ainsi :

barplot( table(data$genre , data$skyblog) , col = c("black" , "grey"))

Remarquez que, séparée par une virgule, on a spécifié une option de couleur col = c("black" , "grey"), on aurait pu choisir d’autres couleurs ainsi :

barplot(table(data$genre , data$skyblog) , col = c("green" , "blue"))

Il nous manque encore une légende on va l’ajouter ainsi :

barplot(table(data$genre , data$skyblog) , col = c("green" , "blue"))
legend("topright", fill = c("blue" , "green"),  c("homme", "femme"))

Remarquez que dans la commande de la légende les couleurs sont inversées fill = c("blue" , "green") par rapport à l’option du graphique col = c("green" , "blue").

La légende est positionné en fonction de l’argument "topright". Elle remplit sa fonction mais est mal placée. On va indiquer des coordonnées pour qu’elle ne compromette pas trop la lisibilité de l’illustration.

barplot(table(data$genre , data$skyblog) , col = c("green" , "blue"))
legend(2.8, 5, fill = c("blue" , "green"),  c("homme", "femme"))

Options dans les fonctions graphiques de R

Il manque encore des informations clé comme un titre ou des noms d’axes qui sont très importants pour la lisibilité.

Pour ajouter un titre quelle que soit la commande graphique (plot, barplot, boxplot…) il faut préciser des options. Si on reprend le premier graphique qui représentait les réponses à la question sur le skyblog :

plot(data$id , data$age)

On va y ajouter un titre ainsi :

plot(data$id , data$age , main = "Âge des répondants selon l'ordre d'arrivée des questionnaires")

On va nommer les axes avec les options xlab et ylab :

plot(data$id , data$age , main = "Âge des répondants selon l'ordre d'arrivée des questionnaires", xlab = "Ordre des réponses", ylab = "Âge")

Plus de deux variables ?

À partir de cette idée de représenter 2 variables sur un seul graphique les choses peuvent se compliquer beaucoup en cherchant à en représenter 3, 4, 5 voir plus en jouant sur les couleurs, la forme, l’interactivité, l’animation.
Jacques Bertin (encore lui) a théorisé ces possibilités je vous invite à vous y intérrésser car c’est l’exemple typique d’une théorie qui dans les années 60 semblait un peu abstraite et qui aujourd’hui est le fondement de la plupart des fonctions graphiques des logiciels. Un exemple avec la vidéo ci-dessous faite par Microsoft pour vendre une application de traitement de données. Si on la regarde sous le regard de la théorie de Bertin, on y voit une mise en pratique qui plus de 50 ans plus tard est tout à fait d’actualité. Le jeu de données qui y est présenté recense les survivants et les disparus du Titanic :

Des visualisations de données plus complexes sont très courantes sur internet on citera ces deux sites : https://flowingdata.com/ et https://datavizcatalogue.com/ mais il est possible d’en trouver un grand nombre sur les réseaux sociaux par exemple.

En conclusion

Il faut classer, ordonner les représentation pour représenter des ensembles. Pour cela il faut avoir bien compris que les graphiques sont la représentation d’une liste dans le cas d’une seule variable et d’un tableau (plus ou moins compliqué) quand il y a au moins deux variables.

Je vous invite vivement à lire cet entretien avec Jacques Bertin : http://www.persee.fr/doc/colan_0336-1500_1975_num_28_1_4248 qui présente tout ce qu’il faut savoir pour représenter des données.

À faire

Choisissez 5 variables dans le questionnaire et faites en des représentations graphiques.

Rédigez un compte rendu avec des graphiques indiquant clairement ce que vous y voyez.

Vous enverrez votre document par email à Mehdi.Khaneboubi@u-cergy.fr.


  1. Vous trouverez un article en anglais sur la question ici dont sont issue les graphiques ci-dessous : What’s Wrong with this Picture? The Art of Honest Visualizations. Mike Woodward, 2015. http://data-informed.com/whats-wrong-picture-art-honest-visualizations

  2. On peut aussi utiliser beaucoup d’autres fonctions qui donnent des informations sur la base de données voir notamment l’excellent document de Julien Barnier : https://juba.github.io/tidyverse/03-premier_travail.html#structure-du-tableau

  3. On a recodé la variable sur le genre avec le script names(data)[which(attributes(data)$variable.labels == "Vous êtes :")]<-"genre" car son intitulé préttait à confusion. Remarquez que la formule utilisée dans la fonction plot est différente de celle utilisée précédemment puisque l’on utilise seulement les noms de colonne[^rcd] : age ~ genre et que l’on indique le nom de l’objet ensuite data = data[^bjt]

  4. À noter que la variable portant sur les Skyblogs a été recodée. Le nom de colonne “Q3_SQ001” a été remplacé par “skyblog” avec la commande : names(data)[14]<-"skyblog"