Introduction aux graphiques avec R

Voici une synthèse non exhaustive introduisant la modélisation de données à travers l'utilisation du langage R. Ce dernier est une langage libre dédié aux statistiques et à la science des données (Source : Wikipédia). Bien entendu, nous n'évoquerons ici qu'une infime partie de ce dont est capable cet écosystème.

Heureusement pour nous, il n'est pas nécessaire de maîtriser l'intégralité du langage R pour profiter au moins d'un fragment (et non du moindre !) : les bibliothèques de représentation des données sous une multitude de formes de graphes. Commençons avec une mise en contact fortement inspirée du tutoriel présent sur le site Harding.

Les bases des graphes en R

Avant tout, il faudra installer le logiciel. Sous Fedora par exemple, un simple sudo dnf install R fera l'affaire.

Le premier contact

Voici une liste d'instructions à renseigner dans votre interpréteur R :

Dessin de notre premier graphique
# Définition de deux vecteurs.
> cars  trucks  g_range  g_range
[1]  0 12

# Cette commande génère une ligne représentant les valeurs de notre vecteur « cars ».
# Pour plus d'information concernant l'utilisation de la fonction «plot »,
# je vous invite à lire la documentation adéquate.
> plot(cars, type="o", col="blue", ylim=g_range, 
+ axes=FALSE, ann=FALSE)

# Nous créons l'axe des abscisses, des points 1 à 5, ayant respectivement les valeurs 
# contenues dans le  vecteur « lab ».
> axis(1, at=1:5, lab=c("Mon","Tue","Wed","Thu","Fri"))

# Création de l'axe des ordonnées, avec un label toutes les quatre entrées, 
# de zéro au second élément de g_range, soit la valeur maximale.
> axis(2, las=1, at=4*0:g_range[2])

# Création d'une « boite » au tour du graphique.
> box()

# Ajout d'une ligne correspondant aux valeurs des camions.
> lines(trucks, type="o", pch=22, lty=2, col="red")

# Ajout d'un titre au tableau.
> title(main="Autos", col.main="red", font.main=4)

# Ajout d'un titre à l'axe des abscisses.
> title(xlab="Days", col.lab=rgb(0,0.5,0))
# Ajout d'un titre à l'axe des ordonnées.
> title(ylab="Total", col.lab=rgb(0,0.5,0))

# Création d'un bloc de légende en haut à gauche.
> legend(1, g_range[2], c("cars","trucks"), cex=0.8, 
+  col=c("blue","red"), pch=21:22, lty=1:2);

À présent, le tableau ci-dessous devrait être généré. Il n'a rien d'exceptionnel, mais nous pouvons quand même constater la simplicité avec laquelle il aura été réalisé.

Utilisation des véhicules cette semaine

Notre premier graphique en R !

Si nous désirons avoir une sortie autrement que via R Graphics, nous pouvons le faire avant de commencer à dessiner le graphe. Par exemple, si nous renseignons l'instruction png(filename="/tmp/figure.png", height=295, width=300, bg="white") avant toutes celles du bloc précédent, l'image sera en fait constituée dans le fichier /tmp/figure.png. De la même façon pdf(file="/tmp/figure.pdf", height=3.5, width=5) permettra d'enregistrer le graphique dans un PDF. Attention toutefois, le dessin ne se fera plus en temps réel. Il faudra en effet finir avec l'instruction dev.off() pour écrire le fichier sur le disque dur.

Lecture depuis un fichier

Il est bon à savoir que nous pouvons très facilement récupérer les données d'un fichier plutôt que de devoir les écrire en dur dans le code de notre application. On pourrait par exemple avoir le fichier suivant :

Fichier : auto.dat
cars    trucks  suvs
1       2       4
3       5       4
6       4       6
4       5       6
9       12      16

Qui serait utilisé de cette façon :

Chargement d'un fichier en R
# On charge le fichier, en disant que la première ligne
# correspond au header, et la tabulation comme séparateur de colonnes.
> autos_data  autos_data
 cars trucks suvs
1    1      2    4
2    3      5    4
3    6      4    6
4    4      5    6
5    9     12   16
# Nous pouvons à présent utiliser les éléments de ce fichier 
# comme nous le faisions précédemment avec des vecteurs.
# Voici par exemple la génération de la ligne correspondant
# aux infos des camions.
> lines(autos_data$trucks, type="o", pch=22, lty=2, col="red")

