Introduction à R


Mettre en oeuvre une chaîne de traitement reproductible

Cette présentation s’adresse aux personnes souhaitant s’initier au language/logiciel R et aux démarches d’analyse reproductibles. Elle s’articule tout d’abord autour d’une présentation de R, de son environnement Rstudio et des atouts de cet outil (polyvalence, extensibilité, reproductibilité…). Dans un second temps et en suivant un exemple illustré sont présentées plusieurs librairies utiles pour couvrir une chaîne de traitement, depuis l’acquisition et la mise en forme des données, en passant par leur analyse et leur représentation jusqu’à leur export et leur valorisation.

Objectifs de la séance :

– Acquérir les bases du logiciel/language R et de son environnement RStudio.

– Comprendre les atouts de cet outil pour la mise en place d’une chaine de traitements reproductible.

– Découvrir les librairies utiles pour réaliser les traitements les plus courants.


Pourquoi R ?

La (R)évolution

Toutes les disciplines dans lesquelles l’analyse de données occupe une place importante ont connu ces dernières années une petite R-évolution. Depuis le début des années 2000, le logiciel R gagne en importance et s’impose petit à petit comme une référence, au même titre que les trois grands logiciels (payant) d’analyse de données qui domine le marché : SAS, SPSS et Stata.

Figure : Popularité croissante du langage R depuis 2008 (classement Index TIOBE)


  • Libre et multiplateforme
  • R est un langage de programmation et un logiciel libre dédié aux statistiques et à la science des données soutenu par la R Foundation for Statistical Computing. R fait partie de la liste des paquets GNU. Il est multiplateforme et peut donc s’installer sur Windows, Mac OS ou GNU/Linux.


  • Polyvalent
  • R permet de manipuler tous types d’objets. C’est d’ailleurs pour une de ces raisons qu’il concurrence, complète ou remplace toute une gamme de logiciels et de langages pré-existants y compris dans des domaines trés spécifiques, par exemple : la statistique textuelle, l’analyse de graphes, la cartographie, la statistique spatiale, le traitement d’enquête, le webscraping, la production de document, les applications web…. il entre aussi en concurrence avec d’autres langages très utilisés pour le calcul scientifique et l’analyse de données, comme Python.


  • Extensible
  • R est composé d’un socle commun r-base (fonctions statistiques et graphiques standards, appelées fonctions primitives ou basiques) sur lequel se greffe un ensemble d’extensions appelées packages. Un package est une bibliothèque de fonctions implémentée par les utilisateurs et mise à disposition de tous par l’intermédiaire de dépôts regroupés dans le cadre du Comprehensive R Archive Network (CRAN). Cette structure modulaire explique la vaste étendue des applications possibles : l’expansion du logiciel n’est limité que par les contributions des utilisateurs du monde entier à la communauté (13517 packages disponibles sur le CRAN le 06 déc. 2018.


  • Reproductible
  • L’ensemble d’une chaine de traitement peut ainsi être réalisée sous R, depuis l’import, la manipulation de données, leur analyse et représentation, jusqu’à leur diffusion. Ce flux de travail intégré est par ailleurs plus efficace et plus sûr : suppression des imports et exports permettant de passer d’un logiciel à l’autre, meilleure manipulation des données (éviter les erreurs courantes de copier/coller dans des interfaces clic-bouton). Au final, le fait de décrire toute la chaine de traitement de l’information dans des scripts exécutables assure l’archivage, la diffusion et la reproductibilité de l’integralité de son travail et de sa méthodologie.


Un language pour tout f’R

Ces différents atouts ont fait de R un outil adopté par de nombreuses disciplines scientifiques, aussi bien issues des SHS que des sciences “dures”. R dispose aujourd’hui de nombreux contributeurs aux profils et interêts variés, ce qui lui assure un développement fonctionnel et thématique à la fois large et spécialisé.

Actuellement, en plus des fonctions du socle commun r-base, 13517 librairies (packages) sont disponibles sur le Comprehensive R Archive Network (CRAN). De nombreux packages en développement sont aussi mis à disposition sur GhitHub (service web d’hébergement et de gestion de développement de logiciels). Certains champs scientifiques ont également leur propre dépôt, comme la biostatistique avec le site bioconductor qui met à disposition plus de 1600 packages (Novembre 2018), permettant d’analyser et décrypter le génome.

R est ainsi trés utilisé dans le monde académique, mais aussi au sein d’organismes publics, d’ONG, chez les analystes travaillant comme consultants (selon Rexer Analytics).
Cette communauté éclectique est trés active sur le web. Elle se rassemble par exemple autour du hashtag #rstats sur twitter ou se retrouve sur des forums comme Stack Overflow, qui a pour objectif de rassembler une communauté de développeurs pour partager leurs connaissances ou problèmes dans le domaine de la programmation. Il existe également une importante blogosphère, notamment mise en valeur par les agrégateurs de blogs comme Rweekly ou R-bloggers.

Cette communauté importante de contributeurs et d’utilisateurs se traduit par une polyvalence remarquable de l’outil. R se substitue à tout un ensemble de logiciel qu’il était nécessaire de maîtriser et d’utiliser pour réaliser l’ensemble d’une chaine de traitement. Il est desomais possible de réaliser une chaîne de traitement complète et reproductible à l’aide d’un seul outil libre, gratuit et multiplateforme.



Se facilite(R) la vie avec RStudio

RStudio est un outil qui vient combler un manque dans la collection des outils associés à R : il s’agit d’un environnement de développement intégré (IDE en anglais) facilitant la saisie, l’exécution de code, la visualisation des résultats… etc.

En effet, le logiciel R propose une interface trés pauvre sur MAC et Windows et inexistante sous linux.

Figure : Interface du logiciel R, sous Windows


Figure : Aucune interface sous Linux. Utilisation du terminal

L’IDE Rstudio facilite considérablement l’apprentissage et l’utilisation du langage R. Parque c’est pratique, complet et en rapide évolution : il est recommandé d’utiliser l’environnement RStudio !

L’interface de RStudio se présente sous la forme d’une unique fenêtre découpée en quatre zones que l’on peut redimensionner, masquer ou maximiser selon ses préférences :

  • L’éditeur de code
  • Cette zone permet l’édition de fichiers source R (avec coloration syntaxique et autocomplétion).

  • La console
  • La console avec la session R en cours d’exécution. La console affiche à la fois le code exécuté et ses résultats associés.

  • L’espace de travail
  • Cette zone permet de lister, typer et visualiser les objets créés par l’exécution du code R.

  • Une quatrième zone pemettant de basculer entre :
  • Un explorateur de fichiers, une fenêtre graphique, une fenêtre de gestion des packages et de la documentation associée aux fonctions et packages.


    RStudio propose de nombreuses fonctionnalités intéressantes, par exemple :

    • La création de projet
    • RStudio dispose d’une fonctionnalité très pratique pour organiser son travail en projets. L’idée principale est de réunir tous les fichiers et documents relatifs à un même projet (que ce soit les données, les scripts, les rapports automatisés…) dans un répertoire dédié. L’onglet Projects est situé en haut à droite de l’interface. Cela permet notamment de partager à d’autres ses analyses sans avoir à se soucier des chemins permettant d’accéder aux fichiers. Pourquoi utiliser les projets RStudio ?

      -> Un repertoire de travail prédéfini : Le répertoire de travail de R est celui du projet. Il n’est plus utile de paramétrer un répertoire courant.

      -> Une mémoire de l’espace de travail : Lorsque l’on ouvre un projet RStudio, on revient à l’état de notre projet tel qu’il était lors de la dernière utilisation. Les scripts ouverts lors d’une précédente séance de travail sont automatiquement chargés.

      -> Une mobilité améliorée : Vous pouvez utiliser facilement votre projet et vos scripts sur différentes machines et/ou systèmes d’exploitation sans perdre d’information. Il suffit de copier/coller le répertoire du projet.

      -> L’utilisation d’un Git : Il est possible d’utiliser des systèmes de gestion de version comme svn ou git. Les systèmes de gestion de version permettent de gérer les différentes versions de scripts et facilite le travail collaboratif.


    • Une interface clic-bouton pour faciliter la prise en main de l’outil
    • Plusieurs actions comme la création et le chargement de programme, l’import de données, l’installation et le chargement de packages, l’accés à la documentation, la visualisation des objets, l’export de figures… sont exécutables en un simple clic.

    • L’autocomplétion
    • RStudio présente aussi la capacité de compléter automatiquement les termes en cours d’écriture. L’autocomplétion fonctionne avec la touche Tab du clavier. Cela aide l’utilisateur dans la saisi des noms d’objet, de fonction, de variable, et même des arguments de fonction.

    • Raccourcis clavier
    • RStudio propose de nombreux raccourcis clavier intéressants, exemple :

      • Alt + - renvoie l’opérateur d’assignation accompagné d’un espace avant et un espace après (<-)
      • Ctrl + Entrée exécute le code écrit dans la fenêtre d’édition (script)
      • Ctrl + 1 et Ctrl + 2 permettent de passer de la console à l’éditeur de code et vice versa
      • shift+alt+k pour accéder à l’ensemble des raccourcis.


> Exemple

A ce lien, vous pouvez télécharger un projet R qui contient des données et un script R prêt à être éxécuté. Ce script réalise une chaîne de traitement complète. Les données sont successivement téléchargées, explorées, enrichies, analysées et cartographiées. Il vous suffit de dézipper le dossier, d’ouvrir le projet RUSS_inro_R.proj et d’éxécuter le scrit osm.R.

Au bout de cette chaîne de traitement, deux cartes réalisées à partir de données extraites d’OpenStreetMap:


0. Prise en main


0.1 Installation

Vous pouvez télécharger le logiciel R depuis le Comprehensive R Archive Network (CRAN) :

Une fois R correctement installé, rendez-vous sur le site web Rstudio pour télécharger la dernière version stable de RStudio. Plus précisément, il s’agit de l’édition Open Source de RStudio Desktop (il existe aussi une version serveur) :

Choisissez l’installateur correspondant à votre système d’exploitation et suivez les instructions du programme d’installation.

Pour mettre à jour R, il suffit de télécharger et d’installer la dernière version du programme d’installation.
Petite particularité, la nouvelle version sera installée à côté de l’ancienne version. Désinstallez l’ancienne version si vous souhaitez faire de la place sur votre disque dur. Lorsque plusieurs versions de R sont disponibles, RStudio choisit par défaut la plus récente. Il est vous est possible de spécifier à RStudio quelle version de R utiliser via le menu Tools > Global Options > General.

Si vous souhaitez utiliser R et RStudio, vous n’avez en aucun cas besoin de lancer le logciel R. Il vous suffit d’ouvrir RStudio.


0.2 Les projets RStudio

Cette fonctionnalité permet d’organiser son travail en différents projets. L’idée principale est de réunir tous les fichiers relatifs à un même projet (quelque soit leur format) dans un répertoire dédié. Le menu “Project” est accessible via une icône dédiée située tout en haut à droite :



Dans le menu Project, sélectionnez l’option New project :



Dans un nouveau répertoire, créez un projet vide. Indiquez le nom de votre projet, qui sera également le nom du répertoire créé pour stocker les données du projet. Puis, indiquez le répertoire parent, dans lequel votre projet sera créé :



0.3 Les objets R

Tout ce qui est créé et manipulé sous R est un objet. Ces objets permettent de stocker et de structurer les données.

Créer un objet

Un objet peut être créé avec l’opérateur « assigner » (<-), une flèche composée du signe inférieur (<) accolé à un tiret (-). Si l’objet existe déjà, sa valeur précédente est remplacée par la nouvelle. La valeur renvoyée peut être le résultat d’une opération et/ou d’une fonction :

n <- "chaîne de caractères"

n
## [1] "chaîne de caractères"
n <- 15 + 9

n
## [1] 24

On peut également écrire une expression sans assigner son résultat ou sa valeur à un objet, le résultat est alors affiché à l’écran mais n’est pas stocké dans un objet en mémoire :

(10 + 2) * 5
## [1] 60


La fonction

Le logiciel R dispose de fonctions préprogrammées appelées fonctions primitives ou basiques et regroupés dans le package base qui est automatiquement chargé. Pour connaître toutes les fonctions primitives, utilisez la fonction library(help = “base”) :

library(help = "base")

# Quelques exemples...

# class()           Connaitre la classe de données d'un élément
# as.character()    Assigner la class 'caractere' à un élement
# is.numeric()      Tester si un élément est numéric (réponse TRUE ou FALSE) 
# paste()           Coller des chaine de caractère
# unlist()         permet de transformer une liste en vecteur

Pour utiliser une fonction, il suffit d’écrire son nom, puis de spécifier des arguments entre parenthése.

Exemple de fonctions permettant d’assigner ou de modifier la classe d’un objet :

# Les différentes fonctions permettant de modifier la classe de l'objet 'mon_objet' :
as.vector(x='mon_objet')
as.data.frame(x='mon_objet')
as.matrix(x='mon_objet')
as.array(x='mon_objet')
as.list(x='mon_objet')
as.factor(x='mon_objet')
# Exemple
mon_objet <- "20345"

class(mon_objet)
## [1] "character"
mon_objet <- as.numeric(mon_objet)

class(mon_objet)
## [1] "numeric"

Dans la plupart des cas, les arguments d’une fonction sont prédéfinis. Il est donc important de se renseigner sur les différents arguments d’une fonction et ses valeurs paramétrées par défault. Attention, certains arguments n’ont pas de valeur prédéfinie mais doivent obligatoirement être renseigné.

Exemple avec la fonction mean() :

notes <- c(11,13,15,17,10,8,14,13,12,15,19,NA)

# Il est évidemment obligatoire de spécifier le vecteur de valeurs sur lequel on calcul une moyenne !
mean(notes)
## [1] NA

La fonction mean() retourne NA car la série statistique présente une valeur manquante (NA). L’arguments na.rm (= FALSE par défault) permet de ne pas prendre en compte les valeurs manquantes :

# na.rm (= FALSE par défault) permet de prendre en compte ou non les valeurs NA
mean(notes, na.rm = TRUE)
## [1] 13.36364

L’utilisateur a également la possibilité de définir ses propres fonctions. Une fonction est mise dans une variable contenant un bloc d’instructions introduit par la commande function(). La syntaxe générale est :

nom_de_fonction <- function(arguments) { instructions }

Exemple :

# Ecriture une fonction
carre <- function(x) {
  y <- x*x
  return(y)
}

# Pour afficher le code source d'une fonction (non primitive), 
# écrire son nom sans parenthèse :
carre
## function(x) {
##   y <- x*x
##   return(y)
## }
# Utiliser une fonction :
# fonction(argument1=... , argument2=..., argument3=..., ... )

# Exemple :
# carre(x=3) ou plus simplement :
carre(3)
## [1] 9

Si vous souhaitez utiliser une fonction issue d’un package spécifique, vous devez d’abord installer le package et chargez la library :

# Installation du package
install.packages("foreign")

# Chargement de la library
library(foreign)

# Utilisation de la fonction read.dbf() de la library "foreign"
# L'argument as.is permet de convertir ou non les vecteurs en facteurs
read.dbf("D:/users/geographie/Documents/nom_fichier.dbf", as.is = FALSE)


Le vecteur

Un vecteur permet de regrouper des éléments d’une même classe.

# Joindre des éléments dans un vecteur
mon_vecteur <- c(1,2,3,4,5,6,7,8,9)
mon_vecteur <- c("A","B","C","D","E")
mon_vecteur <- c("nom", "prenom", 10, 20.78, TRUE)
mon_vecteur
## [1] "nom"    "prenom" "10"     "20.78"  "TRUE"
# Créer une séquence complexe dans un vecteur
mon_vecteur <- c(seq(2, 3, by=0.5))
mon_vecteur
## [1] 2.0 2.5 3.0
# Répeter un vecteur
mon_vecteur <- c(rep(1:2, times=3))
mon_vecteur
## [1] 1 2 1 2 1 2
# Répeter chaque éléments
mon_vecteur <- c(rep(1:2, each=3))
mon_vecteur
## [1] 1 1 1 2 2 2
# Créer un séquence de nombre entier
mon_vecteur <- c(1:7)
mon_vecteur
## [1] 1 2 3 4 5 6 7
# Ajouter un element à un vecteur
mon_vecteur_new <- c(mon_vecteur, "Un Element Supplémentaire")

# Interroger les élements d'un vecteur -> mon_vecteur[element]
# Elément 2
mon_vecteur[2]
## [1] 2
# Eléments 2 à 4
mon_vecteur[2:4]
## [1] 2 3 4
# Eléments 2 et 5
mon_vecteur[c(2,5)]
## [1] 2 5


Le data frame

Un data frame est utilisé pour stocker une table de données. Il s’agit d’une liste de vecteurs de même longueur.

# Construction de trois vecteurs
personne <- c('John Doe','Peter Gynn','Jolie Hope','John snow')
salaire <- as.integer(c(21000, 23400, 26800, 32700))
date <- as.Date(c('2010-11-1','2008-3-25','2007-3-14', '1678-1-23'))

# Construction du data.frame à partir de trois vecteurs de même longueur
mon_tableau <- data.frame(personne, salaire, date)
mon_tableau
##     personne salaire       date
## 1   John Doe   21000 2010-11-01
## 2 Peter Gynn   23400 2008-03-25
## 3 Jolie Hope   26800 2007-03-14
## 4  John snow   32700 1678-01-23
# Ajouter une variable
mon_tableau$New_col_1 <- "mon_texte"
mon_tableau$New_col_2 <- c(1,2,3,4)
mon_tableau
##     personne salaire       date New_col_1 New_col_2
## 1   John Doe   21000 2010-11-01 mon_texte         1
## 2 Peter Gynn   23400 2008-03-25 mon_texte         2
## 3 Jolie Hope   26800 2007-03-14 mon_texte         3
## 4  John snow   32700 1678-01-23 mon_texte         4
# Interroger les éléments d'un tableau -> mon_tableau[ligne,colonne]
# Ligne 2
mon_tableau[2,]
##     personne salaire       date New_col_1 New_col_2
## 2 Peter Gynn   23400 2008-03-25 mon_texte         2
# Colonnes 1 et 3
mon_tableau[,c(1,3)]
##     personne       date
## 1   John Doe 2010-11-01
## 2 Peter Gynn 2008-03-25
## 3 Jolie Hope 2007-03-14
## 4  John snow 1678-01-23
# Colonne 'personne'
mon_tableau$personne
## [1] John Doe   Peter Gynn Jolie Hope John snow 
## Levels: John Doe John snow Jolie Hope Peter Gynn
# Ligne 4 & colonne 'personne' - method 1
mon_tableau[4,"personne"]
## [1] John snow
## Levels: John Doe John snow Jolie Hope Peter Gynn
# Ligne 4 & colonne 'personne' - method 2
mon_tableau$personne[4]
## [1] John snow
## Levels: John Doe John snow Jolie Hope Peter Gynn


La liste

Une liste est un vecteur d’objets. Il permet de stocker différents types d’objets dans un seul objet.

ma_fonction <- function() {cat("hello")}
mon_vecteur1 <- c('John Doe','Peter Gynn','Jolie Hope','John snow')
mon_vecteur2 <- as.Date(c('2010-11-1','2008-3-25','2007-3-14', '1678-1-23'))
mon_tableau <- data.frame(mon_vecteur1, mon_vecteur2)

# Création d'une liste
ma_liste <- list(ma_fonction, mon_vecteur1, mon_vecteur2,mon_tableau)
ma_liste
## [[1]]
## function () 
## {
##     cat("hello")
## }
## 
## [[2]]
## [1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 
## 
## [[3]]
## [1] "2010-11-01" "2008-03-25" "2007-03-14" "1678-01-23"
## 
## [[4]]
##   mon_vecteur1 mon_vecteur2
## 1     John Doe   2010-11-01
## 2   Peter Gynn   2008-03-25
## 3   Jolie Hope   2007-03-14
## 4    John snow   1678-01-23
# Ajouter un élément à une liste
ma_liste[[length(ma_liste) + 1]] <- "J'ajoute un objet à ma liste"


# Interroger les objets d'une liste -> ma_list[[élement]][sous element]
# Objet 1
ma_liste[5]
## [[1]]
## [1] "J'ajoute un objet à ma liste"
# Objets 2 et 3
ma_liste[c(2,3)]
## [[1]]
## [1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 
## 
## [[2]]
## [1] "2010-11-01" "2008-03-25" "2007-03-14" "1678-01-23"
# Tous les objets sauf le 1 et le 4
ma_liste[-c(1,4)] 
## [[1]]
## [1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 
## 
## [[2]]
## [1] "2010-11-01" "2008-03-25" "2007-03-14" "1678-01-23"
## 
## [[3]]
## [1] "J'ajoute un objet à ma liste"
# Elément 2 de l'objet 3
ma_liste[[3]][2]
## [1] "2008-03-25"


La matrice

Une matrice est un tableau de nombre à double entrée.

ma_matrice <- matrix(c(1:16), nrow=4, ncol=4) 

# On navigue dans une matrice de la même façon que dans un data frame -> ma_matrice[ligne, colonne]
ma_matrice[4,3]
## [1] 12

De nombreuses opérations et fonctions primitives sont applicables à cet objet. Quelques exemples :

# Multiplication de matrice, élément par élément.
ma_matrice * ma_matrice 
##      [,1] [,2] [,3] [,4]
## [1,]    1   25   81  169
## [2,]    4   36  100  196
## [3,]    9   49  121  225
## [4,]   16   64  144  256
# Transposer la matrice
t(ma_matrice)
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
# Sélectionner la diagonale
diag(ma_matrice)
## [1]  1  6 11 16
# Moyennes des lignes
rowMeans(ma_matrice)
## [1]  7  8  9 10
# Sommes des colonnes
colSums(ma_matrice)
## [1] 10 26 42 58


L’array

Les arrays sont des matrices à plusieurs dimensions.

mon_array <- array(1:45, dim=c(3,5,3))
mon_array
## , , 1
## 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## [2,]    2    5    8   11   14
## [3,]    3    6    9   12   15
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   16   19   22   25   28
## [2,]   17   20   23   26   29
## [3,]   18   21   24   27   30
## 
## , , 3
## 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   31   34   37   40   43
## [2,]   32   35   38   41   44
## [3,]   33   36   39   42   45
# Interroger les éléments d'un array -> array[ligne,colonne,tableau]
mon_array[2,5,3]
## [1] 44


Le Simple Feature data frame

L’objet sf est en quelque sorte une table de données géographique. Il permet de gérer de l’information spatiale. Il s’agit tout simplement d’un dataframe qui stocke également des geométries.

# Création d'un vecteur de nombre (1 à 10)
ID <-seq(1:10)
# Création d'un vecteur de lettres (a à j)
name <-letters[1:10]
latitude <- c(48.84905, 48.85217, 48.83349, 48.86528, 48.86409, 48.85176, 48.85207, 48.88334, 48.85758, 48.87391)
longitude <- c(2.331454, 2.347332, 2.318518, 2.371150, 2.356515, 2.299024, 2.358712, 2.333936, 2.352751, 2.343179)

mes_donnees <- data.frame(ID, name, latitude, longitude)

library(sf)
mes_donnees_SF <- st_as_sf(mes_donnees, coords = c("longitude", "latitude"), crs = 4326, agr = "constant")
mes_donnees_SF
## Simple feature collection with 10 features and 2 fields
## Attribute-geometry relationship: 2 constant, 0 aggregate, 0 identity
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: 2.299024 ymin: 48.83349 xmax: 2.37115 ymax: 48.88334
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
##    ID name                  geometry
## 1   1    a POINT (2.331454 48.84905)
## 2   2    b POINT (2.347332 48.85217)
## 3   3    c POINT (2.318518 48.83349)
## 4   4    d  POINT (2.37115 48.86528)
## 5   5    e POINT (2.356515 48.86409)
## 6   6    f POINT (2.299024 48.85176)
## 7   7    g POINT (2.358712 48.85207)
## 8   8    h POINT (2.333936 48.88334)
## 9   9    i POINT (2.352751 48.85758)
## 10 10    j POINT (2.343179 48.87391)
# Interroger un objet sf
# Fonctionne comme pour un data frame pour les différentes variables
# Colonne 'ID'
mes_donnees_SF$ID
##  [1]  1  2  3  4  5  6  7  8  9 10
# Colonne ID, ligne 3
mes_donnees_SF$name[3]
## [1] c
## Levels: a b c d e f g h i j
# Geometries de l'entités 3
mes_donnees_SF$geometry[3]
## Geometry set for 1 feature 
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: 2.318518 ymin: 48.83349 xmax: 2.318518 ymax: 48.83349
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs


Le facteur

Un facteur (factor) est un vecteur contenant uniquement certaines valeurs prédéfinies. Les valeurs pré-définies sont appelées des levels.

my_factor <- sample(x = c("North", "East", "South", "West"), size = 13, replace = TRUE)
my_factor
##  [1] "South" "North" "North" "South" "South" "West"  "North" "North"
##  [9] "West"  "North" "West"  "South" "North"
# Les éléments sont considérés comme caractère
class(my_factor)
## [1] "character"
# Conversion en facteur
my_factor <- factor(my_factor)

# Comment se structure le facteur
str(my_factor)
##  Factor w/ 3 levels "North","South",..: 2 1 1 2 2 3 1 1 3 1 ...
# Interroger les éléments d'un factor -> factor[element]

# levels() permet d'obtenir la liste des valeurs :
levels(my_factor)
## [1] "North" "South" "West"
# Compte du nombre d'éléménts par level
summary(my_factor)
## North South  West 
##     6     4     3
# Elément 8
my_factor[8]
## [1] North
## Levels: North South West
# Elément 7 à 13, avec uniquement les levels présents
my_factor[7:13, drop=TRUE]
## [1] North North West  North West  South North
## Levels: North South West


0.4 Les opérateurs

Arithémtiques

# Addition
5 + 5
## [1] 10
# Soustraction
5 - 5
## [1] 0
# Divivion
5 / 5
## [1] 1
# Multiplication
5 * 5
## [1] 25
# Exposant
5^5
## [1] 3125


Relationel

  <    # inférieur à 
  >    # supérieur à 
  <=   # inférieur ou égal à 
  >=   # supérieur ou égal à 
  ==   # égal 
  !=   # différent 
  %in% # Test de présence entre deux vecteurs
# Exemple
5 == 5
## [1] TRUE
5 != 5
## [1] FALSE
c(1,2,3) %in% c(2,7,5) 
## [1] FALSE  TRUE FALSE


Logique

  !         # Négation
  &, &&     # ET 
  |, ||     # OU inclusif
  xor(,)    # OU exclusif (retournera TRUE si l'une ou l'autre mais pas les deux sont vraies)
  is.na()   # Valeur manquante ?
  is.null() # Valeur Null ?
  is.character() # Caractère ?
  is.numeric() # Numérique ?
# Exemples

# Selection dans un data frame avec plusieus conditions (ET)
mtcars[mtcars$mpg %in% c(21.0,14.3,22.8,19.2) & mtcars$hp != 123 & mtcars$wt >= 3, ]
##                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Duster 360       14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 230         22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Pontiac Firebird 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
# Selection dans un data frame avec plusieus conditions (OU)
mtcars[mtcars$mpg %in% c(21.0,14.3,22.8,19.2) | mtcars$hp != 123 | mtcars$wt >= 3, ]
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
# Test valeurs NA (différent de NA ?) dans la variable mtcars$mpg
!is.na(mtcars$mpg)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [15] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [29] TRUE TRUE TRUE TRUE


0.5 Les packages

R fourni directement un important nombre de fonctions pré-installées, stockées dans ce qui est appelé le R Base Package. Il n’est pas nécessaire de les installer ou de les charger, elles sont imédiatement utilisables. À ce jour, 1211 fonctions sont proposées par le le R-base.

Les fonctions du r-base permettent d’effectuer les manipulations de données les plus classiques. Pour effectuer des traitements plus spécifiques, il est nécessaire d’installer des packages mise à disposition par d’autres utilisateurs sur le CRAN.
Les packages sont des collections de fonctions, associées à de la documentation et parfois même à des données. 13517 packages supplémentaires étaient mis à disposition le 06 déc. 2018 sur le CRAN. Tous les packages disponibles sur The Comprehensive R Archive Network ont été controlés. Leur fonctionnement technique (uniquement) est garanti, car il s’agit d’un depôt officiel de packages.

Il est également possible d’installer des packages en cours de développement et mise à disposition sur un GIT ou d’installer un package stocké en .tar.gz sur votre machine.

Installer un package en language R :

# Pour les packages disponibles sur le CRAN :
install.packages("cartography") # Installer un package
update.packages("cartography")  # Mettre à jour un package

# Pour obtenir le chemin de la librarie contenant les packages installés
.libPaths() 
# Pour voir tous les packages installés
library()   

# Pour les packages stocké en local et compressé en tar.gz. Ex (NOT RUN) :
install.packages("C:\\RJSONIO_0.2-3.tar.gz", repos = NULL, type="source")

# Pour les packages en cours de développement sur un GIT,
# il est nécessaire d'installer et de charger le package devtools :
install.packages("devtools")
library(devtools)
install_github("riatelab/MTA")

Une fois installé, un package doit être chargé à chaque nouvelle session de R pour être utilisé. A un package est systématiquement associé de la documentation permettant de comprendre son contenu et aider à sa prise en main :

# Charger un package pour en utiliser ses fonctions
library("cartography")  

# Utiliser directement une fonction d'un package
cartography::propSymbolsChoroLayer()

# Accèder à la documentation basique des packages
help("cartography") 

# Acceder à la documentation d'une fonction
?mean

# Accèder à une vignette (falcutatif) de package
vignette(topic = "cartography", package = "cartography")

# Accèder à une cheatsheet (falcutatif) de package
vignette(topic = "cheatsheet", package = "cartography") 

# Charger un jeu de données exemple (primitif ou de package)
data(iris)

# Chercher documentation par mot clé
help.search("weighted mean")


Exemple de cheatsheet (antisèche en angalis), avec le package “cartography” :


L’interface RStudio permet également l’installation et le chargement manuel des packages

…et d’accèder à la documentation :

Sur R, il y a souvent plusieurs manière de réaliser une opération. On peut ainsi utiliser plusieurs fonctions ou packages pour aboutir au même résultat. Pour assurer la pérénnité de ses programmes, préferez toujours une fonction issue d’un package de référence. Les packages de référence sont facilement repérables, en fonction du volume de documentation et d’exemples disponibles sur le web.

Par exemple, utilisez de préference les packages produits par RStudio (collection de package tidyverse), qui seront logiquement toujours utilisable sur les prochaine version de l’IDE RStudio et extrêmement bien documentés (une cheatsheet est disponible pour chaque package de la collection tidyverse).


0.6 Espace de travail & sauvegarde

Gérer son espace de travail

list.files() / dir() # Afficher le contenu du repertoire courant

getwd() # Afficher le répertoire de travail actuel
setwd() # Changer le répertoire courant

dir.create()  # Créer un repertoire
file.remove() / unlink() # Supprimer un fichier
file.create() # Créer un fichier 
file.exists() # Tester l'existence d'un fichier
file.rename() # Renommer un fichier
file.append() # Fusionner deux fichiers
file.copy()   # Copier un ficher

save.image()  # Sauvegarder l'espace de travail dans le fichier .RData par défaut

q()           # Quitter R


Sauvegarder et supprimer des objets

ls()    # lister les objets définis dans l'espace de travail actuel
rm()    # Supprimer un objet
rm(list=ls()) # Supprimer tous les objets

save()  # Sauvegarder des objets dans un fichier RData 
load()  # Charger un fichier RData
mon_objet <- c("un", "deux", "trois")

# Sauvegarde de l'objet crée
save(mon_objet, file="Nom_objet_stocké")

# Suppression de l'objet TEMPORAIRE
rm(mon_objet) 

# Chargement de l'objet préalablement enregistré
load("Nom_objet_stocké") 

Toutes ces actions peuvent être réalisées manuellement depuis un explorateur de fichier ou depuis l’interface RStudio.


0.7 Règles de codage

Les règles de codage permettent d’écrire un code plus clair et plus lisible pour soi et pour les autres. Vous pourrez trouver plusieurs propositions de coding style car il n’existe pas de style officiel pour le logiciel R. Quelque soit le style choisi l’idée est de conserver le même tout au long d’un programme.
Voir par exemple :

Troix règles font tout de même l’unanimité :

  • Eviter les lignes de plus de 80 charactères.
  • Utiliser un espace avant et après les opérateurs :
# Préférez
x  <-  12
# à
x<-12

# Préférez
average  <-  mean(feet  /  12 + inches,  na.rm = TRUE)
# à
average<-mean(feet/12+inches,na.rm=TRUE)
  • Eviter les lignes avec plus d’une opération :
### Il est possible d'écrire plusieurs opération sur une me ligne, en les séparant d'un ;
# Exemple
notes <- c(4,2,8,6,5,9,3,2,5,6); mean(notes); sd(notes)

# Mais cela est à proscrire.
# Pour plus de visibilité, préférez :
notes <- c(4,2,8,6,5,9,3,2,5,6)
mean(notes)
sd(notes)


L’intégration de commentaire dans le code est également une pratique apprécié. Pour cela, insérez un # en début de ligne.

# Les caractères suivants seront considérés comme du commentaire
# Vous pouvez écrire ce que vous voulez, mais toujours précédé d'un #


# une chaîne de 5# (#####) permet de créer de bloc de code dépliable :

###### 
mean(c(1,7,3,2,8,9,2,3))


1. Acquisition de données

1.1 Import & téléchargement


Import de données

Il est possible d’importer et d’exporter des données avec R. Pour cela, une série de fonctions (primitives ou non) peut être utilisée. Quelques exemples :

## IMPORTER
read.table()   # Importer une table (format multiple)

# Excel 
read.xlsx()    # Fichier Excel / library(xlsx) 
loadWorkbook() # Fichier Excel / library(XLConnect)
read_excel()   # Fichier Excel / library(readxl)...  Beaucoup de librairies pour Excel

read.csv()   # Fichier csv
read_sas()   # Fichier sas / library(haven)
read.dbf()   # Fichier dbf / library(foreign)
read_sf()    # Fichier shape / library(sf)

Pour réaliser un import correct, il est souvent nécessaire de renseigner un certain nombre d’arguments, comme par exemple :

header = valeur logique qui indique si la première ligne du fichier importé contient les noms des variables.
sep = Indique le séparateur de champ du fichier.
stringsAsFactor = Le données de type caractère sont transformées (par défaut) en facteur.
Encoding = Indique l’encodage utilisé pour les chaînes de caractères.

# Import d'un fichier 
# not run
Mon_Objet <- read.table(file = "/data/user/documents/mes.donnes.csv", 
                        header = TRUE, 
                        sep = ",", 
                        stringsAsFactors = FALSE, 
                        encoding = "UTF-8")


Téléchargement de données

Il est possible de télécharger directement des fichiers quelque soit le format.

# Télécharger un fichier
download.file(url = "https://www.insee.fr/fr/statistiques/fichier/2522602/Fichier_poplegale_6815.xls", 
              destfile = "/data/user/documents/New_name.xls", 
              mode = 'wb')


# Un fois télécharger, un fichier zip peut également être décompressé
unzip(zipfile = "data/mes_donnees.zip", exdir = "data/")


Jeu de données exemple

De nombreux packages mettent à disposition des jeux de données, le plus souvent pour être utilisé comme exemple par les fonctions du package.

# Liste des jeux de données mis à disposition par les packages installés
data(package = .packages(all.available = TRUE))

# Exemple de jeu de données
library(datasets)
data(mtcars)

Mais parfois, il peut s’agir de données intérréssantes :

# Natural Earth = Fond de carte monde
library(rnaturalearthdata)

# UN - World Population Prospects 2017
library(wpp2017)


Packages d’API

Plusieurs packages permettent d’utiliser des API, et ainsi de récuperer des données directement avec R :

# Eurostat
library(eurostat)

# Worls Bank
library(wbstats)
library(WDI)

# Open street map
library(osmdata)

# Twitter
library(twitteR)
library(rtweet)

# Spotify
library(spotifyr)

# Youtube
library(tuber)

# Google...
library(googleAuthR) # Pour s'identifier... parce que c'est google quand même !
library(googleAnalyticsR)
library(googleComputeEngineR)
library(searchConsoleR)
library(bigQueryR)
library(gtmR)
library(googleID)
library(googleCloudStorageR)
library(RoogleVision)


1.2 Collecte sur le web

Au delà des packages permettant l’utilisation d’API existante, et ainsi l’accès direct à des bases de données. Des packages R permettent de webscrapper toute sorte d’information consutable sur le Web. Les deux packages de référence sont :

library(rvest)
library(RSelenium)

De nombeuses ressources (blog, wiki tutoriel…) sont disponibles pour vous aider à utiliser ces packages. Il existe par exemple un wiki assez complet pour le package rvest.


1.3 Interroger ses données

Une fois l’import terminé, plusieurs fonctions permettent de consulter ses données. Cette étape, indispensable avant tout traitement ou analyse, peut également être réalisée depuis l’inteface RStudio.

# Utilisation du jeu de données exemple 'mtcars' (data frame)
mtcars <- mtcars
# Visualiser dans RStudio :
View(mtcars)
# Aperçu rapide dans la console
str(mtcars)
## 'data.frame':    32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
# Premiers éléments (6 par défaut) de l'objet
head(mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
# Derniers éléments (6 par défaut) de l'objet
tail(mtcars,2)
##                mpg cyl disp  hp drat   wt qsec vs am gear carb
## Maserati Bora 15.0   8  301 335 3.54 3.57 14.6  0  1    5    8
## Volvo 142E    21.4   4  121 109 4.11 2.78 18.6  1  1    4    2
# Statistiques de base
summary(mtcars)
##       mpg             cyl             disp             hp       
##  Min.   :10.40   Min.   :4.000   Min.   : 71.1   Min.   : 52.0  
##  1st Qu.:15.43   1st Qu.:4.000   1st Qu.:120.8   1st Qu.: 96.5  
##  Median :19.20   Median :6.000   Median :196.3   Median :123.0  
##  Mean   :20.09   Mean   :6.188   Mean   :230.7   Mean   :146.7  
##  3rd Qu.:22.80   3rd Qu.:8.000   3rd Qu.:326.0   3rd Qu.:180.0  
##  Max.   :33.90   Max.   :8.000   Max.   :472.0   Max.   :335.0  
##       drat             wt             qsec             vs        
##  Min.   :2.760   Min.   :1.513   Min.   :14.50   Min.   :0.0000  
##  1st Qu.:3.080   1st Qu.:2.581   1st Qu.:16.89   1st Qu.:0.0000  
##  Median :3.695   Median :3.325   Median :17.71   Median :0.0000  
##  Mean   :3.597   Mean   :3.217   Mean   :17.85   Mean   :0.4375  
##  3rd Qu.:3.920   3rd Qu.:3.610   3rd Qu.:18.90   3rd Qu.:1.0000  
##  Max.   :4.930   Max.   :5.424   Max.   :22.90   Max.   :1.0000  
##        am              gear            carb      
##  Min.   :0.0000   Min.   :3.000   Min.   :1.000  
##  1st Qu.:0.0000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :0.0000   Median :4.000   Median :2.000  
##  Mean   :0.4062   Mean   :3.688   Mean   :2.812  
##  3rd Qu.:1.0000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :1.0000   Max.   :5.000   Max.   :8.000
# Pour les objets à plusieurs dimensions :
# Nom des colonnes / objets
colnames(mtcars)
##  [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
## [11] "carb"
# Nom des colonnes / objets
names(mtcars)[3]
## [1] "disp"
# Nom des lignes
row.names(mtcars) 
##  [1] "Mazda RX4"           "Mazda RX4 Wag"       "Datsun 710"         
##  [4] "Hornet 4 Drive"      "Hornet Sportabout"   "Valiant"            
##  [7] "Duster 360"          "Merc 240D"           "Merc 230"           
## [10] "Merc 280"            "Merc 280C"           "Merc 450SE"         
## [13] "Merc 450SL"          "Merc 450SLC"         "Cadillac Fleetwood" 
## [16] "Lincoln Continental" "Chrysler Imperial"   "Fiat 128"           
## [19] "Honda Civic"         "Toyota Corolla"      "Toyota Corona"      
## [22] "Dodge Challenger"    "AMC Javelin"         "Camaro Z28"         
## [25] "Pontiac Firebird"    "Fiat X1-9"           "Porsche 914-2"      
## [28] "Lotus Europa"        "Ford Pantera L"      "Ferrari Dino"       
## [31] "Maserati Bora"       "Volvo 142E"
# Dimensiomtcarsn de l'objet
dim(mtcars)
## [1] 32 11
# Nombre de colonne
ncol(mtcars)
## [1] 11
# Nombre de ligne
nrow(mtcars)
## [1] 32
# Longueur, nombre d'éléments de l'objet
length(mtcars)
## [1] 11
# Nombre d'éléments de la première colonne
length(mtcars[,1])
## [1] 32


Depuis l’interface RStudio…


Classe de données

Les objets peuvent stocker des types de données très différents. Quelques classes de données existantes sous R :

  • La chaine de caractères
# as.character permet d'assigner la classe integer à une valeur
a <- as.character("Chaîne de caractères")

class(a)
## [1] "character"
  • Nombre entier (integer)
a <- as.integer(347)

class(a)
## [1] "integer"
  • Nombre réel (real or decimal)
a <- as.numeric(86.3)

# Test - a est elle numérique ?
is.numeric(a)
## [1] TRUE
  • Valeur logique (logical or boolean)
a <- as.logical(c(TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE))
# ou
a <- as.logical(c(1,0,1,1,1,1,0))

a
## [1]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
  • Date
ma_date <- as.Date("2007-06-22")
ma_date 
## [1] "2007-06-22"
class(ma_date )
## [1] "Date"
# Les dates sont stockées en nombre. Il s'agit du nombre de jours depuis le 01-01-1970
as.numeric(ma_date)
## [1] 13686
# calcul temporel
as.Date("2007-06-22") - as.Date("1970-02-01")
## Time difference of 13655 days


> Exemple

Téléchargez ce projet R qui contient des données et un script R prêt à être éxécuté. Dézippez le dossier, puis ouvrez le projet RUSS_running_example.Rproj. Vous y trouverez un script R qui regroupe tous les exemples de code présentés pour chaque étape de la chaîne de traitement.

ÉTAPE 1 : Import et de consultation de données sous R :

######################################################
# INED - 6 DECEMBRE 2018 - SEMINAIRE RUSS
# RUNNING EXAMPLE
# R. YSEBAERT (UMS RIATE), HUGUES PECOUT (FR CIST)
######################################################

#####################################
# Packages nécessaires
#####################################

# Ces packages sont à installer (une seule fois) pour exécuter le programme ci-dessous

#install.packages("readxl")
#install.packages("sf")
#install.packages("stringr")
#install.packages("ggplot2")
#install.packages("ggthemes")
#install.packages("dplyr")
#install.packages("reshape2")
#install.packages("questionr")


###############################
# Démo 1 - Import des données
###############################

# Importer à partir d'un fichier Excel (INSEE) 
library(readxl)
data2015 <- data.frame(read_excel("data/Fichier_poplegale_6815.xlsx", skip = 7, sheet = "2015")) 
data1990 <- data.frame(read_excel("data/Fichier_poplegale_6815.xlsx", skip = 7, sheet = "1990")) 
data1975 <- data.frame(read_excel("data/Fichier_poplegale_6815.xlsx", skip = 7, sheet = "1975")) 

# Importer des géométries communales (IGN - Geofla 2016)
library(sf)
communes <- st_read(dsn = "data/COMMUNE.shp", stringsAsFactors = F)

# Importer l'appartenance intercommunale des communes de la Métropole du Grand Paris
EPT <- read.csv(file = "data/EPT.csv", sep = ",", stringsAsFactors = F )
EPT$INSEE_COM <- as.character(EPT$INSEE_COM)

# Quels objets ?
str(data2015)
str(communes)
str(EPT)

# Visualisation des premières lignes
head(communes)
head(data2015)
head(data1990)
head(data1975)
head(EPT)


2. Gestion & traitement

2.1 Gestion de vecteur

x <- c("A","E","N","E","E","E","A","A","N")
# Trier un vecteur
sort(x)
## [1] "A" "A" "A" "E" "E" "E" "E" "N" "N"
# Inverser un vecteur
rev(x)
## [1] "N" "A" "A" "E" "E" "E" "N" "E" "A"
# table de contingence
table(x)
## x
## A E N 
## 3 4 2
# Valeurs unique d'un vecteur
unique(x)
## [1] "A" "E" "N"


2.1 Séléctionner & trier

Sélectionner

# Methode 1 
mtcars[mtcars$cyl==4 & mtcars$wt > 3,  c(1:7) ]
##            mpg cyl  disp hp drat   wt qsec
## Merc 240D 24.4   4 146.7 62 3.69 3.19 20.0
## Merc 230  22.8   4 140.8 95 3.92 3.15 22.9
# Methode 2, fonction subset
subset(mtcars, cyl==4 & mtcars$wt > 3, select=c(1:7))
##            mpg cyl  disp hp drat   wt qsec
## Merc 240D 24.4   4 146.7 62 3.69 3.19 20.0
## Merc 230  22.8   4 140.8 95 3.92 3.15 22.9
# Methode 3, fonction filter() du package 'dplyr'
library(dplyr)
mtcars %>% 
  select(1:7) %>%
  filter(cyl==4, wt > 3)
##    mpg cyl  disp hp drat   wt qsec
## 1 24.4   4 146.7 62 3.69 3.19 20.0
## 2 22.8   4 140.8 95 3.92 3.15 22.9

Trier

# Fonction order()
order_mtcars <- mtcars[order(mtcars$cyl, -mtcars$disp, mtcars$carb, decreasing = TRUE), ]
head(order_mtcars)
##                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Merc 450SE       16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL       17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC      15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Maserati Bora    15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## AMC Javelin      15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Dodge Challenger 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2


2.2 Regrouper

Comme pour beaucoup de manipulation sous R, il existe plusieurs façon pour regrouper des éléments. Ci dessous, deux exemple de regroupement, avec calcul d’une somme :

# METHODE 1 -> Fonction primitive aggregate(), fonction applicable sur une seule variable
aggregate(data = mtcars, disp ~ cyl + vs, sum)
##   cyl vs   disp
## 1   4  0  120.3
## 2   6  0  465.0
## 3   8  0 4943.4
## 4   4  1 1036.2
## 5   6  1  818.2
# METHODE 2 -> Fonction du package dpkyr
library(dplyr)
mtcars %>% group_by(cyl, vs) %>% summarise(sum_disp=sum(disp), moy_hp=mean(hp), nb_element=length(cyl) )
## # A tibble: 5 x 5
## # Groups:   cyl [?]
##     cyl    vs sum_disp moy_hp nb_element
##   <dbl> <dbl>    <dbl>  <dbl>      <int>
## 1     4     0     120.   91            1
## 2     4     1    1036.   81.8         10
## 3     6     0     465   132.           3
## 4     6     1     818.  115.           4
## 5     8     0    4943.  209.          14


2.3 Chaîne de caractères

Concaténer une chaîne de caractères :

# Concaténation de chaîne de caractère, AVEC séparateur
paste("Champions", "du", "monde", sep=" ")
## [1] "Champions du monde"
# Concaténation de chaîne de caractère, SANS séparateur
paste0("Champions", "du", "monde")
## [1] "Championsdumonde"

Gérer la casse :

text <- "champion Du MONDEEEEEE !"

# tout minuscule
tolower(text)
## [1] "champion du mondeeeeee !"
# tout majuscule
toupper(text)
## [1] "CHAMPION DU MONDEEEEEE !"

Interroger une chaîne de caractères :

# Nombre de caractères
nchar(text)
## [1] 24
# Rechercher un/des caractère(s) avec grepl()
# TRUE ou FALSE
grepl(pattern = "E" , text)
## [1] TRUE

Le package stringr propose de nombreuses fonctions trés pratiques. Il s’agit du package de référence pour la gestion de chaîne de caractère.

library(stringr)

# Rechercher un/des caractère(s)
str_detect(text,  "E")
## [1] TRUE
# Position de la première occurrence d'une chaine de caractère
str_locate(text, "pi")
##      start end
## [1,]     5   6
# Toutes les position du caractère recherché
str_locate_all(text, "E")
## [[1]]
##      start end
## [1,]    17  17
## [2,]    18  18
## [3,]    19  19
## [4,]    20  20
## [5,]    21  21
## [6,]    22  22

Modifier une chaîne de caractères :

text <- "Champions du monde"

# Scinder une chaîne de caractère
strsplit(text, split = " ", fixed = TRUE)
## [[1]]
## [1] "Champions" "du"        "monde"
# Remplacer la première occurence d'une chaîne de caractère
sub("o", "___", text)
## [1] "Champi___ns du monde"
# Remplacer un ou une chaîne de caractère
gsub("o", "___", text)
## [1] "Champi___ns du m___nde"
# Autre fonction de remplacement
chartr(text, old = "mn", new = "XY") 
## [1] "ChaXpioYs du XoYde"
library(stringr)
# Extraire un segment de chaîne de caractère
str_sub(text,  5, 9)
## [1] "pions"
library(stringr)
# Remplacer un segment de chaîne de caractère par un autre
str_sub(text,  5, 9) <-"pionnes"
text
## [1] "Championnes du monde"
library(stringr)
# Suppression d'espace en début et fin de chaîne de caractère
str_trim("  abc   ")
## [1] "abc"


2.4 Transformer

# Construction data frame
mydata <- data.frame(id=c(1,1,2,2),time=c(1,2,1,2), 
                     x1=c(5,3,6,2), x2=c(6,5,1,4))
mydata
##   id time x1 x2
## 1  1    1  5  6
## 2  1    2  3  5
## 3  2    1  6  1
## 4  2    2  2  4
# Transposition de la table
t(mydata)
##      [,1] [,2] [,3] [,4]
## id      1    1    2    2
## time    1    2    1    2
## x1      5    3    6    2
## x2      6    5    1    4


Le package reshape2 contient plusieurs fonctions de remodelage de table :

library(reshape2)

# Fonction melt() 
mydata_melt <-melt(mydata, id=c("id","time"))
mydata_melt
##   id time variable value
## 1  1    1       x1     5
## 2  1    2       x1     3
## 3  2    1       x1     6
## 4  2    2       x1     2
## 5  1    1       x2     6
## 6  1    2       x2     5
## 7  2    1       x2     1
## 8  2    2       x2     4
#  fonction dcast(data, formula, function) - s'applique sur des 'melted data'
mydata_melt_cast <- dcast(mydata_melt, id~variable, mean)
mydata_melt_cast 
##   id x1  x2
## 1  1  4 5.5
## 2  2  4 2.5


Il est aussi possible d’utiliser des fonctions du package tidyr.

2.5 Joindre et fusionner

Pour joindre ou fusionner des tables de données :

# Construction de deux dataframe avec un identifiant commun
ID <- as.character(c(1, 2, 3, 4))
Prenom <- c('John','Peter','Jolie','John')
Nom <- c('Doe','Gynn','Hope','snow')

# Dataframe 1
mon_tab_1 <- data.frame(ID, Prenom)

# Dataframe 2
mon_tab_2 <- data.frame(ID, Nom)

# Jointure des deux objets avec la fonction merge()
merge(mon_tab_1, mon_tab_2)
##   ID Prenom  Nom
## 1  1   John  Doe
## 2  2  Peter Gynn
## 3  3  Jolie Hope
## 4  4   John snow
# si les clefs de jointure ont des noms différents :
merge(mon_tab_1, mon_tab_2, by.x="ID", by.y="ID")
##   ID Prenom  Nom
## 1  1   John  Doe
## 2  2  Peter Gynn
## 3  3  Jolie Hope
## 4  4   John snow
# Combiner deux objets par les colonnes
# Les deux dataframe doivent avoir le même nombre de lignes :
cbind(mon_tab_1,mon_tab_2)
##   ID Prenom ID  Nom
## 1  1   John  1  Doe
## 2  2  Peter  2 Gynn
## 3  3  Jolie  3 Hope
## 4  4   John  4 snow
# Combiner deux objets par les lignes
# Les deux data frame doivent avoir les mêmes noms de colonnes :
colnames(mon_tab_1) <- colnames(mon_tab_2)
rbind(mon_tab_1,mon_tab_2)
##   ID   Nom
## 1  1  John
## 2  2 Peter
## 3  3 Jolie
## 4  4  John
## 5  1   Doe
## 6  2  Gynn
## 7  3  Hope
## 8  4  snow


2.6 Boucle itérative

Une boucle est une série d’instructions exécutées jusqu’à ce qu’un résultat particulier soit obtenu ou qu’une condition pré-déterminée soit remplie. Les boucles permettent de ré-utiliser des séries d’instructions et permettent ainsi de limiter le nombre d’instructions.

# Structure d'une boucle
for (variable in vecteur) {
  instruction
}
# Exemple
for (i in 1:5) {
  print(paste0("Passage n°", i))
}
## [1] "Passage n°1"
## [1] "Passage n°2"
## [1] "Passage n°3"
## [1] "Passage n°4"
## [1] "Passage n°5"


2.7 Fonctions apply

L’utilisation d’une boucle est très fréquente en traitement de données. Celle-ci sert généralement à effectuer de traitements sur des objets de structure multidimensionnelle (data frame, matrice, array, sf…). Dans ca cas, la boucle for n’est pas la technique otpimale. Les concepteurs de R ont développé des fonctions spécialement prévues à cet effet.

# Appliquer une fonction sur les lignes :
apply(mtcars,1,mean)
##           Mazda RX4       Mazda RX4 Wag          Datsun 710 
##            29.90727            29.98136            23.59818 
##      Hornet 4 Drive   Hornet Sportabout             Valiant 
##            38.73955            53.66455            35.04909 
##          Duster 360           Merc 240D            Merc 230 
##            59.72000            24.63455            27.23364 
##            Merc 280           Merc 280C          Merc 450SE 
##            31.86000            31.78727            46.43091 
##          Merc 450SL         Merc 450SLC  Cadillac Fleetwood 
##            46.50000            46.35000            66.23273 
## Lincoln Continental   Chrysler Imperial            Fiat 128 
##            66.05855            65.97227            19.44091 
##         Honda Civic      Toyota Corolla       Toyota Corona 
##            17.74227            18.81409            24.88864 
##    Dodge Challenger         AMC Javelin          Camaro Z28 
##            47.24091            46.00773            58.75273 
##    Pontiac Firebird           Fiat X1-9       Porsche 914-2 
##            57.37955            18.92864            24.77909 
##        Lotus Europa      Ford Pantera L        Ferrari Dino 
##            24.88027            60.97182            34.50818 
##       Maserati Bora          Volvo 142E 
##            63.15545            26.26273
# Appliquer une fonction sur les colonnes :
apply(mtcars,2,sum)
##      mpg      cyl     disp       hp     drat       wt     qsec       vs 
##  642.900  198.000 7383.100 4694.000  115.090  102.952  571.160   14.000 
##       am     gear     carb 
##   13.000  118.000   90.000
# Appliquer une fonction sur chaque items (sortie vector) :
sapply(mtcars$mpg, function(x) x/100)
##  [1] 0.210 0.210 0.228 0.214 0.187 0.181 0.143 0.244 0.228 0.192 0.178
## [12] 0.164 0.173 0.152 0.104 0.104 0.147 0.324 0.304 0.339 0.215 0.155
## [23] 0.152 0.133 0.192 0.273 0.260 0.304 0.158 0.197 0.150 0.214
# Appliquer une fonction sur chaque items (sortie list)
Resultat_lapply <- lapply(mtcars$mpg, function(x) x/100)
Resultat_lapply[1:5]
## [[1]]
## [1] 0.21
## 
## [[2]]
## [1] 0.21
## 
## [[3]]
## [1] 0.228
## 
## [[4]]
## [1] 0.214
## 
## [[5]]
## [1] 0.187


2.8 Test conditionnel

Un test conditionnel permet d’exécuter une portion de code qui effectue différents calculs ou actions, en fonction de l’évaluation d’une condition booléenne, à savoir vraie ou fausse.

# Test simple
if (condition){action}

# Test avec deux solutions
if (condition){
  action1
} else {
  action2
}
# Exemple
x <- "chaîneDeCaractères"
x <- TRUE
x <- 12

if (is.character(x)){
  
  print("x est une chaîne de caractères")
  
} else {
  
  if (is.numeric(x)) {
    
    print("x est numéric") 
    
  } else {
    
    print("x est bizarre !")
    
  }
}
## [1] "x est numéric"

Il existe également une fonction primitive pour réaliser un test conditionnel:

# Création d'un vecteur de chiffre positifs et négatifs
x <- c(-22,9,-4,10,-13,5,7)

# Fonction ifelse()
ifelse(test = (x >= 0), yes = "Positif", no = "Négatif")
## [1] "Négatif" "Positif" "Négatif" "Positif" "Négatif" "Positif" "Positif"


2.9 Modification manuelle

CECI EST UNE TRÉS MAUVAISE PRATIQUE QUE NOUS DÉCONSEILLONS !

La fonction edit() permet d’éditer un objet et d’en modifier manuellement ses valeurs. Il s’agit d’une fonction à éviter pour différentes raisons, mais qui peut s’avèrer salvatrice pour un utilisateur débutant…

my_dataframe <- mtcars

# Fonction edit()
# Pour que les modifications soient enregistrées,
# Il est nécéssaire d'assigner le résultat dans un objet
my_dataframe <- edit(my_dataframe)

L’éxexcution de la fonction génère l’ouverture d’une fenêtre dans laquelle les valeurs de l’objet sont affichées et peuvent être modifiées manuellement.

Une fois la modification effectuée, cliquer sur une autre cellule puis fermer la fenêtre.


> Exemple

ÉTAPE 2 : Gestion et traitement de données sous R :
Retrouvez ce bout de code dans le projet RUSS_running_example.Rproj téléchargeable ici.

####################################
# Démo 2 - Manipulation de données
####################################

# Jointure : On regroupe les objets data2015, data1990 et data1975 en un seul objet "data"
data <- merge(data2015, data1990, by.x = "COM", by.y = "COM", all.x = T)
data <- merge(data, data1975, by.x = "COM", by.y = "COM", all.x = T) 
head(data)

# Jointure 2 : On regroupe avec les Etablissements publics territoriaux d'appartenance
data <- merge(data, EPT, by.x = "COM", by.y = "INSEE_COM", all.y = T)
head(data)

# Jointure 3 : On ne conserve que les communes de la MGP
communes <- merge(communes, EPT, by.x = "INSEE_COM", by.y = "INSEE_COM", all.y = T)
plot(communes)
plot(st_geometry(communes), col = "black", border = "white")

# Supprimer les objets inutiles (pas obligatoire mais permet d'y voir plus clair... 
# Dans les faits on réalise plutôt cette opération à la fin du programme)
rm(data1975,data1990,data2015,EPT)

# Conserver uniquement certaines variables et les renommer
fields <- c("COM", "NCC.x", "PSDC75", "PSDC90", "PMUN15", "EPT", "EPT_Nom")
data <- data[,fields]
colnames(data) <- c("COM","Nom","POP_1975","POP_1990","POP_2015", "EPT", "EPT_Nom")
head(data)

# Créer de nouveaux indicateurs à partir de variables pré-existantes
# Variable quantitative : taux de croissance moyens annuels 1975-1990, 1990-2015 et 1990-2015
data$acc_7590 <- 100 * (exp(log(data$POP_1990 / data$POP_1975) / (1990 - 1975))-1)
data$acc_9015 <- 100 * (exp(log(data$POP_2015 / data$POP_1990) / (2015 - 1990))-1)
data$acc_7515 <- 100 * (exp(log(data$POP_2015 / data$POP_1975) / (2015 - 1975))-1)
head(data)
# Variable qualitative : un petit test conditionnel (quelles communes sont en croissance démographique ?)
data$typo9015 <- ifelse(data$acc_9015 >= 0 & data$acc_9015 < 1, "POP+ (0-1%)",
                        ifelse(data$acc_9015 > 1, "POP++ (+1%)",
                               "POP- (<0%)"))
head(data)

# Extraite une chaine de caractère : département d'appartenance de chaque commune ? 
library(stringr)
data$DEP <- str_sub(data$COM,  1, 2)
head(data)


# Et si on aggrégeait le fond communal en EPT ? 
library(dplyr)

head(communes)
agg <- communes %>% group_by(EPT) %>% summarize(names = first(EPT_Nom))
par(mar = c(0.5,0.5,1.5,0.5)) # Ajuster les marges
plot(st_geometry(communes), col = "white", border = "black") # Le fond communal
plot(st_geometry(agg), col = NA, border = "red", add = T, lwd = 2) # Les EPT de la métro du Grand Paris

head(data)
head(communes)
head(agg)


3. Analyse

3.1 Statistique univariée et bivariée

Pour pratiquer de la statistique basique, R met à disposition toutes les fonctions basiques nécessaires.

Pour les variable quantitatives :
Quelques fonctions mathématiques standards :

# Création de deux vecteurs
x <- c(3, 13, 6, 7, 9.45654, 3, 8, 10, 1, 6, 11, 12.001, 2.1, 5)
y <- c(8, 26.78, 16, 12, 21.35, 6, 12.85, 14, 4, 12, 15, 14.7, 5.4, 9)

# Minimum
min(x)
## [1] 1
# Maximum
max(x)
## [1] 13
# Somme
sum(x)
## [1] 96.55754
# Moyenne
mean(x)
## [1] 6.896967
# Médiane
median(x)
## [1] 6.5
# Ecart-type
sd(x)
## [1] 3.832111
# Quantile
quantile(x)
##        0%       25%       50%       75%      100% 
##  1.000000  3.500000  6.500000  9.864135 13.000000
# min, max, médianne et quartile
summary(x)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   3.500   6.500   6.897   9.864  13.000
# Rang des éléments
rank(x)
##  [1]  3.5 14.0  6.5  8.0 10.0  3.5  9.0 11.0  1.0  6.5 12.0 13.0  2.0  5.0
# Variance
var(x)
## [1] 14.68507
# Coefficient de corrélation
cor(x, y)
## [1] 0.8603352
# Modèle linéaire 
lm(x ~ y) 
## 
## Call:
## lm(formula = x ~ y)
## 
## Coefficients:
## (Intercept)            y  
##      0.2099       0.5287
# Modèle linéaire généralisé
glm(x ~ y)
## 
## Call:  glm(formula = x ~ y)
## 
## Coefficients:
## (Intercept)            y  
##      0.2099       0.5287  
## 
## Degrees of Freedom: 13 Total (i.e. Null);  12 Residual
## Null Deviance:       190.9 
## Residual Deviance: 49.6  AIC: 63.44
# Pour plus d'information, à utiliser avec la fonction summary()
summary(glm(x ~ y))
## 
## Call:
## glm(formula = x ~ y)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.6688  -1.3571  -0.4680   0.8589   4.0195  
## 
## Coefficients:
##             Estimate Std. Error t value  Pr(>|t|)    
## (Intercept)  0.20991    1.26622   0.166     0.871    
## y            0.52868    0.09042   5.847 0.0000788 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for gaussian family taken to be 4.133484)
## 
##     Null deviance: 190.906  on 13  degrees of freedom
## Residual deviance:  49.602  on 12  degrees of freedom
## AIC: 63.44
## 
## Number of Fisher Scoring iterations: 2
# Logarithme naturel
log(x)
##  [1] 1.0986123 2.5649494 1.7917595 1.9459101 2.2467066 1.0986123 2.0794415
##  [8] 2.3025851 0.0000000 1.7917595 2.3978953 2.4849900 0.7419373 1.6094379
# exponentiel
exp(x)
##  [1]     20.085537 442413.392009    403.428793   1096.633158  12791.549032
##  [6]     20.085537   2980.957987  22026.465795      2.718282    403.428793
## [11]  59874.141715 162917.627615      8.166170    148.413159
# Arrondir une valeur (ex : 2 nombres après la virgule) :
round(x, 1)
##  [1]  3.0 13.0  6.0  7.0  9.5  3.0  8.0 10.0  1.0  6.0 11.0 12.0  2.1  5.0
# Discrétiser une variable
cut(x, c(0,3,6,9,11,14))
##  [1] (0,3]   (11,14] (3,6]   (6,9]   (9,11]  (0,3]   (6,9]   (9,11] 
##  [9] (0,3]   (3,6]   (9,11]  (11,14] (0,3]   (3,6]  
## Levels: (0,3] (3,6] (6,9] (9,11] (11,14]

Quelques fonctions de test statistique :

# Test de corrélation
cor.test(x,y)
## 
##  Pearson's product-moment correlation
## 
## data:  x and y
## t = 5.8468, df = 12, p-value = 0.00007877
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.6066998 0.9549862
## sample estimates:
##       cor 
## 0.8603352
# test for equality of proportions without continuity correction
prop.test(x, y) 
## 
##  14-sample test for equality of proportions without continuity
##  correction
## 
## data:  x out of y
## X-squared = 14.677, df = 13, p-value = 0.328
## alternative hypothesis: two.sided
## sample estimates:
##    prop 1    prop 2    prop 3    prop 4    prop 5    prop 6    prop 7 
## 0.3750000 0.4854369 0.3750000 0.5833333 0.4429293 0.5000000 0.6225681 
##    prop 8    prop 9   prop 10   prop 11   prop 12   prop 13   prop 14 
## 0.7142857 0.2500000 0.5000000 0.7333333 0.8163946 0.3888889 0.5555556
# Test for a difference between proportions.
t.test(x, y) 
## 
##  Welch Two Sample t-test
## 
## data:  x and y
## t = -2.9402, df = 21.593, p-value = 0.007669
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -9.812949 -1.690260
## sample estimates:
## mean of x mean of y 
##  6.896967 12.648571
# Preform a t-test for  paired data
pairwise.t.test(x, y) 
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  x and y 
## 
##       4 5.4 6 8 9 12 12.85 14 14.7 15 16 21.35
## 5.4   - -   - - - -  -     -  -    -  -  -    
## 6     - -   - - - -  -     -  -    -  -  -    
## 8     - -   - - - -  -     -  -    -  -  -    
## 9     - -   - - - -  -     -  -    -  -  -    
## 12    - -   - - - -  -     -  -    -  -  -    
## 12.85 - -   - - - -  -     -  -    -  -  -    
## 14    - -   - - - -  -     -  -    -  -  -    
## 14.7  - -   - - - -  -     -  -    -  -  -    
## 15    - -   - - - -  -     -  -    -  -  -    
## 16    - -   - - - -  -     -  -    -  -  -    
## 21.35 - -   - - - -  -     -  -    -  -  -    
## 26.78 - -   - - - -  -     -  -    -  -  -    
## 
## P value adjustment method: holm
# Analyse de la variance
aov(x ~ y) 
## Call:
##    aov(formula = x ~ y)
## 
## Terms:
##                         y Residuals
## Sum of Squares  141.30416  49.60181
## Deg. of Freedom         1        12
## 
## Residual standard error: 2.033097
## Estimated effects may be unbalanced

Quelques fonctions très utiles pour visualiser des données :

# Histogramme de distribution d'une variable + mean
hist(x,  breaks = seq(0,16,2))
# Ajout moyenne
abline(v=mean(x), col="red", lwd=1 , lty=2, add=T)
# Autre éléments...
rug(x, col="blue")

# Graphique simple + régréssion linéaire 
plot(x,y)
abline(lm(y ~ x), col="red", lwd=2)

# Boite à moustache
# boxplot(x)
boxplot(x,
        main = "Distribution de ma variable",
        xlab = "x",
        col = "orange",
        border = "brown",
        horizontal = TRUE)

Pour les variables qualitatives :
LA fonction indispensable pour les variables qualitatives :

# Utilisation d'un jeu de données exemple proposées par le package 'questionr'
library(questionr)
data(hdv2003)

# Table de contingence :
# 1 variable
table(hdv2003$sexe)
## 
## Homme Femme 
##   899  1101
# 2 variables
table(hdv2003$sport,hdv2003$sexe)
##      
##       Homme Femme
##   Non   530   747
##   Oui   369   354
# Ou plus...
table(hdv2003$sport, hdv2003$cuisine, hdv2003$sexe)
## , ,  = Homme
## 
##      
##       Non Oui
##   Non 401 129
##   Oui 228 141
## 
## , ,  = Femme
## 
##      
##       Non Oui
##   Non 358 389
##   Oui 132 222
# Calculer les proportions, utilisation de fonction de la library questionr()
ma_table <- table(hdv2003$sport,hdv2003$sexe)
prop.table(ma_table)
##      
##        Homme  Femme
##   Non 0.2650 0.3735
##   Oui 0.1845 0.1770

Réaliser un test du chi2 :

# Table de contingence
ma_table <- table(hdv2003$sport, hdv2003$qualif)

# test chi2
tab.chi2 <- chisq.test(ma_table)
tab.chi2
## 
##  Pearson's Chi-squared test
## 
## data:  ma_table
## X-squared = 100.27, df = 6, p-value < 2.2e-16
# effectifs observés
tab.chi2$observed
##      
##       Ouvrier specialise Ouvrier qualifie Technicien
##   Non                166              215         44
##   Oui                 37               77         42
##      
##       Profession intermediaire Cadre Employe Autre
##   Non                       83   117     401    38
##   Oui                       77   143     193    20
# effectifs théoriques
tab.chi2$expected
##      
##       Ouvrier specialise Ouvrier qualifie Technicien
##   Non          130.66667          187.954   55.35632
##   Oui           72.33333          104.046   30.64368
##      
##       Profession intermediaire     Cadre  Employe    Autre
##   Non                102.98851 167.35632 382.3448 37.33333
##   Oui                 57.01149  92.64368 211.6552 20.66667
# résidus
tab.chi2$residuals
##      
##       Ouvrier specialise Ouvrier qualifie Technicien
##   Non          3.0910228        1.9727718 -1.5263498
##   Oui         -4.1544675       -2.6514902  2.0514798
##      
##       Profession intermediaire      Cadre    Employe      Autre
##   Non               -1.9696359 -3.8925387  0.9540511  0.1091089
##   Oui                2.6472754  5.2317394 -1.2822858 -0.1466471

Visualiser des données qualitatives :

# barplot(ma_table)
barplot(ma_table, 
        las=2, 
        cex.names=0.8,
        col=c("red4","darkblue"))
# Ajout legend
legend("topleft", legend = c("Non", "Oui"), fill =c("red4","darkblue"))

# Fonction mosaicplot()
mosaicplot(ma_table, shade = TRUE, main = "Graphe en mosaïque", cex=0.6)


3.2 Statistique multivariée

Variables quantitatives :

### Analyse en Composante Principale (ACP)

# fonction de base
prcomp()
princomp()

# Packages
library(FactoMineR) - PCA()
library(ade4) - dudi.pca()
library(ExPosition) - epPCA()

Variables qualitatives :

### Analyse Factorielle des Correspondances (AFC)
### Analyse des Correspondances Multiples (ACM)
library(FactoMineR) - CA() / MCA()
library(ade4) - dudi.coa() / dudi.acm()
library(MASS) - corresp() / mva()
library(ExPosition) - epCA() /  epMCA()

Variables qualitatives et quantitatives :

### Analyse Factorielle Multiple (AFM)
library(FactoMineR)
library(ade4) 

Peu importe la fonction que vous décidez d’utiliser, vous pouvez facilement extraire et visualiser les résultats d’une ACP, AFC ou ACM avec la librairie factoextra. Vous trouverez des exemples trés complets d’utilisation sur ce site.

Réaliser des classifications, à l’aide de fonctions basiques :

### Classification par la méthode des nuées dynamiques (k-means)
# Fonction primitive : kmeans()
kmeans_3class <- kmeans(mtcars[, c(1,7)], centers=3)

# Représentation graphique
plot(mtcars$mpg, mtcars$qsec, col=kmeans_3class$cluster, pch=20)

### Classification Ascendante Hiérarchique (CAH)
# Fonction primitive : hclust()

# Exemple
# Création d'une matrice de distance avec la fonction dist()
mat_dist <- dist(mtcars[, c(1,7)], method = "euclidean", diag = FALSE, upper = FALSE, p = 2)
# CAH
clusters <- hclust(mat_dist)
clusters
## 
## Call:
## hclust(d = mat_dist)
## 
## Cluster method   : complete 
## Distance         : euclidean 
## Number of objects: 32
# Affichage graphique de l'arbre
plot(clusters)

# Choix du nombre de classes
clusterCut <- cutree(clusters, 3)
clusterCut
##           Mazda RX4       Mazda RX4 Wag          Datsun 710 
##                   1                   1                   2 
##      Hornet 4 Drive   Hornet Sportabout             Valiant 
##                   2                   1                   1 
##          Duster 360           Merc 240D            Merc 230 
##                   1                   2                   2 
##            Merc 280           Merc 280C          Merc 450SE 
##                   1                   1                   1 
##          Merc 450SL         Merc 450SLC  Cadillac Fleetwood 
##                   1                   1                   1 
## Lincoln Continental   Chrysler Imperial            Fiat 128 
##                   1                   1                   3 
##         Honda Civic      Toyota Corolla       Toyota Corona 
##                   3                   3                   2 
##    Dodge Challenger         AMC Javelin          Camaro Z28 
##                   1                   1                   1 
##    Pontiac Firebird           Fiat X1-9       Porsche 914-2 
##                   1                   2                   2 
##        Lotus Europa      Ford Pantera L        Ferrari Dino 
##                   3                   1                   1 
##       Maserati Bora          Volvo 142E 
##                   1                   2
# Représentation graphique
library(ggplot2)
plot(mtcars$mpg, mtcars$qsec, col=clusterCut, pch=20)

3.3 Traitement d’enquête

Les libraries survey et questionr permettent de gérer et d’analyser facilement des données issues d’enquête.

Librarie questionr :

library(questionr)
data(happy)

### Moyenne & variance pondérée
wtd.mean(happy$age, weights = happy$wtssall)
## [1] 44.11619
wtd.var(happy$age, weights = happy$wtssall)
## [1] 287.6387
### Tableau de contigence pondéré
# Arguments possible importants :
# na.rm : Prendre en compte les valeurs manquantes ?
# normwt : Normaliser les poids pour que effectifs pondérés = effectifs initiaux ?
wtd.table(happy$sex, weights = happy$wtssall)
##     male   female 
## 23305.33 27714.66
wtd.table(happy$sex, happy$degree, weights = happy$wtssall)
##        lt high school high school junior college  bachelor  graduate
## male         5337.846   11675.107       1114.496  3349.283  1746.676
## female       6175.978   15149.942       1498.066  3457.830  1353.974

Ces fonctions rendent possibles l’utilisation de la statistique descriptive et le traitement des tableaux croisés (les fonctions lprop(), cprop() ou chisq.test() peuvent être appliquées au résultat d’un wtd.table()) mais restent limitées en termes de tests statistiques ou de graphiques…

librairie survey :

library(survey)
data(api)
mon_enquete <- apiclus1
# Création objet avec plan d'échantillonage
mon_enquete_dw <- svydesign(ids = ~1, data = mon_enquete, weights = ~mon_enquete$pw)
mon_enquete_dw
## Independent Sampling design (with replacement)
## svydesign(ids = ~1, data = mon_enquete, weights = ~mon_enquete$pw)
# Les données brutes sont toujours accessibles dans le nouvel objet créé
str(mon_enquete$stype)
##  Factor w/ 3 levels "E","H","M": 2 1 1 1 1 1 1 1 1 3 ...
str(mon_enquete_dw$variables$stype)
##  Factor w/ 3 levels "E","H","M": 2 1 1 1 1 1 1 1 1 3 ...

Une fois le plan d’échantillonnage déclaré, vous pouvez lui appliquer un certain nombre de fonctions qui prendra en compte la pondération. Exemple:

# svymean, svyvar, svytotal, svyquantile : statistiques univariées (moyenne, variance, total, quantiles)
# svytable : tri à plat et tableau croisé
# svychisq : test du χ²
# svyby : statistiques selon un facteur
# svyttest : test t de Student de comparaison de moyennes
# svyciprop : intervalle de confiance d’une proportion
# svyglm : modèles linéaires généralisés (dont régression logistique)
# svyplot, svyhist, svyboxplot : fonctions graphiques

### Exemple : Fonctions pour représenter les données :
# Histogramme de distribution
svyhist(~target, mon_enquete_dw, col = "red", main = "Histogramme")

# Boite à moustache
svyboxplot(target ~ 1, mon_enquete_dw, main = "Boxplot simple", ylab = "target")

# Croiser deux variables
svyplot(~stype + target, mon_enquete_dw, col = "red", main = "Simple plot")

3.4 Analyse textuelle

De nombreuses librairies permettent l’analyse textuelle.
Certaines proposent une interface graphique qui facilite les traitements :

# Iramuteq est une interface du logiciel R
# Le logiciel R est donc indispensable à son fonctionnement
library(IRaMuTeQ)

# Il existe également R.temis, qui propose une fenêtre graphique
library(R.temis)
# Pour l'interface graphique :
library(RcmdrPlugin.temis)

Fenêtre graphique au chargement de la libraririe RcmdrPlugin.temis


Trois packages semblent se démarquer dans les communautés spècialistes de l’analyse textuelle : tidytext, tm et quanteda

library(tidytext)
library(tm)
library(quanteda)

# Dans les trois cas, le corpus de text utilisé est transformé en objet 'corpus', auquel un certain nombre de fonctions peuvent être appliquées.

quanteda est un package developpé par Kenneth Benoit & co. Ce package a été developpé dans le cadre de l’ERC QUANTESS (ERC-2011-StG 283794-QUANTESS).* Une série de packages additionnels fonctionne parfaitement avec quanteda :
library(readtext) # Package permettant l’import simple de données textuelle de tout format
library(SpacyR) # Librarie open source spaCy, pour le traitement automatique du langage (NLP)
library(quanteda.dictionaries) # Dictionnaires quanteda

### Exemple d'utilisation de quanteda
library(quanteda)
data(data_char_ukimmig2010)

# Construction d'un objet corpus à partir du text brut
my_corpus <- corpus(data_char_ukimmig2010)  # build a new corpus from the texts
summary(my_corpus)
## Corpus consisting of 9 documents:
## 
##          Text Types Tokens Sentences
##           BNP  1125   3280        88
##     Coalition   142    260         4
##  Conservative   251    499        15
##        Greens   322    679        21
##        Labour   298    683        29
##        LibDem   251    483        14
##            PC    77    114         5
##           SNP    88    134         4
##          UKIP   346    723        27
## 
## Source: /data/user/p/hpecout/Cours_INED_InitiationR/* on x86_64 by hpecout
## Created: Thu Dec  6 00:00:47 2018
## Notes:
# Ou création d'une matrice creuse pour la création d'un simple nuage de mots
my_dfm <- dfm(data_char_ukimmig2010, remove = stopwords("english"), remove_punct = TRUE)

# Nuage de mot
textplot_wordcloud(my_dfm, min_count = 6, random_order = FALSE,
                   rotation = .25,
                   color = RColorBrewer::brewer.pal(8,"Dark2"))

Pour plus d’information sur le package quanteda, vous pouvez en consultez la vignette très complète.


3.5 Analyse multiniveau

Tout comme avec Sas® et Stata®, il est possible de réaliser des analyses multiniveaux avec R.

# Cadre linèaire
library(lme4) 

# cadre non linéaire
library(nlme4)

# SOURCE : www.ined.fr


3.6 Analyse de graphe

L’analyse de graphe se pratique beaucoup au travers de logiciel spécifiques (ex : gephi, ucinet, netdraw…). Comme pour l’analayse textuelle, il est dorénavant possible de réaliser ce genre d’analyse sous R.

Deux packages font office de référence dans le domaine : igraph et statnet

library(statnet)
library(igraph)

# Attention, ces deux packages ne permettent pas d’analyser des graphes valués
# (i.e. l’intensité des liens n’est pas prise en compte pour le calcul des indicateurs).
# Mais il est possible de faire varier l’épaisseur des liens en fonction de leur 
# intensité dans une représentation graphique.

# Pour analyser des graphes valués (et bipartis) :
library(tnet)

# Pour des graphes bipartis
library(bipartite)

# Pour la modèlisation
# Pour du blockmodeling
library(blockmodeling)

# Modélisation des dynamiques d’un graphe
library(Rsiena)

Selon les spécialistes, igraph propose une approche plus basique. Les fonctions sont plus efficaces et plus complètes… Mais du coup un peu plus complexe d’utilisation.

Attention, évitez de lancer en même temps statnet et igraph, car vous vous exposez à des risques de conflit entre certaines fonctions (ex : gplot). Cette remarque est valable pour de nombreux packages proposant le même genre de fonction et d’analyse.

Exemple d’analyse avec igraph:

library(igraph)

# Construction d'une matrice exemple
ma_matrice <- matrix(sample(c(0,1),32,T), 8, 8)
row.names(ma_matrice) <- c("A","B","C","D","E","F","G","H")
colnames(ma_matrice) <- c("A","B","C","D","E","F","G","H")
ma_matrice
##   A B C D E F G H
## A 1 1 1 1 1 1 1 1
## B 1 1 0 0 1 1 0 0
## C 1 0 1 1 1 0 1 1
## D 1 1 0 0 1 1 0 0
## E 1 0 1 1 1 0 1 1
## F 0 0 1 1 0 0 1 1
## G 1 1 0 1 1 1 0 1
## H 0 1 1 1 0 1 1 1

La construction d’un objet igraph peuvent se réaliser à partir de différents types d’objet, en utilisant par exemple les fonctions suivantes :

# graph_from_data_frame()
# graph_from_edgelist()
# graph_from_adj_list()
# ...

# Exemple de construction objet igraph à partir d'une matrice
g <- graph_from_adjacency_matrix(ma_matrice)
g
## IGRAPH 11105d3 DN-- 8 44 -- 
## + attr: name (v/c)
## + edges from 11105d3 (vertex names):
##  [1] A->A A->B A->C A->D A->E A->F A->G A->H B->A B->B B->E B->F C->A C->C
## [15] C->D C->E C->G C->H D->A D->B D->E D->F E->A E->C E->D E->E E->G E->H
## [29] F->C F->D F->G F->H G->A G->B G->D G->E G->F G->H H->B H->C H->D H->F
## [43] H->G H->H

Un nombre important de fonctions peut être appliqué à cet objet ‘igraph’ afin de l’analyser :

#densité 
graph.density(g)
## [1] 0.7857143
# diamètre
diameter(g)
## [1] 2
#intermédiarité
betweenness(g)
##        A        B        C        D        E        F        G        H 
## 3.583333 0.500000 1.166667 2.500000 2.583333 2.583333 2.500000 1.583333
# Centralité
closeness(g)
##          A          B          C          D          E          F 
## 0.14285714 0.09090909 0.11111111 0.10000000 0.11111111 0.10000000 
##          G          H 
## 0.12500000 0.11111111
# distance
average.path.length(g)
## [1] 1.303571
# plus court chemin
shortest.paths(g)
##   A B C D E F G H
## A 0 1 1 1 1 1 1 1
## B 1 0 2 1 1 1 1 1
## C 1 2 0 1 1 1 1 1
## D 1 1 1 0 1 1 1 1
## E 1 1 1 1 0 2 1 1
## F 1 1 1 1 2 0 1 1
## G 1 1 1 1 1 1 0 1
## H 1 1 1 1 1 1 1 0
# réciprocité
reciprocity(g, ignore.loops=TRUE)
## [1] 0.6666667
# Visualisation simple (non interactif), sinon utiliser tkplot(g)
plot(g) 

### Et bien d'autres...
# cliques(g) - recherche de cliques - à éviter sur les graphes de grande taille
# largest.cliques(g) - Plus grande clique
# clique.number(g) - Nombre de cliques
# transitivité globale - transitivity(g)
# transitivité locale - transitivity(g, type=c("local"), vids=NULL)
# dyades - dyad.census(g)
# triades - triad.census(g)
# points d’articulation - articulation.points(g)
# .... 

De nombreuses ressources sont disponibles sur le web pour vous aider à utiliser ces packages. Par exemple, cet article de Laurent Beauguitte : Analyser les réseaux avec R (packages statnet, igraph et tnet) offre une brève vue d’ensemble de ces trois packages. L’exemple ci-dessus s’appuie sur cet article.


3.7 Analyse spatiale

Depuis peu, le package sf est devenu la référence en matière d’analyse spatiale sur R. Ce package permet d’importer, de gérer et de transformer des données spatiales. Il permet ainsi de réaliser tous les traitements spatiaux proposés par les SIG (Union, différenciation, regroupement, jointure et intersection spatiale, zone tampons, calcul de distance…). Exemple :

library(sf)
# Import d'un fichier shape (couche géographique) = Création d'un objet sf
quartier_paris <- st_read(dsn = "paris/quartier_paris_pop12_pop07.shp", stringsAsFactors = F)
## Reading layer `quartier_paris_pop12_pop07' from data source `/data/user/p/hpecout/Cours_INED_InitiationR/paris/quartier_paris_pop12_pop07.shp' using driver `ESRI Shapefile'
## Simple feature collection with 80 features and 9 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 643065.8 ymin: 6857479 xmax: 661079.6 ymax: 6867083
## epsg (SRID):    NA
## proj4string:    +proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +units=m +no_defs
head(quartier_paris,3)
## Simple feature collection with 3 features and 9 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 651908.5 ymin: 6859831 xmax: 653578.2 ymax: 6863241
## epsg (SRID):    NA
## proj4string:    +proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +units=m +no_defs
##   c_quinsee   n_sq_qu c_qu  surface   n_sq_ar               l_qu c_ar
## 1   7510302 750000010   10 271750.3 750000003     Enfants-Rouges    3
## 2   7510404 750000016   16 378252.2 750000004         Notre-Dame    4
## 3   7510502 750000018   18 798389.4 750000005 Jardin-des-Plantes    5
##   P12_POP P07_POP                       geometry
## 1    9569    9118 POLYGON ((653578.2 6862510,...
## 2    3271    3286 POLYGON ((653144.9 6861099,...
## 3   18219   18300 POLYGON ((652426.7 6859833,...
# Affichage graphique d'un objet sf
plot(quartier_paris)

# Afficher uniquement la géométrie d'un objet sf
plot(st_geometry(quartier_paris), col="#aec8f2", border="darkblue", lwd=1)

# Récupération du centroïde d'un quartier - st_centroid()
mon_quartier <- quartier_paris[quartier_paris$c_quinsee == "7510302",]
moncentre <- st_centroid(mon_quartier)

# Création d'une zone tampon de 2000 m autour du centroïde - st_buffer()
buff <- st_buffer(x = st_geometry(moncentre), dist=2000)

# Intersection entre la zone tampon et les quartier de paris
quartier_paris$buff <- st_intersects(st_geometry(quartier_paris), st_geometry(buff), sparse = FALSE)
head(quartier_paris)
## Simple feature collection with 6 features and 10 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 650029.3 ymin: 6859831 xmax: 653578.2 ymax: 6865053
## epsg (SRID):    NA
## proj4string:    +proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +units=m +no_defs
##   c_quinsee   n_sq_qu c_qu  surface   n_sq_ar                 l_qu c_ar
## 1   7510302 750000010   10 271750.3 750000003       Enfants-Rouges    3
## 2   7510404 750000016   16 378252.2 750000004           Notre-Dame    4
## 3   7510502 750000018   18 798389.4 750000005   Jardin-des-Plantes    5
## 4   7510701 750000025   25 826559.4 750000007 Saint-Thomas-d'Aquin    7
## 5   7510903 750000035   35 417335.1 750000009  Faubourg-Montmartre    9
## 6   7510904 750000036   36 500435.4 750000009         Rochechouart    9
##   P12_POP P07_POP                       geometry  buff
## 1    9569    9118 POLYGON ((653578.2 6862510,...  TRUE
## 2    3271    3286 POLYGON ((653144.9 6861099,...  TRUE
## 3   18219   18300 POLYGON ((652426.7 6859833,...  TRUE
## 4   11635   12227 POLYGON ((650138.4 6861145,... FALSE
## 5   10375   10625 POLYGON ((652227.8 6864265,...  TRUE
## 6   22734   22146 POLYGON ((652259.6 6864352,...  TRUE
# Cartographie des résultat des résultats
par(mar = c(0.5,0.5,1.5,0.5)) 
plot(st_geometry(quartier_paris), col="#aec8f2", border="darkblue", lwd=1)
plot(st_geometry(quartier_paris[quartier_paris$buff == TRUE,]), col="pink", lwd=2, border="red", add=T)
plot(st_geometry(mon_quartier), col="white", border="red", lwd=2, add=T)
plot(st_geometry(moncentre), pch=20, col="black", cex=1, add=T)
plot(buff, col=NA, border="black", lwd=1.5, lty=2,add=T)

# La fonction st_write() permet d'exporter des couche géographiques
# st_write(obj = mon_quartier, dsn = "paris/mon_quartier.shp")


> Exemple

ÉTAPE 3 : L’exemple d’analyse est regroupé avec celui des représentations de données (cf.partie suivante).
Retrouvez ce bout de code dans le projet RUSS_running_example.Rproj téléchargeable ici.


4. Représentation

4.1 Représentations basiques

Réaliser des graphiques en utilisant les fonctions basiques suivantes :

# Nuage de points ou ligne
plot()

# Graphique en barre
barplot()

# Histogramme
hist()

# Boite à moustache
boxplot()

# Dot plots
dotcharts()

# Camembert
pie()


# Plusieurs arguments permettent d'améliorer le rendu graphique :
main = # Définir un titre
sub = # Définir un sous-titre
xlab = # Définir nom axe x
ylab = # Définir nom axe y
...


# Eléments à ajouter à un plot existant
lines()
points()
text()
title()
axis()
mtext() # Label des axes
abline()
legend()
...

# Il est également possible de superposer les plots

R possède déjà des fonctions graphiques pré-installées, qui permettent en jouant avec les arguments des fonctions de mettre en forme un graphique en y rajoutant des segments, des points, du texte, ou toutes sortes d’autres symboles. Pour une vue d’ensemble des fonctions basiques permettant les représentations graphiques, vous pouvez consulter la cheatsheet de ces fonctions.

Exemple : visualiser la forme d’une distribution

# Histogramme de distribution
hist(mtcars$mpg, 
     breaks=12, 
     col="goldenrod1",
     border = "goldenrod4",
     xlab= "",
     ylab = "Fréquence",
     main = "Distribution de la variable statistique 'mpg'")

# Ajout de la moyenne
abline(v=mean(mtcars$mpg), col="firebrick", lwd=2.5 , add=T)
# Ajout des quantile
abline(v=quantile(mtcars$mpg), col="dodgerblue3", lwd=1.5 ,lty=2,  add=T)
# Légende pour moyenne
legend("topright", c("moyenne", "quantile"), fill=c(col="firebrick",col="dodgerblue3" ), cex=0.8)

Pour connaître toutes les couleurs implémentées par défaut, ce document de l’université de columbia peut vous être très utile.

Si vous souhaitez avoir accèes à une plus grande varièté de choix, et pouvoir créer des degradés de couleur, vous pouvez utiliser le package de référence RColorBrewer.


4.2 Représentations avancés

Pour produire un graphique complet avec les fonctions basiques de R, il faut parfoit un peu bricoler…
Le package ggplot2, développée par Hadley Wickham (directeur scientifique de RStudio) et mettant en œuvre la “grammaire graphique” théorisée par Leland Wilkinson, est un plus lorsque l’on souhaite réaliser des graphiques plus complexes et stylisés.
Ci-dessous, quelques exemples d’utilisation de la librarie ggplot2 issues du site http://r-statistics.co :

La cheatsheet de ggplot2 permet de se faire une idée des possibilitées offertes par cette extension :


L’extension plotly permet de rendre vos graphiques intéractifs. Vous trouverez de la documentation est un certains nombre d’exemple (cf.ci-dessous) sur le site https://plot.ly/r/.


4.3 Cartographie

Il existe plusieurs manière de faire des cartes sur R. L’utilisation du package ggplot2 est une possibilité.

library(ggplot2)

ggplot() + 
geom_sf(data = quartier_paris, aes(fill = P12_POP)) + scale_y_continuous()

D’autres packages, permettent la gestion et/ou la représentation de données spatiales.

library(rgdal)
library(rgeos)
library(ggmap)
library(leaflet)
library(tmap)
library(maptools)
library(cartogram) # cartogrammes continus ou discontinus.
...

Mais si vous souhaitez réaliser une carte thématique dans les règles de l’art, nous vous recommandons d’utiliser le package cartography, développé par des cartographes.
Ce package permet des représentations cartographiques tels que les cartes en symboles proportionnels, des cartes choroplèthes, des typologies, des cartes de flux ou des cartes de discontinuités. Il offre également des fonctions qui permettent d’améliorer la réalisation de la carte, comme des palettes de couleur, des éléments d’habillage (échelle, flèche du nord, titre, légende…), d’y rattacher des labels ou d’accéder à des APIs cartographiques.

Documentation pour cartography : https://www.rdocumentation.org/packages/cartography/versions/2.1.1

Exemple : Consulter la cheatsheet de ce package pour une information claire et concise.


> Exemple

ÉTAPE 3 et 4 : Analyse et représentation de données sous R :
Retrouvez ce bout de code dans le projet RUSS_running_example.Rproj téléchargeableici.

#####################################################################
# Démo 3 - Quelques statistiques et graphiques associés 
#####################################################################

#  3.1 Statistiques de base - résumé statistique
summary(data)

# 3.2 Analyse spatiale - distance au centre de Paris (1er arrondissement)
# Définir un centre (pour les calculs de distance)
moncentre <- "75101"
monpoly <- communes[communes$INSEE_COM == moncentre,]
communes$distance <- c(st_distance(st_centroid(x = monpoly), st_centroid(x = communes)))
head(communes)
communes$distance <- as.numeric(communes$distance)

# Jointure des stats spatiales au fichier de données pour analyse et représentations graphiques
data <- merge(x = data, y = communes[,c("INSEE_COM","distance")], by.x = "COM", by.y = "INSEE_COM", all.x = TRUE)
head(data)

# 3.3 Visualisations simples associés à des types statistiques  
# 3.3.1 - Bar plot de la population aux trois périodes de recensement avec une boucle
par(mar = c(2,2,2,2)) 
par(mfrow = c(2,2)) # 4 graphiques (2 en colonnes et 2 en ligne)

for (i in 3:5){ # On prend les colonnes 3 à 5 du dataframe
  popYear <- colnames(data) # récupérer le nom des colonnes
  hist(data[ ,i], # un histogramme
       breaks = 20, # la série statistique est coupée en 20 classes
       main = popYear[i], # titre
       col = "#4286f4", # couleur des barres
       border = "white", # couleur des bordures
       xlab = "Population", # titre de l'axe des X
       ylab = "Fréquence") # titre de l'axe des Y
}


# 3.3.2 - Deux variables quantitatives : Quelle relation distance au centre / accroissement de la population? 
cor.test(data$acc_9015, data$distance) 
par(mfrow = c(1,1)) 
par(mar = c(4,4,4,4)) 
plot(data$distance, data$acc_9015) # En quelques instructions on peut obtenir un graphique ! 

# Amélioration du graphique avec les fonctions de base de R...
data$DEP <- as.factor(data$DEP)

library(cartography)
colours <- carto.pal(pal1 = "multi.pal", n1 = nlevels(data$DEP)) # 1 couleur par dépt

# Assigner les couleurs aux départements d'appartenance
data <-data[order(data$DEP, decreasing = FALSE), ]
data$col <- as.factor(data$DEP)
levels(data$col) <- colours
# Représentation graphique
par(mfrow = c(1,2))
plot(data$distance, data$acc_9015,
     ylab = "Taux d'accroissement moyen annuel (1990-2015, %)",
     xlab = "Distance au centre de l'espace d'étude (m) ",
     pch = 20,
     col = as.vector(data$col))
# Afficher la régression linéaire
abline((lm(data$acc_9015 ~ data$distance)), col = "red", lwd =1)
# Afficher la légende
data$DEP <- as.factor(data$DEP)
legend("topleft", legend = levels(data$DEP),pch = 20,col = colours, cex = 0.5, pt.cex = 1,
       title = "Département")

# Il suffirait de quelques modifications dans le code pour reproduire cette analyse avec
# le taux d'accroissement sur la précédente période censitaire ! 
# Représentation graphique
plot(data$distance, data$acc_7590,
     ylab = "Taux d'accroissement moyen annuel (1975-1990, %)",
     xlab = "Distance au centre de l'espace d'étude (m) ",
     pch = 20,
     col = as.vector(data$col))
# Afficher la régression linéaire
abline((lm(data$acc_7590 ~ data$distance)), col = "red", lwd =1)
# Afficher la légende
data$DEP <- as.factor(data$DEP)
legend("topleft", legend = levels(data$DEP),pch = 20,col = colours, cex = 0.5, pt.cex = 1,
       title = "Département")


# On peut aussi utiliser ggplot pour réaliser des graphiques
library(ggplot2)
library(ggthemes)

par(mfrow = c(1,1)) # Un graphique par plot 
ggplot(data, aes(x=distance, y=acc_9015, color = DEP )) + 
  geom_point(aes(size=POP_2015)) +
  xlab("Distance au centre (m)") +
  ylab("Taux d'accroissement moyen annuel (1990-2015, %)") +
  ggtitle("Croissance démographique et distance au centre de l'espace d'étude") +
  theme_wsj() +
  scale_fill_wsj(palette = "colors6", "DEP") + 
  labs(subtitle="Sources: INSEE-IGN, 2018 / Réalisation : R.Ysebaert / H.Pécout, 2018") +
  theme(axis.text = element_text(size = 6), 
        axis.title = element_text(size = 10, face = "bold"),
        legend.title=element_text(size=12, face = "bold"),
        legend.text=element_text(size=10),
        plot.subtitle=element_text(size=8),
        plot.title = element_text(size = 15, face = "bold")) 


# 3.3.3 Deux variables qualitatives : Commune d'appartenance et catégorie d'accroissement de population ? 
# Test du Chi-2
tab <- table(data$typo9015, data$EPT_Nom)
tab.chi2 <- chisq.test(tab)
tab.chi2

library(questionr)
ctab <- cprop(tab, total = FALSE)


# Diagramme en bâton
par(mar = c(10,2,2,2))
col <- c("#fc8d59","#a6d96a","#1a9641")
barplot(ctab, main = "Croissance démographique 1990-2015 par EPT",las = 2, col= col,
        cex.axis=0.75, cex.names = 0.75)
legend("topright", c("POP- (<0%)", "POP+ (0-1%)","POP++ (+1%)"), fill = col, cex = 0.8, bg = "#ffffff80")



# 3.3.4 - Une variable qualitative et une variable quantitative
# On charge à représenter le taux de croissance 1975-2015 par EPT

# Le box plot sera ordonné en fonction de la moyenne de chaque EPT sur la variable du taux de croissance de la population
data$EPT <- with(data, reorder(EPT, acc_9015, mean, na.rm = TRUE))

col <- carto.pal(pal1 = "red.pal", n1 = (nlevels(data$EPT)/2), pal2 = "green.pal", n2 = (nlevels(data$EPT)/2),
                   middle = FALSE, transparency = TRUE)

par(mar = c(4,4,4,4))
boxplot(data$acc_9015 ~ data$EPT,
        col = col,
        ylab = "Taux de croissance moyen annuel",
        varwidth = TRUE,
        range = 1,
        outline = TRUE,
        las = 1) 

# Ligne de repère
abline (h = seq(min(data$acc_9015,na.rm=T),max(data$acc_9015,na.rm=T),0.5), col = "#00000080", lwd = 1, lty = 1)

# Représenter les valeurs moyennes
xi<- tapply(data$acc_9015, data$EPT, mean, na.rm = T)
points(xi,col="#7C0000",pch=19)

# Legend for the boxplot
data$EPT_Nom<- as.factor(data$EPT_Nom)
data$EPT_Nom <- with(data, reorder(EPT_Nom, acc_9015, mean, na.rm = TRUE))
legend("topleft",
       legend = levels(data$EPT_Nom),
       pch = 20,
       col = col,
       cex = 0.6,
       pt.cex = 1,
       title = "Etablissements publics territoriaux")


# 3.4 - Cartographie
library(cartography)

# On joint les colonnes du dataframe utiles à la carto
communes <- merge(x = communes, y = data[,c("COM","POP_1975","POP_1990","POP_2015", "acc_9015","acc_7590")],
                  by.x = "INSEE_COM", by.y = "COM", all.x = TRUE)


# 3.4.1 - Cartographie de discontinuités (choro layer +  discLayer)
par(mfrow=c(1,2))
par(mar = c(0.5,0.5,1.5,0.5)) # Ajuster les marges

cols <- carto.pal(pal1 = "red.pal", pal2 = "green.pal",  n1 = 2, n2 = 4)

# 1975- 1990
plot(st_geometry(communes), col = NA, border = NA)

choroLayer(x = communes, var = "acc_7590", 
           border = "grey80",
           col = cols, 
           breaks = c(min(data$acc_7590,na.rm = T),-0.25,0,0.25,0.5,1,max(data$acc_7590,na.rm = T)),
           nclass = 10, 
           legend.pos = "topleft", 
           legend.values.rnd = 2,
           lwd=0.5, 
           add = T,
           legend.title.txt = "Taux de croissance moyen annuel (%)")

borders <- getBorders(communes)

discLayer(x = borders, # sf 
          df = communes,
          var = "acc_7590", # variable used to compute discontinuties 
          type = "abs", # type of discontinuity measure 
          method="equal", # discretisation of discontinuities
          nclass=4, # number of discontinuities classes
          threshold = 0.5, # representation threshold of discontinuities  
          sizemin = 0.5, # minimum size of discontinuities lines
          sizemax = 6, # maximum size of discontinuities lines
          col="red", # color of the lines
          legend.values.rnd = 1,
          legend.title.txt = "Discontinuités \n absolues (max-min)",
          legend.pos = "bottomleft", 
          add=TRUE)

layoutLayer(title = "Évolution démo 1975-1990 - Discontinuités territoriales",
            author = "Ronan Ysebaert, Hugues Pécout 2018", sources = "INSEE, IGN, 2018",
            scale = 5,
            frame = TRUE,
            col = "red",
            coltitle = "white",
            south = TRUE)


# 1990 - 2015
plot(st_geometry(communes), col = NA, border = NA)

choroLayer(x = communes, var = "acc_9015", 
           border = "grey80",
           col = cols, 
           breaks = c(min(data$acc_9015,na.rm = T),-0.25,0,0.25,0.5,1,max(data$acc_9015,na.rm = T)),
           nclass = 10, 
           legend.pos = "topleft", 
           legend.values.rnd = 2,
           lwd=0.5, 
           add = T,
           legend.title.txt = "Taux de croissance moyen annuel (%)")

discLayer(x = borders, # sf 
          df = communes,
          var = "acc_9015", # variable used to compute discontinuties 
          type = "abs", # type of discontinuity measure 
          method="equal", # discretisation of discontinuities
          nclass=4, # number of discontinuities classes
          threshold = 0.5, # representation threshold of discontinuities  
          sizemin = 0.5, # minimum size of discontinuities lines
          sizemax = 6, # maximum size of discontinuities lines
          col="red", # color of the lines
          legend.values.rnd = 1,
          legend.title.txt = "Discontinuités \n absolues (max-min)",
          legend.pos = "bottomleft", 
          add=TRUE)

layoutLayer(title = "Évolution démo 1990-2015 - Discontinuités territoriales",
            author = "Ronan Ysebaert, Hugues Pécout 2018", sources = "INSEE, IGN, 2018",
            scale = 5,
            frame = TRUE,
            col = "red",
            coltitle = "white",
            south = TRUE)

# 3.4.2 - Cercles proportionnels et carte choroplèthe
# 1975 - 1990
plot(st_geometry(communes), col = "lightblue", border = NA)
plot(st_geometry(agg), col = NA, border = "white", lwd = 1, add = T)

propSymbolsChoroLayer(x = communes, var = "POP_1990", var2 = "acc_7590", 
                      col = cols,
                      inches = 0.2, 
                      breaks = c(min(data$acc_7590,na.rm = T),-0.25,0,0.25,0.5,1,max(data$acc_7590,na.rm = T)),
                      border = "grey50", lwd = 1,
                      legend.var.pos = "bottomleft", legend.var2.pos = "topleft",
                      legend.var2.title.txt = 
                        "Taux de croissance moyen annuel (%)",
                      legend.var.title.txt = "Population totale 1990",
                      legend.var.style = "e",
                      add = T)

layoutLayer(title = "Évolution démo 1975-1990 et population 1990",
            author = "Ronan Ysebaert, Hugues Pécout 2018", sources = "INSEE, IGN, 2018",
            scale = 5,
            frame = TRUE,
            col = "red",
            coltitle = "white",
            south = TRUE)


# 1990 - 2015
plot(st_geometry(communes), col = "lightblue", border = NA)
plot(st_geometry(agg), col = NA, border = "white", lwd = 1, add = T)

propSymbolsChoroLayer(x = communes, var = "POP_2015", var2 = "acc_9015", 
                      col = cols,
                      inches = 0.2, 
                      breaks = c(min(data$acc_9015,na.rm = T),-0.25,0,0.25,0.5,1,max(data$acc_9015,na.rm = T)),
                      border = "grey50", lwd = 1,
                      legend.var.pos = "bottomleft", legend.var2.pos = "topleft",
                      legend.var2.title.txt = 
                        "Taux de croissance moyen annuel (%)",
                      legend.var.title.txt = "Population totale 2015",
                      legend.var.style = "e",
                      add = T)

layoutLayer(title = "Évolution démo 1990-2015 et population 2015",
            author = "Ronan Ysebaert, Hugues Pécout 2018", sources = "INSEE, IGN, 2018",
            scale = 5,
            frame = TRUE,
            col = "red",
            coltitle = "white",
            south = TRUE)


# 3.4.3 - Carte de potentiel sur les deux recensements
# 1975-1990
par(mar = c(0.5,0.5,1.5,0.5)) # Ajuster les marges

plot(st_geometry(communes), col = NA, border = NA)

distr <- communes$POP_1990 / communes$POP_1975
summary(distr)
cols <- carto.pal(pal1 = "red.pal", pal2 = "green.pal",  n1 = 2, n2 = 5)

smoothLayer(x = communes,
            var = 'POP_1990', var2 = 'POP_1975',
            span = 2000, beta = 2,
            resolution = 500,
            legend.title.txt = "Potentiel de croissance de population, \n(pas de lissage = 2 km)",
            col = cols, 
            breaks = c(min(communes$POP_1990/communes$POP_1975, na.rm=T),
                       0.95,1,1.05,1.1,1.15,1.2, 
                       max(communes$POP_1990/communes$POP_1975, na.rm = T)),
            mask = st_buffer(communes,1),
            legend.pos = "topleft", legend.values.rnd = 2,
            add = T)

plot(st_geometry(agg), col = NA, border = "white", lwd = 1, add = T)

layoutLayer(title = "Croissance démographique 1975-1990 - carte de potentiel",
            author = "Ronan Ysebaert, Hugues Pécout 2018", sources = "INSEE, IGN, 2018",
            scale = 5,
            frame = TRUE,
            col = "red",
            coltitle = "white",
            south = TRUE)

# 1990-2015
plot(st_geometry(communes), col = NA, border = NA)

distr <- communes$POP_2015 / communes$POP_1990
summary(distr)
cols <- carto.pal(pal1 = "red.pal", pal2 = "green.pal",  n1 = 2, n2 = 5)

smoothLayer(x = communes,
            var = 'POP_2015', var2 = 'POP_1990',
            span = 2000, beta = 2,
            resolution = 500,
            legend.title.txt = "Potentiel de croissance de population, \n(pas de lissage = 2 km)",
            col = cols, 
            breaks = c(min(communes$POP_2015/communes$POP_1990, na.rm=T),
                       0.95,1,1.05,1.1,1.15,1.2, 
                       max(communes$POP_2015/communes$POP_1990, na.rm = T)),
            mask = st_buffer(communes,1),
            legend.pos = "topleft", legend.values.rnd = 2,
            add = T)

plot(st_geometry(agg), col = NA, border = "white", lwd = 1, add = T)

layoutLayer(title = "Croissance démographique 1990-2015 - carte de potentiel",
            author = "Ronan Ysebaert, Hugues Pécout 2018", sources = "INSEE, IGN, 2018",
            scale = 5,
            frame = TRUE,
            col = "red",
            coltitle = "white",
            south = TRUE)


5. Partage et valorisation

5.1 Export donnèes et figures

Pour partager votre travail réalisé sur R, il existe une serie de fonctions primitives ou mises à disposition par des packages, qui permettent d’exporter vos figures, vos tableaux ainsi que vos fichier de données en formats très divers.

#### EXPORTER Table de données #### 

## fonctions primitives
# .txt /.csv / ...
write.table(Mon_Objet, "c:/mydata.txt", sep="\t") 
# .csv
write.csv(Mon_Objet, file = "MyData.csv")


# format Excel
library(xlsx)
write.xlsx(Mon_Objet, "c:/mydata.xlsx") 

# format sas, spss... 
library(foreign)
write.foreign(Mon_Objet, "c:/mydata.txt", "c:/mydata.sas",   package="SAS")
write.foreign(Mon_Objet, "c:/mydata.txt", "c:/mydata.sps",   package="SPSS")

# format shape
library(sf) 
st_write()



####  EXPORTER graphique #### 

## fonctions primitives
# format jpeg
jpeg()

# format png
png()

# format pdf
pdf()

# format svg
svg()


# Exemple - Enregistrement d'un plot en format png
jpeg('rplot.jpg')
plot(runif(10, 1, 100),runif(10, 1, 100))
dev.off()


# Enregistrement d'un tableau de donnée en format png
library(gridExtra)
png("test.png", height = 50*nrow(mtcars), width = 200*ncol(mtcars))
grid.table(mtcars)
dev.off()



# format GIF
# Source : https://yihui.name/animation/example/savegif/
# Nécessite d'installer ImageMagick sur votre system system
library(animation) 
saveGIF({brownian.motion(pch = 21, cex = 5, col = "red", bg = "yellow")}, 
        movie.name = "brownian_motion.gif", 
        interval = 0.1, 
        nmax = 30, 
        ani.width = 600)


5.2 Production de document

Depuis quelques années, RStudio intègre la possibilité d’écrire des notebooks combinant de manière interactive du code R, du texte mis en forme en markdown (JavaScript, CSS), et des appels à du code Python, Bash, SQL, Rccp et Stan.
La combinaison de ces différents languages permet de produire des documents de qualité pouvant contenir l’intégralité de son code (affiché ou non), ses résultats graphiques (ou non) et des commentaires (texte, note de bas de page, bibliographie, lien…) associé. Le choix du format de fichier en sorti est assez large : pdf, html, word/odt, diapositives, LaTeX…

Pour produire un document en Rmarkdown, il est necessaire d’écrire son code dans un fichier.rmd (et non .R) :


Le documents se compose alors de trois zones :
- En en-tête de fichier, les paramètres généraux du documents
- Dans le corps du fichier, les zones de rédaction mise en page différent selon le type de fichier en sorti (html, pdf, word…)
- Dans le corps du fichier, les chunks, qui sont balises dans lequel on peut insérer du code d’un autre langage

Pour générer le document, il suffit de ‘knit’ le document (en haut à droite de l’interface RStudio). Votre fichier sera alors réecris en format markdown classique, puis traiter par pandoc (logiciel libre de conversion de documents numériques en ligne de commande, à installer selon les systèmes d’exploitation) qui genère le docmuent final. La production du document peut également être executée automatiquement, en encapsulant tout le code avec la fonction render().

De nombreux arguments peuvent être affectés à chaque chunk, pour gérer les éléments qui apparaissent (ou non) :

eval = Executer le code du chunk durant la génération du document
include = Rendre le code du chunk visible dans le document
warning = Affichage des messages d’alerte dans le document, après le chunk
message = Affichage des messages d’information dans le document, après le chunk
echo = Affichage des résultat (ex: graphiques) dans le document, après le chunk
fig.height = Hauteur des figures générées par le chunk
fig.width = largeur des figures générées par le chunk

# ```{r nom_du_chunk, warning=FALSE, message=FALSE, eval=TRUE, include= TRUE, echo=FALSE...}

# ```

Ce document est un bon exemple des possibilitées offerte par un Rmarkdown… Il est intégralement produit avec R. Preuve à l’appui :

De nombreuses ressources sont disponibles pour comprendre et apprendre à utiliser cette extension. En voici trois de réference :
- https://rmarkdown.rstudio.com/
- https://bookdown.org/yihui/rmarkdown/
- https://www.rstudio.com


5.3 Application web et Dashboard

Pour les utilisateurs avancés, R offre aussi la possibilité de construire des applications web et des tableaux de bord. Deux librairies, a combiner avec R Markdown peuvent vous permettre de réaliser de véritable document ou application interactives :

# Application web :
library(shiny)

# Dashboard :
library(flexdashboard)

Comme pour la plupart des packages de référence, ces deux librairies sont trés documentées. De nombreux exemples sont consultables sur le web, notamment sur le site de RStudio :
- https://shiny.rstudio.com/
- https://shiny.rstudio.com/gallery/
- https://shiny.rstudio.com/images/shiny-cheatsheet.pdf/a>


> Exemple

ÉTAPE 5 : Partage et valorisation sous R :
Vous pouvez télécharger le bout de code exemple (cf. capture ci-dessous) dans le projet RUSS_running_example.Rproj à ce lien.


Sources & références

Il existe de nombreuses ressources documentaires sur R. En voici quelques-unes en libre accès, dont certaines ont largement été utilisées pour produire ce document :


– R Session info –

R.version
##                _                           
## platform       x86_64-pc-linux-gnu         
## arch           x86_64                      
## os             linux-gnu                   
## system         x86_64, linux-gnu           
## status                                     
## major          3                           
## minor          5.1                         
## year           2018                        
## month          07                          
## day            02                          
## svn rev        74947                       
## language       R                           
## version.string R version 3.5.1 (2018-07-02)
## nickname       Feather Spray
sessionInfo()
## R version 3.5.1 (2018-07-02)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: CentOS Linux 7 (Core)
## 
## Matrix products: default
## BLAS: /opt/R/3.5.1/lib64/R/lib/libRblas.so
## LAPACK: /opt/R/3.5.1/lib64/R/lib/libRlapack.so
## 
## locale:
##  [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=fr_FR.UTF-8    
##  [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
##  [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] grid      stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] maptools_0.9-2     graticule_0.1.2    sp_1.3-1          
##  [4] RTriangle_1.6-0.10 rgl_0.99.16        plotly_4.8.0      
##  [7] scales_0.5.0       plyr_1.8.4         ggalt_0.4.0       
## [10] gapminder_0.3.0    ggthemes_4.0.1     quantmod_0.4-13   
## [13] TTR_0.23-4         xts_0.11-0         zoo_1.8-3         
## [16] igraph_1.2.1       quanteda_1.3.0     survey_3.34       
## [19] survival_2.42-6    Matrix_1.2-14      questionr_0.7.0   
## [22] reshape2_1.4.3     bindrcpp_0.2.2     dplyr_0.7.8       
## [25] osmdata_0.0.8      cartography_2.1.2  sf_0.6-3          
## [28] ggplot2_3.0.0      stringr_1.3.1      rvest_0.3.2       
## [31] xml2_1.2.0        
## 
## loaded via a namespace (and not attached):
##  [1] lubridate_1.7.4         webshot_0.5.0          
##  [3] ash_1.0-15              RColorBrewer_1.1-2     
##  [5] httr_1.3.1              rprojroot_1.3-2        
##  [7] tools_3.5.1             backports_1.1.2        
##  [9] utf8_1.1.4              R6_2.3.0               
## [11] KernSmooth_2.23-15      spData_0.2.9.0         
## [13] rgeos_0.3-28            DBI_1.0.0              
## [15] lazyeval_0.2.1          colorspace_1.3-2       
## [17] raster_2.8-4            manipulateWidget_0.10.0
## [19] withr_2.1.2             tidyselect_0.2.5       
## [21] extrafontdb_1.0         curl_3.2               
## [23] compiler_3.5.1          cli_1.0.0              
## [25] labeling_0.3            bookdown_0.7           
## [27] proj4_1.0-8             classInt_0.2-3         
## [29] digest_0.6.15           foreign_0.8-71         
## [31] rmarkdown_1.10          pkgconfig_2.0.2        
## [33] htmltools_0.3.6         extrafont_0.17         
## [35] highr_0.7               maps_3.3.0             
## [37] htmlwidgets_1.2         rlang_0.3.0.1          
## [39] rstudioapi_0.7          shiny_1.1.0            
## [41] bindr_0.1.1             jsonlite_1.5           
## [43] crosstalk_1.0.0         magrittr_1.5           
## [45] Rcpp_1.0.0              munsell_0.5.0          
## [47] fansi_0.2.3             stringi_1.2.4          
## [49] yaml_2.2.0              MASS_7.3-50            
## [51] promises_1.0.1          crayon_1.3.4           
## [53] miniUI_0.1.1.1          lattice_0.20-35        
## [55] splines_3.5.1           knitr_1.20             
## [57] klippy_0.0.0.9500       pillar_1.3.0           
## [59] codetools_0.2-15        stopwords_0.9.0        
## [61] fastmatch_1.1-0         glue_1.3.0             
## [63] evaluate_0.11           data.table_1.11.4      
## [65] RcppParallel_4.4.0      rmdformats_0.3.3       
## [67] httpuv_1.4.5            selectr_0.4-1          
## [69] Rttf2pt1_1.3.7          tidyr_0.8.2            
## [71] gtable_0.2.0            purrr_0.2.5            
## [73] assertthat_0.2.0        xfun_0.3               
## [75] mime_0.5                xtable_1.8-2           
## [77] e1071_1.6-8             later_0.7.3            
## [79] viridisLite_0.3.0       class_7.3-14           
## [81] tibble_1.4.2            spacyr_0.9.9           
## [83] units_0.6-0             ISOcodes_2018.06.29


Ce document est mis à disposition selon les termes de la Licence Creative Commons :
Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

Hugues Pecout (CIST) - Ronan Ysebaert (RIATE)

Séminaire RUSS (INED) - EHESS, Paris
6 Décembre 2018