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.

In [1]:
2 + 3
5

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 <-

In [2]:
a <- 2
b <- 3
a + b
5

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.

In [3]:
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 :

In [4]:
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.

In [5]:
a
2
In [6]:
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 "".

In [7]:
a <- "Texte"
a
'Texte'

La fonction class() permet de connaitre la typologie d'un objet.

In [8]:
class(a)
'character'

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.

In [9]:
b <- c(18, 182, 1.5, 15, 200, 5)
b
  1. 18
  2. 182
  3. 1.5
  4. 15
  5. 200
  6. 5

Si l'on veut plutôt créer un tableau de valeurs, on pourra utiliser les matrices :

In [10]:
c <- matrix(c (18, 182, 1.5, 15, 200, 5), nrow = 2)
c
A matrix: 2 × 3 of type dbl
18 1.5200
18215.0 5

Au sein d'une fonction, on peut trouver des arguments facultatifs que l'on peut utiliser en utilisant le signe =

In [11]:
d <- matrix(b, ncol = 2)
d
A matrix: 3 × 2 of type dbl
18.0 15
182.0200
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 :

In [12]:
b[1]
18
In [13]:
e <- b[2] + b[3]
e
183.5

Pour des tableaux comme les matrices par exemple, on pourra faire référence au numéro de ligne et de colonne :

In [14]:
c[1,2]
1.5

On peut utiliser ces index pour modifier une valeur spécifique.

In [15]:
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 # .

In [16]:
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.

In [17]:
b[c(1,3)]
  1. 18
  2. 1.5

De même, il est possible d'utiliser des tests.

In [18]:
2 < 10
TRUE
In [19]:
b < 10
  1. FALSE
  2. FALSE
  3. TRUE
  4. FALSE
  5. FALSE
  6. TRUE
In [20]:
b[ b < 10]
  1. 1.5
  2. 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.

In [21]:
df <- data.frame(col, col2)
df
A data.frame: 3 × 2
colcol2
<dbl><dbl>
18.0 15
182.0200
1.5 5
In [22]:
class(df)
'data.frame'

Généralement, à ces colonnes sont associés des noms de colonne.

In [23]:
df2 <- data.frame(taille = col, age = col2)
df2
A data.frame: 3 × 2
tailleage
<dbl><dbl>
18.0 15
182.0200
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.

In [24]:
df2[,1]
  1. 18
  2. 182
  3. 1.5
In [25]:
df2$taille
  1. 18
  2. 182
  3. 1.5

La fonction names() permet de récupérer les noms des colonnes d'un dataFrame.

In [26]:
names(df2)
  1. 'taille'
  2. 'age'

Statistique et visualisation graphique¶

R propose plein de fonctions permettant de calculer les principaux indicateurs statistiques

In [27]:
mean(b)
70.25
In [28]:
median(b)
16.5
In [29]:
sd(b) # écart-type
93.9040733940759
In [30]:
var(b)
8817.975
In [31]:
min(b)
1.5
In [32]:
max(b)
200
In [33]:
sum(b)
421.5

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.

In [34]:
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.

In [35]:
length(b)
6

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().

In [36]:
plot(d[,1],d[,2])
No description has been provided for this image
In [37]:
plot(d[,1],d[,2], col = 'red', main = 'Graphique', xlab = 'X', ylab = 'Y')
No description has been provided for this image

Mais R propose bien d'autres représentations comme les histogrammes par exemple.

In [38]:
hist(b)
No description has been provided for this image

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.

In [ ]:
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...

In [39]:
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
In [40]:
plot(d[,1],d[,2])
abline(reg)
No description has been provided for this image

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().

In [41]:
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...

In [42]:
ad
'C:\\Users\\Serge\\Downloads\\PARIS(3)\\IRIS.csv'

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.

In [43]:
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.

In [62]:
head(iris)
OBJECTIDN_SQ_IRC_IRL_IRM2_POPSHAPE_AreaTx_MonoTx_OuvrierRevenuXY
20 750004033 751186922 Grandes Carri?¿res 2242891.78 80920.79 0.1699 0.0517 31376 651225.3 6866376
21 750004043 751186923 Grandes Carri?¿res 2351939.49 68661.34 0.3265 0.0875 21229 650861.0 6866264
22 750004027 751186924 Grandes Carri?¿res 2443233.73 73724.51 0.3491 0.0701 17436 650950.0 6866511
23 750004026 751186925 Grandes Carri?¿res 2537176.58 81608.21 0.5014 0.1773 13180 651420.2 6866557
24 750004862 751186926 Grandes Carri?¿res 2638308.33 176037.03 0.5323 0.1397 10465 651645.9 6866858
25 750004020 751186927 Grandes Carri?¿res 2721445.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().