De façon similaire, il serait également possible de récupérer les données depuis des systèmes de gestion de base de données comme SQLite.

L'intégration des graphiques dans des documents LaTeX

Une autre force de R est la grande intégration que son écosystème partage avec celui de LaTeX, le compositeur de documents. Nous présenterons le module R « tikzDevice », qui permet d'obtenir une sortie TikZ des graphiques. Voici une illustration :

Fichier : figs/auto.R
#!/usr/bin/env Rscript
require("tikzDevice")
tikz("auto.tex", width = 5, height = 3)

cars <- c(1, 3, 6, 4, 9)
trucks <- c(2, 5, 4, 5, 12)
g_range <- range(0, cars, trucks)

plot(cars, type="o", col="blue", ylim=g_range, axes=FALSE, ann=FALSE)
axis(1, at=1:5, lab=c("Mon", "Tue", "Wed", "Thu", "Fri"))
axis(2, las=1, at=4*0:g_range[2])
box()
lines(trucks, type="o", pch=22, lty=2, col="red")

title(main="Autos", col.main="red", font.main=4)
title(xlab="Days", col.lab=rgb(0,0.5,0))
title(ylab="Total", col.lab=rgb(0,0.5,0))
legend(1, g_range[2], c("cars","trucks"), cex=0.8, col=c("blue","red"), pch=21:22, lty=1:2);

