Introduction à R¶
R est un langage de programmation statistique permettant de faire du traitement de données avancé. Il s'est imposé comme un outil de base dans de nombreux domaines (économie, géographie, géomarketing).
Les bases du langage¶
On peut directement écrire dans la console des opérations mathématiques.
2 + 3
R est un langage de programmation orienté objet. Il repose donc sur la création d'objets auxquels il convient d'affecter des valeurs à l'aide des caractères <-
a <- 2
b <- 3
a + b
Un objet peut être créé en ayant recours à d'autres objets. Un objet c'est quelque chose qui permet de stocker des valeurs, de l'information.
c <- a + b
Le nom d'un objet doit toujours commencer par une lettre et peut contenir des chiffres, des points ou encore des underscores (_). R repose sur des fonctions que l'on pourra utiliser de la manière suivante :
print(c)
[1] 5
La fonction print() permet donc simplement d'afficher la valeur d'un objet. Pour faire fonctionner une fonction, il faut connaitre son nom et les paramètres requis que l'on placera à l'intérieur des parenthèses. Ces paramètres s'appellent des arguments.
Attention, R est un langage sensible à la casse.
a
A
Error in eval(expr, envir, enclos): objet 'A' introuvable Traceback:
Pour modifier la valeur d'un objet, il suffit de l'écraser en reprocédant à l'affectation. Au passage, pour créer un objet de type texte on utilise les guillemets "".
a <- "Texte"
a
La fonction class() permet de connaitre la typologie d'un objet.
class(a)
La fonction c() permet de créer une liste de valeurs, c’est-à-dire un objet contenant plusieurs valeurs. Les virgules permettent de séparer les différentes valeurs. Au passage, on utilise le point pour les valeurs décimales.
b <- c(18, 182, 1.5, 15, 200, 5)
b
- 18
- 182
- 1.5
- 15
- 200
- 5
Si l'on veut plutôt créer un tableau de valeurs, on pourra utiliser les matrices :
c <- matrix(c (18, 182, 1.5, 15, 200, 5), nrow = 2)
c
| 18 | 1.5 | 200 |
| 182 | 15.0 | 5 |
Au sein d'une fonction, on peut trouver des arguments facultatifs que l'on peut utiliser en utilisant le signe =
d <- matrix(b, ncol = 2)
d
| 18.0 | 15 |
| 182.0 | 200 |
| 1.5 | 5 |
Que ce soit dans une liste, un tableau ou une matrice, on peut récupérer une valeur en s'appuyant sur son index de la manière suivante :
b[1]
e <- b[2] + b[3]
e
Pour des tableaux comme les matrices par exemple, on pourra faire référence au numéro de ligne et de colonne :
c[1,2]
On peut utiliser ces index pour modifier une valeur spécifique.
c[1,2] <- 0
print(c)
[,1] [,2] [,3] [1,] 18 0 200 [2,] 182 15 5
Pour récupérer une ligne ou une colonne en entier, il suffira de ne pas préciser un numéro de ligne ou de colonne spécifique... Pour écrire des commentaires dans le code, on peut utiliser des # .
col <- d[,1] # Récupération première colonne
print(col)
col2 <- d[,2] # Récupération deuxième colonne
print(col2)
ligne <- d[1,] # Récupération première ligne
print(ligne)
[1] 18.0 182.0 1.5 [1] 15 200 5 [1] 18 15
Il est possible d'utiliser des listes d'index pour filtrer l'information voulue.
b[c(1,3)]
- 18
- 1.5
De même, il est possible d'utiliser des tests.
2 < 10
b < 10
- FALSE
- FALSE
- TRUE
- FALSE
- FALSE
- TRUE
b[ b < 10]
- 1.5
- 5
Pour de véritable tableau, en R, on privilégie les dataFrames. Pour créer un dataFrame, on utilisera la fonction data.frame(), les arguments de cette fonction permettant d'ajouter différentes colonnes de même taille.
df <- data.frame(col, col2)
df
| col | col2 |
|---|---|
| <dbl> | <dbl> |
| 18.0 | 15 |
| 182.0 | 200 |
| 1.5 | 5 |
class(df)
Généralement, à ces colonnes sont associés des noms de colonne.
df2 <- data.frame(taille = col, age = col2)
df2
| taille | age |
|---|---|
| <dbl> | <dbl> |
| 18.0 | 15 |
| 182.0 | 200 |
| 1.5 | 5 |
A l'aide de $ et des noms de colonne, on peut alors avoir accès facilement aux valeurs d'une colonne. Néanmoins, on peut toujours utiliser les index.
df2[,1]
- 18
- 182
- 1.5
df2$taille
- 18
- 182
- 1.5
La fonction names() permet de récupérer les noms des colonnes d'un dataFrame.
names(df2)
- 'taille'
- 'age'
Statistique et visualisation graphique¶
R propose plein de fonctions permettant de calculer les principaux indicateurs statistiques
mean(b)
median(b)
sd(b) # écart-type
var(b)
min(b)
max(b)
sum(b)
R propose aussi une fonction summary() très pratique qui permet d'avoir un résumé des objets étudiés. Ce summary peut s'adapter à différents types d'objets.
summary(b)
Min. 1st Qu. Median Mean 3rd Qu. Max. 1.50 7.50 16.50 70.25 141.00 200.00
La fonction length() est aussi pratique pour connaitre la taille d'une série statistique par exemple.
length(b)
En statistique, la visualisation des données est importante. Ainsi, R propose des fonctions permettant de représenter des données. La plus courante est la fonction plot().
plot(d[,1],d[,2])
plot(d[,1],d[,2], col = 'red', main = 'Graphique', xlab = 'X', ylab = 'Y')
Mais R propose bien d'autres représentations comme les histogrammes par exemple.
hist(b)
Si vous avez besoin d'aide pour personnaliser votre histogramme, vous pouvez utiliser l'aide de R en utilisant la fonction help() et en écrivant le nom de la fonction.
help(hist)
La fonction lm() permet de créer des modèles linéaires qui permettront de calculer des régressions linéaires, d'étudier des corrélations...
reg <- lm(d[,1] ~ d[,2])
summary(reg)
Call:
lm(formula = d[, 1] ~ d[, 2])
Residuals:
1 2 3
3.8070 -0.1952 -3.6118
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.57118 3.91681 0.146 0.9078
d[, 2] 0.90812 0.03382 26.855 0.0237 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 5.251 on 1 degrees of freedom
Multiple R-squared: 0.9986, Adjusted R-squared: 0.9972
F-statistic: 721.2 on 1 and 1 DF, p-value: 0.02369
plot(d[,1],d[,2])
abline(reg)
Chargement de données tabulaires¶
Il existe de multiples possibilités pour charger des fichiers dans R. Personnellement, pour récupérer l'adresse d'un fichier avant de chercher à le charger, j'aime utiliser la fonction file.choose().
ad <- file.choose()
Une boite de dialogue s'ouvre et on indique où est stocké le fichier. Attention, cette fonction ne charge pas le fichier dans R, mais récupère juste son emplacement, son adresse...
ad
Ensuite, on peut utiliser des fonctions qui vont s'appuyer sur cette adresse pour charger le fichier. Ici, il s'agit d'un fichier CSV, je vais donc utiliser la fonction read.csv() pour le charger. L'argument sep me permet de bien préciser comment sont séparés les champs (les colonnes) de mon fichier. Il faut connaitre sa structure.
iris <- read.csv(ad, sep=';')
A noter que l'on peut écrire à la main sous la forme de texte l'adresse, il n'y a pas d'obligation à utiliser la fonction file.choose().
Pour visualiser ces données, on peut ne pas chercher à tout afficher dans la console. Pour cela, la fonction head() est très pratique.
head(iris)
| OBJECTID | N_SQ_IR | C_IR | L_IR | M2_POP | SHAPE_Area | Tx_Mono | Tx_Ouvrier | Revenu | X | Y |
|---|---|---|---|---|---|---|---|---|---|---|
| 20 | 750004033 | 751186922 | Grandes Carri?¿res 22 | 42891.78 | 80920.79 | 0.1699 | 0.0517 | 31376 | 651225.3 | 6866376 |
| 21 | 750004043 | 751186923 | Grandes Carri?¿res 23 | 51939.49 | 68661.34 | 0.3265 | 0.0875 | 21229 | 650861.0 | 6866264 |
| 22 | 750004027 | 751186924 | Grandes Carri?¿res 24 | 43233.73 | 73724.51 | 0.3491 | 0.0701 | 17436 | 650950.0 | 6866511 |
| 23 | 750004026 | 751186925 | Grandes Carri?¿res 25 | 37176.58 | 81608.21 | 0.5014 | 0.1773 | 13180 | 651420.2 | 6866557 |
| 24 | 750004862 | 751186926 | Grandes Carri?¿res 26 | 38308.33 | 176037.03 | 0.5323 | 0.1397 | 10465 | 651645.9 | 6866858 |
| 25 | 750004020 | 751186927 | Grandes Carri?¿res 27 | 21445.84 | 44308.01 | 0.5561 | 0.1739 | 10986 | 651526.2 | 6866707 |
Si on sait manipuler les index, on peut aussi afficher les 10 premières lignes du tableau. La fonction summary() peut aussi être utile, comme la fonction length().
iris[1:10,]
| OBJECTID | N_SQ_IR | C_IR | L_IR | M2_POP | SHAPE_Area | Tx_Mono | Tx_Ouvrier | Revenu | X | Y |
|---|---|---|---|---|---|---|---|---|---|---|
| 20 | 750004033 | 751186922 | Grandes Carri?¿res 22 | 42891.78 | 80920.79 | 0.1699 | 0.0517 | 31376 | 651225.3 | 6866376 |
| 21 | 750004043 | 751186923 | Grandes Carri?¿res 23 | 51939.49 | 68661.34 | 0.3265 | 0.0875 | 21229 | 650861.0 | 6866264 |
| 22 | 750004027 | 751186924 | Grandes Carri?¿res 24 | 43233.73 | 73724.51 | 0.3491 | 0.0701 | 17436 | 650950.0 | 6866511 |
| 23 | 750004026 | 751186925 | Grandes Carri?¿res 25 | 37176.58 | 81608.21 | 0.5014 | 0.1773 | 13180 | 651420.2 | 6866557 |
| 24 | 750004862 | 751186926 | Grandes Carri?¿res 26 | 38308.33 | 176037.03 | 0.5323 | 0.1397 | 10465 | 651645.9 | 6866858 |
| 25 | 750004020 | 751186927 | Grandes Carri?¿res 27 | 21445.84 | 44308.01 | 0.5561 | 0.1739 | 10986 | 651526.2 | 6866707 |
| 26 | 750004019 | 751186928 | Grandes Carri?¿res 28 | 22749.05 | 45661.40 | 0.5135 | 0.1453 | 11770 | 651273.0 | 6866732 |
| 28 | 750004121 | 751187001 | Clignancourt 1 | 44844.08 | 73361.91 | 0.2281 | 0.0817 | 25557 | 652217.4 | 6865260 |
| 29 | 750004137 | 751187002 | Clignancourt 2 | 44804.09 | 68369.98 | 0.1257 | 0.0515 | 28270 | 651912.9 | 6865054 |
| 30 | 750004148 | 751187003 | Clignancourt 3 | 29176.10 | 40418.48 | 0.1654 | 0.0662 | 29112 | 651594.7 | 6864962 |
summary(iris)
OBJECTID N_SQ_IR C_IR L_IR
Min. : 20.0 Min. :7.5e+08 Min. :751010201 Length:864
1st Qu.: 275.8 1st Qu.:7.5e+08 1st Qu.:751114208 Class :character
Median : 649.5 Median :7.5e+08 Median :751155702 Mode :character
Mean : 780.6 Mean :7.5e+08 Mean :751141569
3rd Qu.:1201.2 3rd Qu.:7.5e+08 3rd Qu.:751176815
Max. :3368.0 Max. :7.5e+08 Max. :751208026
M2_POP SHAPE_Area Tx_Mono Tx_Ouvrier
Min. : 8590 Min. : 18109 Min. :0.0418 Min. :0.00400
1st Qu.: 30200 1st Qu.: 50416 1st Qu.:0.1336 1st Qu.:0.02958
Median : 37574 Median : 66735 Median :0.1741 Median :0.04395
Mean : 41869 Mean : 83173 Mean :0.2141 Mean :0.05399
3rd Qu.: 48182 3rd Qu.: 91643 3rd Qu.:0.2504 3rd Qu.:0.06742
Max. :264565 Max. :842544 Max. :0.7855 Max. :0.22380
Revenu X Y
Min. : 9196 Min. :645404 Min. :6857720
1st Qu.:23240 1st Qu.:649702 1st Qu.:6860491
Median :30123 Median :652064 Median :6862331
Mean :30375 Mean :651840 Mean :6862420
3rd Qu.:36482 3rd Qu.:654180 3rd Qu.:6864456
Max. :64854 Max. :656987 Max. :6866885
length(iris) # permet de récupérer la taille du tableau ici le nombre de colonnes.
length(iris[,1]) # permet de récupérer la taille d'une colonne, ici le nombre d'IRIS du 75.
La plupart du temps, les fichiers pourront s'utiliser comme des dataFrames, ce qui permet de récupérer les champs à l'aide de leur nom.
names(iris)
- 'OBJECTID'
- 'N_SQ_IR'
- 'C_IR'
- 'L_IR'
- 'M2_POP'
- 'SHAPE_Area'
- 'Tx_Mono'
- 'Tx_Ouvrier'
- 'Revenu'
- 'X'
- 'Y'
Tx_Ouv <- iris$Tx_Ouvrier
Rev <- iris$Revenu
plot(Tx_Ouv, Rev)
reg <- lm(Rev ~ Tx_Ouv)
summary(reg)
Call:
lm(formula = Rev ~ Tx_Ouv)
Residuals:
Min 1Q Median 3Q Max
-17027 -4695 -1308 3146 35569
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 41869.8 440.6 95.02 <2e-16 ***
Tx_Ouv -212907.8 6832.6 -31.16 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 7083 on 862 degrees of freedom
Multiple R-squared: 0.5297, Adjusted R-squared: 0.5292
F-statistic: 971 on 1 and 862 DF, p-value: < 2.2e-16
Des tests peuvent aussi être utilisés pour identifier certains IRIS...
iris[Rev>60000,]
| OBJECTID | N_SQ_IR | C_IR | L_IR | M2_POP | SHAPE_Area | Tx_Mono | Tx_Ouvrier | Revenu | X | Y | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 127 | 171 | 750004228 | 751083210 | Europe 10 | 49685.63 | 99290.84 | 0.2746 | 0.0476 | 60878 | 649440.9 | 6864240 |
| 530 | 777 | 750004500 | 751072806 | Gros Caillou 6 | 46462.97 | 112121.33 | 0.1364 | 0.0517 | 64854 | 648669.4 | 6862085 |
| 531 | 778 | 750004542 | 751072807 | Gros Caillou 7 | 41052.70 | 111841.62 | 0.1424 | 0.0358 | 61048 | 648414.0 | 6861826 |
| 573 | 1112 | 750004136 | 751176608 | Plaine Monceau 8 | 32986.66 | 53491.93 | 0.1526 | 0.0670 | 63174 | 648686.8 | 6865025 |
Données spatiales et chargement de bibliothèques¶
Dans R, pour charger des données spatiales utilisant des formats spécialement conçus à cet effet, il faudra utiliser des bibliothèques qui ne sont pas présentes par défaut dans R. On peut les installer simplement en allant dans "Packages -> Installer le(s) package(s)". Ici, on va commencer avec le package sf. Pour charger ensuite ces bibliothèques, il faut utiliser la fonction library().
library(sf)
Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 7.2.1; sf_use_s2() is TRUE
La bibliothèque sf propose une fonction st_read() qui peut s'appliquer directement à l'adresse du fichier géographique étudié, par exemple le fichier shp d'un shapefile. On peut récupérer cette adresse à l'aide de la fonction file.choose().
adresse <- file.choose()
iris <- st_read(adresse)
Reading layer `IRIS75C' from data source `C:\Users\Serge\Downloads\PARIS(3)\IRIS75C.shp' using driver `ESRI Shapefile' Simple feature collection with 864 features and 15 fields Geometry type: MULTIPOLYGON Dimension: XY Bounding box: xmin: 645280.2 ymin: 6857479 xmax: 657175.3 ymax: 6867083 Projected CRS: RGF93 / Lambert-93
La fonction st_read() crée un objet sf qui peut s'utiliser comme un dataFrame, on peut ainsi utiliser la fonction names() pour connaitre les champs du fichier shapefile chargé ou la fonction head() pour afficher le début de la table attributaire.
names(iris)
- 'OBJECTID'
- 'N_SQ_IR'
- 'C_CAINSEE'
- 'N_QU'
- 'C_IR'
- 'C_TYPEIR'
- 'L_IR'
- 'M2_IP'
- 'M2_POP'
- 'M2_EMP'
- 'SHAPE_Leng'
- 'SHAPE_Area'
- 'Tx_Mono'
- 'Tx_Ouvrier'
- 'Revenu'
- 'geometry'
La fonction st_read() a ajouté une colonne 'geometry' à la table attributaire d'origine, c'est cette colonne que l'on va pouvoir utiliser pour manipuler les géométries des objets spatiaux étudiés. Avec la fonction plot(), on peut simplement afficher ces géométries. Les couleurs de ces géométries peuvent être personnalisées à l'aide de codes hexadécimaux.
plot(iris$geometry)
plot(iris$geometry, col="#777777") # Couleur hexadécimale
Comme pour les dataFrames, on peut étudier les champs de la table attributaire facilement.
revenu <- iris$Revenu
summary(revenu)
Min. 1st Qu. Median Mean 3rd Qu. Max. 9196 23240 30123 30375 36482 64854
A noter que la personnalisation des couleurs des objets géographiques peut être facilement réalisée en utilisant une liste de couleurs de la même taille que le nombre d'objets géographiques.
coul <- rep("#BBBBBB",length(revenu))
plot(iris$geometry, col=coul)
Ainsi, si on opère une modification de cette liste de couleurs à l'aide d'un test qui sert habituellement de filtre, on peut identifier facilement les objets géographiques caractérisés par certaines propriétés.
coul[revenu>50000] <- "#466EE0" # En bleu les élements de la liste ayant un revenu > 50000
plot(iris$geometry, col=coul)
Comme pour un dataFrame, on peut utiliser sur les index pour extraire certains éléments géographiques.
plot(iris$geometry[c(1,2,4)], col='red')
Il serait peut-être un peu fastidieux de définir nous-même l'ensemble des règles permettant de réaliser un simple aplat de couleurs sur des valeurs numériques. C'est pourquoi, on peut utiliser la bibliothèque RColorBrewer (très utilisée par ailleurs pour faire des représentations statistiques sous R) qui propose des palettes de couleurs toutes prêtes. Ainsi la fonction brewer.pal() permet de choisir une palette de couleurs et le nombre de couleurs souhaitées. https://r-graph-gallery.com/38-rcolorbrewers-palettes.html
library(RColorBrewer)
palette <- brewer.pal(n = 5, name = "YlOrRd")
palette
- '#FFFFB2'
- '#FECC5C'
- '#FD8D3C'
- '#F03B20'
- '#BD0026'
On obtient simplement une liste de codes hexadécimaux qu'il faut ensuite associer aux bornes des classes servant à définir une classification. Pour cela, on peut créer la liste des bornes à la main et se servir de la fonction cut() pour associer les bonnes couleurs aux valeurs étudiées.
br <- c(0, 15000, 25000, 35000, 45000, 65000)
a <- cut(revenu, breaks = br, labels = palette)
Pour un plot, il faut que les codes hexadécimaux soient sous la forme de texte (de charactères), on peut pour cela utiliser la fonction as.character().
a <- as.character(cut(revenu, breaks = br, labels = palette))
plot(iris$geometry, col = a, border = "black")
La définition à la main des bornes des classes peut être elle aussi jugée fastidieuse. C'est pourquoi, pour finir, on peut avoir recours à la bibliothèque classInt pour définir ces bornes à l'aide de la fonction classIntervals().
library(classInt)
palette <- brewer.pal(n = 9, name = "YlOrRd")
br <- classIntervals(revenu, n=9, style="quantile")$brks
a <- as.character(cut(revenu, breaks = br, labels = palette))
plot(iris$geometry, col = a, border = "black")