In [63]:
iris[1:10,]
OBJECTIDN_SQ_IRC_IRL_IRM2_POPSHAPE_AreaTx_MonoTx_OuvrierRevenuXY
20 750004033 751186922 Grandes Carri?¿res 2242891.78 80920.79 0.1699 0.0517 31376 651225.3 6866376
21 750004043 751186923 Grandes Carri?¿res 2351939.49 68661.34 0.3265 0.0875 21229 650861.0 6866264
22 750004027 751186924 Grandes Carri?¿res 2443233.73 73724.51 0.3491 0.0701 17436 650950.0 6866511
23 750004026 751186925 Grandes Carri?¿res 2537176.58 81608.21 0.5014 0.1773 13180 651420.2 6866557
24 750004862 751186926 Grandes Carri?¿res 2638308.33 176037.03 0.5323 0.1397 10465 651645.9 6866858
25 750004020 751186927 Grandes Carri?¿res 2721445.84 44308.01 0.5561 0.1739 10986 651526.2 6866707
26 750004019 751186928 Grandes Carri?¿res 2822749.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
In [44]:
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  
In [46]:
length(iris) # permet de récupérer la taille du tableau ici le nombre de colonnes.
11
In [47]:
length(iris[,1]) # permet de récupérer la taille d'une colonne, ici le nombre d'IRIS du 75.
864

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.

In [48]:
names(iris)
  1. 'OBJECTID'
  2. 'N_SQ_IR'
  3. 'C_IR'
  4. 'L_IR'
  5. 'M2_POP'
  6. 'SHAPE_Area'
  7. 'Tx_Mono'
  8. 'Tx_Ouvrier'
  9. 'Revenu'
  10. 'X'
  11. 'Y'
In [49]:
Tx_Ouv <- iris$Tx_Ouvrier
Rev <- iris$Revenu
In [50]:
plot(Tx_Ouv, Rev)
No description has been provided for this image
In [51]:
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...

In [84]:
iris[Rev>60000,]
OBJECTIDN_SQ_IRC_IRL_IRM2_POPSHAPE_AreaTx_MonoTx_OuvrierRevenuXY
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
5731112 750004136 751176608 Plaine Monceau 832986.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().

In [53]:
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().

In [54]:
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.

In [55]:
names(iris)
  1. 'OBJECTID'
  2. 'N_SQ_IR'
  3. 'C_CAINSEE'
  4. 'N_QU'
  5. 'C_IR'
  6. 'C_TYPEIR'
  7. 'L_IR'
  8. 'M2_IP'
  9. 'M2_POP'
  10. 'M2_EMP'
  11. 'SHAPE_Leng'
  12. 'SHAPE_Area'
  13. 'Tx_Mono'
  14. 'Tx_Ouvrier'
  15. 'Revenu'
  16. '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.

In [56]:
plot(iris$geometry)
No description has been provided for this image
In [57]:
plot(iris$geometry, col="#777777") # Couleur hexadécimale
No description has been provided for this image

Comme pour les dataFrames, on peut étudier les champs de la table attributaire facilement.

In [58]:
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.

In [59]:
coul <- rep("#BBBBBB",length(revenu))
plot(iris$geometry, col=coul)
No description has been provided for this image

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.

In [60]:
coul[revenu>50000] <- "#466EE0" # En bleu les élements de la liste ayant un revenu > 50000
plot(iris$geometry, col=coul)
No description has been provided for this image

Comme pour un dataFrame, on peut utiliser sur les index pour extraire certains éléments géographiques.

In [61]:
plot(iris$geometry[c(1,2,4)], col='red')
No description has been provided for this image

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

In [62]:
library(RColorBrewer)
palette <- brewer.pal(n = 5, name = "YlOrRd")
palette
  1. '#FFFFB2'
  2. '#FECC5C'
  3. '#FD8D3C'
  4. '#F03B20'
  5. '#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.

In [63]:
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().

In [64]:
a <- as.character(cut(revenu, breaks = br, labels = palette))
plot(iris$geometry, col = a, border = "black")
No description has been provided for this image

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().

In [65]:
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")
No description has been provided for this image