dev.off()
Fichier : main.tex
\documentclass[a4paper, 10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry}
\usepackage{tikz}
\title{Essais d'intégration \tt{R} dans \LaTeX}
\author{Kevin Hagner}
\date{\today}

\begin{document}

\maketitle

\begin{figure}[h]
	\centering
	\input{figs/auto.tex}
	\caption{Utilisation des véhicules motorisés}
\end{figure}

Voici un graphe représentant l'utilisation des véhicules motorisés ces derniers temps.
\end{document}

Nous pouvons voir que depuis le fichier LaTeX, on importe figs/auto.tex, qui n'existe en fait pas encore. Pour l'obtenir, il faudra exécuter le script R qui le génèrera :

Commandes Linux À exécuter pour générer le document
> cd figs
> ./auto.R
> cd ..
> pdflatex main.tex

Le résultat nous montre une intégration parfaite ☺.

PDF compilé avec LaTeX

Notre graphique en R est correctement intégré au document !

Une grande variété de types de graphes différents

Pour cette illustration, j'ai employé la plus basique des méthodes de représentation les données : un graphique en deux dimensions. R nous permet d'utiliser une très grande variété de graphes de façon tout aussi simple. Il est même possible de réaliser nos propres systèmes. Cette page en liste quelques-uns.

Ces types de graphes sont également exportables dans les formats précédemment évoqués : PNG, PDF, TikZ, mais aussi beaucoup d'autres (svg, cairo, etc.).

La création de documents Web interactifs

L’interaction côté client

Rédiger des documents texte de qualité est une bonne chose, mais profiter de l'interactivité que peut nous offrir le Web en est une autre, autrement plus intéressante ! Ainsi, un grand nombre de librairies JavaScript de représentation des données peuvent être utilisées depuis R grâce au projet htmlwidget.

De cette façon, au lieu de réaliser une image PNG, un PDF, ou un autre format de dessin statique, nous générerons une page HTML chargeant toutes les dépendances nécessaires à l'affichage de la représentation via la librairie choisie.

Voyons un exemple présent sur le site sus-cité permettant d'utiliser la bibliothèque Bokeh.

> library(rbokeh) #Chargement de rbokeh
> # Nous affichons ici un jeu de données préchargé dans l'environnement R 
> # à des fins de test. On va l'utiliser pour générer notre graphique.
> iris
   Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
1            5.1         3.5          1.4         0.2     setosa
2            4.9         3.0          1.4         0.2     setosa
3            4.7         3.2          1.3         0.2     setosa
[…]

> figure() %>%
+ # On affiche un graphe ayant la longueur du sepale 
+ # en abscisse, et sa largeur en ordonnée.
+ ly_points(Sepal.Length, Sepal.Width, data = iris,
+ # La couleur et la forme des points dépendra de l'espèce.
+   color = Species, glyph = Species,
+ # Quand on passe la souris sur un point, des informations 
+ # complémentaires seront disponible, à savoir la hauteur et largeur du sépale.
+   hover = list(Sepal.Length, Sepal.Width)) 

Et c'est tout ! Cependant, il est vrai que l'intérêt peut se montrer limité pour des développeurs habitués à travailler avec des technologies Web, car plutôt que de passer par R, nous pouvons directement utiliser les librairies sous-jacentes permettant d'avoir un code plus optimisé. Néanmoins, cela reste une solution intéressante de par sa rapidité de mise en œuvre.

Graphique généré par Bokeh

Graphique interactif généré par Bokeh

Shiny : le serveur web dynamique

Là où la chose peut devenir plus intéressante encore, c'est si nous voulons ajouter un cran de plus au niveau de l'interactivité en permettant de charger dynamiquement l'affichage côté serveur. C'est ce que Shiny nous propose.

Prenons par exemple ce graphique, qui représente le prix de diamants en fonction de leurs carats, depuis des données de test :

> library(ggplot2)
> # Génération du graphique
> p  # Exportation du graphique en SVG
> ggsave(file="diamonds.svg", plot=p, width=6, height=4)
Graphique du prix des diamants en fonction de leurs carats

Prix des diamants en fonction de leurs carats

Celui-ci affiche bien trop d'éléments pour être pertinent (53 940 points). Afin de pouvoir choisir dynamiquement le nombre de points à représenter, nous pouvons utiliser le code de ces deux fichiers :

Fichier : ui.R
library(shiny)

# Les données à utiliser seront celles du jeu "diamonds"
dataset <- diamonds

shinyUI(fluidPage(
 # Ici, on dessine la page.
 title = 'Use the DT package in shiny',
 sidebarLayout (
   # On utilisera deux colonnes dans notre page.
   # La première contiendra un slider.
   sidebarPanel (
     sliderInput("bins", "Number of bins:", 
     min= 1, max = nrow(dataset), value = 1000)
   ),
   # La seconde un graphique nommé "distPlot".
   mainPanel (plotOutput("distPlot"))
 )
))
Fichier : server.R
library(shiny)
library(DT)
library(ggplot2)

shinyServer(function(input, output, session) {
# Le dataset ne correspond plus à l'ensemble de éléments
# présent dans "diamonds", mais uniquement des x premières
# lignes, avec x défini par la valeur de notre slider
# "bins".
dataset <- reactive({
   diamonds[sample(nrow(diamonds), input$bins),]
 })
 # On dessine notre graphique qu'on renverra au client
 # dans l'élément "distPlot".
 output$distPlot <- renderPlot({
    p <- ggplot(dataset(), aes_string(x='carat', y='price')) + geom_point()
    print(p)
 })
})

Et enfin, lancer notre application de cette façon :

> package("shiny")
> package("ggplot2")
> # Si ui.R et server.R sont dans le dossier courant.
> runApp(".")

Listening on http://127.0.0.1:5642

Maintenant, nous aurons un serveur Web Shiny qui s'exécutera sur notre machine (ici sur le port 5642), que l'on pourra interroger pour récupérer une page HTML. Deux éléments sont créés depuis le code ui.R : un slider nommé « bins » et un graphique « distPlot ». Ce dernier est généré depuis le fichier server.R, à l'aide de la valeur du slider (initialisée à 1000).

Capture d'écran de notre graphique et de son slider.

Capture d'écran de notre graphique et de son slider.

Encore une fois, cet exemple est très simpliste et loin de rendre honneur à l'étendue de ce que Shiny peut gérer. Il permet par exemple de concevoir des dashboard entiers. Mais comme évoqué dans le titre de cet article, il ne s'agit ici que d'introductions. Une des questions que je me pose avec Shiny est relative à la consommation en ressources de l'outil et à la capacité d'un serveur unique à  gérer plusieurs dashboards.

Conclusion

Je pense en avoir fini avec ce tour des diverses possibilités que nous offre R dans la représentation des données. Il s'agit d'un travail de synthèse que j'ai effectué par curiosité. Malgré ma vigilance, il est donc probable que des petites erreurs se soient glissées dans le texte, ou alors que je sois passé à côté d'autres outils qui auraient eux aussi mérités leur paragraphe ici. Si tel est le cas, je vous invite à m'en faire part. En attendant, je ne peux que vous encourager à approfondir vos connaissances dans ces outils et à mettre tout cela en pratique !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *