Prise en main de R

L'objectif de ce TD est de vous familiariser avec R, un environnement libre pour le calcul statistique.

Ce TP est réalisé sous Linux. Sachez néanmoins que R fonctionne sous Windows et sous MacOS.

Lancer R et le quitter

Lancer R

Ouvrez une fenêtre shell, tapez la commande R et voilà... vous obtenez ce qui suit :

message d'accueil dans R

Les commandes essentielles sont indiquées dans ce message, en particulier comment quitter R. La dernière ligne qui commence par un > est une invite pour que vous tapiez une commande : c'est ce que l'on appelle un « prompt », c'est-à-dire, un signe qui vous indique que le logiciel attend que tapiez quelque chose.

Quitter R

La dernière ligne du message d'accueil vous informe que pour quitter R, il faut taper la commande q() suivie d'un retour-chariot (= touche Entrée). Faites-le ; vous obtenez le résultat suivant :

message de départ de R

Vous avez là la possibilité de sauvegarder votre travail en tapant y (comme 'y'es) suivi d'un retour-chariot, ou de quitter R sans sauvegarder votre travail en tapant n (comme 'n'o), ou encore de revenir dans R en tapant c (comme 'c'ontinue).
Si vous quitter R en sauvegardant votre travail, vous avez aussi la possibilité de récupérer votre travail et de le mettre soit sur votre clé USB, soit vous l'envoyer par email pour travailler chez vous (par exemple). Cela sera expliqué à la fin du TP.

Pour l'heure, le TP ne fait que commencer, donc restez sous R en tapant c (suivi de retour-chariot : il faut toujours taper un retour-chariot après une commande pour la valider et que R la prenne en compte ; on ne le dira donc plus).

R : une calculatrice

Calculs élémentaires

L'utilisation la plus simple de R est de l'utiliser comme une « simple » calculatrice. On verra que c'est en fait une calculatrice très sophistiquée.

Par exemple, tapez la commande suivante (tous les exemples doivent être tapés ; le symbole > indique qu'il s'agît d'une commande R : vous ne devez pas le taper, il est déjà affiché à l'écran) :

> 2+3

R vous répond immédiatement :

[1] 5

Si on laisse de côté le [1] qui sera expliqué plus loin, on obtient bien le résultat attendu.

Naturellement, tous les opérateurs habituels sont disponibles, ainsi que les fonctions logarithmiques, trigonométriques, et bien d'autres.

On peut affecter le résultat d'un calcul à une variable. Une variable est une entité qui porte un nom et qui contient une valeur. Par exemple, si on tape :

> a <- 2 * sqrt (5) + pi

R n'affiche rien, mais il a :

L'affectation se fait donc par l'opérateur <-. À sa gauche, on indique le nom de la variable à laquelle il faut affecter la valeur qui se trouve à sa droite. En passant, vous aurez noter l'utilisation de pi pour obtenir la valeur de π. pi est une variable pré-définie dans R dont la valeur est celle de π.

On peut afficher la valeur d'une variable en tapant simplement son nom :

a
[1] 7.613729

Naturellement, on peut utiliser la valeur d'une variable pour effectuer des calculs, par exemple :

> b <- (a - 1) * (a + 1)

Pour simplifier la saisie des commandes, vous pouvez utiliser la touche flêchée ↑ pour retrouvez les commandes que vous avez déjà tapées et pour les modifier. Ainsi, R garde l'historique des commandes que vous tapez. Vous pouvez remonter dans l'historique avec la touche ↑ et redescendre avec la touche ↓. Quand vous remontez dans l'historique, vous pouvez ensuite utiliser les touches flêchées ← et → pour éditer la commande. Ainsi, utilisez ces touches pour taper la commande suivante, qui diffère peu d'une commande que vous avez tapée plus haut :

> 3 * sqrt (5 + pi)

Prenez l'habitude d'utiliser ces touches flêchées : elles permettent d'accélérer très sensiblement la saisie des commandes, et ceci, même si l'on est déjà habile avec le clavier de son ordinateur.

La table suivante indique des opérateurs et des fonctions de R :

notation en Rvaleur mathématique
a + b somme de a et b
a - b b soustrait de a
a * b produit de a par b
a / b division réelle de a par b
a %/% b division euclidienne (entière) de a par b
a %% b a mod b
a ^ b a à la puissance b
sqrt (a) racine carrée de a
abs (a) valeur absolue de a
log (a) logarithme naturel de de a
exp (a) exponentielle de a
sin (a) sinus de a (en radians)
cos (a) cosinus de a (en radians)
tan (a) tangente de a (en radians)

Cette liste est loin d'être exhaustive !

À tout moment une aide en ligne est accessible avec la commande ?topic, où topic peut être remplacé par n'importe-quelle commande. Essayez, par exemple ?log. (Tapez 'q' pour quitter l'aide.) Il est très important d'apprendre à lire l'aide. L'aide en-ligne contient énormément d'information : elle est là, disponible, c'est à vous d'apprendre à l'utiliser. Les pages d'aide ont toutes la même structure :

Répondre aux questions suivantes en utilisant la documentation en-ligne :

Calculs avec des complexes

Jusqu'à maintenant, on n'a manipulé que des nombres réels. On peut aussi manipuler des nombres complexes directement : si l'on colle un i juste derrière un réel, il devient un nombre imaginaire. Ainsi, 2+3i est un nombre complexe, dont la partie réelle vaut 2, la partie imaginaire vaut 3. (Attention, le i doit être collé au nombre.)

Pour savoir si R fait ses calculs dans les réels ou les complexes, la règle est la suivante : si vous n'utilisez que des nombres réels, R fait les calculs dans l'ensemble des réels. Si un complexe intervient, R fait ses calculs dans les complexes. Ainsi, on peut utiliser la notation 0i qui d'un point de vue mathématique n'a pas beaucoup d'intérêt, pour obliger R à faire ses calculs avec des complexes.

Il existe des fonctions pré-définies spécifiques pour les complexes (partie réelle, partie imaginaire, module, argument, conjugué). Vous taperez ?complex pour en avoir une liste. Par ailleurs, toutes les fonctions réelles vues plus haut sont étendues aux complexes.

Syntaxe des commandes R

L'essentiel de ce qui est à connaître sur la syntaxe des commandes R est d'ors et déjà vu ; on voit ainsi que cette syntaxe est très simple. On la résume ci-dessous :

Vecteurs

Après les simples nombres, un deuxième type fondamental d'entités dans R est le vecteur. Un vecteur peut-être créé de différentes manières. Par exemple, créons un vecteur dont les éléments sont 0, -1, π et 4,78, et mettons-le dans une variable dont le nom est v :

> v <- c (0, -1, pi, 4.78)

La fonction c assemble et construit un vecteur avec ces valeurs. On peut ensuite consulter la valeur des composantes du vecteur :

> v
[1]  0.000000 -1.000000  3.141593  4.780000

On retrouve bien les valeurs avec lesquelles on a initialisé le vecteur.

De nombreuses fonctions s'appliquent aux vecteurs. La table ci-dessous en contient un certain nombre ; essayez-les toutes :

notation en Rvaleur résultat sur l'exemple
length (v) nombre d'éléments de v 4
min (v) valeur de l'élément minimal de v -1
max (v) valeur de l'élément maximal de v 4.78
range (v) vecteur composé des deux valeurs précédentes (le min et le max de v) -1.00 4.78
sum (v) valeur de la somme des éléments de v : Σivi 6.921593
prod (v) valeur du produit des éléments de v : Πivi 0
which.min (v) indice de l'élément minimal de v (arg mini vi) 2
which.max (v) indice de l'élément maximal de v (arg maxi vi) 4

Opérations mathématiques sur les vecteurs

R peut naturellement effectuer toutes les opérations habituelles sur les vecteurs. Les opérateurs vues plus haut sur les nombres (+, -, ...) et les fonctions (abs, log, ...) s'appliquent sur les vecteurs comme on s'y attend. Toutes ces opérations se font terme à terme : aussi, quand il y a deux vecteurs (comme pour une addition), il faut que les deux vecteurs aient le même nombre d'éléments.

Une opération très classique est de calculer le produit scalaire de deux vecteurs :

Enfin, on peut ajouter un scalaire aux éléments d'un vecteur, la soustraire, la multiplier, ... par les opérateurs habituels (+, -, *, ...) en combinant un vecteur et un scalaire. Ainsi,

v + 3

produit un vecteur dont les composantes sont celles de v augmentées de 3.

Indexation des éléments d'un vecteur

On peut aussi demander la valeur du troisième élément du vecteur à l'aide de l'opérateur [ :

v [3]
[1] 3.141593

On peut aussi demander la valeur des éléments 1 et 3 du vecteur en fournissant plusieurs indices, comme suit :

v [c (1, 3)]
[1] 0.000000 3.141593

On voit que pour cela, on a spécifié un vecteur dont les composantes sont les indices qui nous intéressent (c (1, 3) est un vecteur de deux éléments, le premier vaut 1, le second vaut 3).

On vient donc de présenter une opération très utile et très importante en R : accéder aux élements d'un vecteur en utilisant un autre vecteur (dénommé « vecteur d'index ») qui contient le numéro des composantes que l'on veut sélectionner.

Une autre manière de spécifier les indices qui nous intéressent est la suivante : 2:4 est un vecteur dont les éléments sont 2, 3 et 4.

Une autre notation pour la même chose consiste à utiliser la fonction seq(). Ainsi,

> seq (2, 4)

(ou

> seq (from = 2, to = 4)

) produit un vecteur dont les éléments sont 2, 3 et 4.
L'intérêt de cette fonction seq()uence et que l'on peut lui indiquer plus généralement la valeur du premier indice, du dernier indice et de l'incrément pour passer de l'un à l'autre. Ainsi :

> seq (from = 1, to = 10, by = 2)
[1] 1 3 5 7 9

l'incrément peut aussi être négatif :

> seq (from = 10, to = -5, by = -2)
[1] 10  8  6  4  2  0 -2 -4

La fonction runif() génère des nombres pseudo-aléatoires depuis une distribution de probabilité uniforme. On va l'utiliser pour générer des vecteurs aussi grands que l'on veut. Ainsi, tapez :

> vu <- runif (100)

et la variable vu contient un vecteur de 100 composantes dont la valeur a été tirée au hasard entre 0 et 1.

Quelques fonctions statistiques sur les vecteurs

En statistique et fouille de données, un vecteur va typiquement contenir des données sur lesquelles on voudra effectuer des traitements statistiques. Les plus simples sont résumés dans la table ci-dessous :

notation en Rvaleur résultat sur l'exemple
mean (v) la moyenne des éléments de v 1.730398
var (v) la variance des éléments de v 7.246964
sd (v) l'écart-type des éléments de v 2.692019
summary (v) fournit plusieurs statistiques sur les éléments de v Min. 1st Qu. Median Mean 3rd Qu. Max.
-1.000 -0.250 1.571 1.730 3.551 4.780

Indexation par un vecteur de booléens

Outre les nombres, R manipule des booléens, qui prennent soit la valeur TRUE (que l'on peut abréger en T), soit la valeur FALSE (que l'on peut abréger en F).
Les booléens apparaissent typiquement à l'occasion du test de la valeur d'une variable : est-elle égale à une autre valeur, plus petite, plus grande, ... La table ci-dessous indique ces opérateurs :

notation en Rvaleur résultat sur l'exemple
a == 1 teste l'égalité entre deux valeurs FALSE
a != 1 teste la différence entre deux valeurs TRUE
a < 1 c'est clair, non ! FALSE
a <= 1 ça aussi FALSE
a > 1 ça aussi TRUE
a >= 1 ça aussi TRUE

Bien sûr, on peut comparer la valeur de deux variables (donc, écrire a == b qui donne FALSE ici).
De la même manière, on peut effectuer ces opérations sur les éléments d'un vecteur. Ainsi,

> v < w
[1]  TRUE FALSE FALSE FALSE

Tout comme plus haut on a sélectionné les éléments d'un vecteur avec un vecteur d'indices, on peut sélectionner les éléments d'un vecteur avec un vecteur de booléens. Ainsi, si l'on veut affecter à 100 les éléments de v qui sont plus petits que ceux de w, on pourra écrire :

> v [v < w] <- 100

Cette opération ne modifiera que le premier élément de v, qui correspond à la seule valeur TRUE du vecteur de booléens utilisé pour l'indexer.

Quelques détails de plus sur les booléens

Il existe des opérations sur les booléens, celles de l'algèbre de Boole : ET, OU, NON, ... On suppose que l'on a défini deux vecteurs booléens comme suit :

> bool1 <- c (T, T, F)
> bool2 <- c (F, T, F)

On résume les principales opérations logiques dans la table ci-dessous :

notation en Rvaleur résultat sur l'exemple
bool1 & bool2 ET logique FALSE TRUE FALSE
bool1 | bool2 OU logique TRUE TRUE FALSE
! bool1 négation FALSE FALSE TRUE

Les data frames

En statistique et en fouille de données, les données sont généralement disponibles sous forme de tableaux de données, chaque ligne correspondant à une donnée, chaque colonne à un attribut. En R, ces tableaux de données portent le nom de data frame.
Un data frame est en fait un ensemble de vecteurs, tous de la même taille ; chaque vecteur contient la valeur d'un attribut pour l'ensemble des données. S'il y a N données, chaque vecteur contient N valeurs.
De plus, chaque colonne/vecteur du data frame possède un nom qui permet de le référencer : c'est le nom de l'attribut.

Illustrons tout cela sur un exemple. A priori, vous obtenez vos données sous la forme d'un fichier. Par exemple, prenons le fichier que vous obtenez en cliquant ici. Nous indiquons le contenu de ce fichier :

p1-palmitic oleic l1-linoleic arachidic eicosenoic
 1075 7823 672 60 29
 1088 7709 781 61 NA
 911 NA 549 63 29
 966 7952 619 78 35
 1051 7771 672 NA 46
 911 NA 678 70 44
 922 7990 618 56 29

On y voit :

Pour charger ce tableau de données dans une variable R, on utilise la fonction read.table() :

> jeu1 <- read.table
	("http://www.grappa.univ-lille3.fr/~ppreux/ensg/miashs/fouilleDeDonneesI/tp/introduction-a-R/jeu1.txt", header = T)

L'option header = T indique que la première ligne du fichier contient le nom des attributs. Si cette ligne spécifiant le nom des attributs est absente, on ne met pas cette option.

Notons également que le fichier a été récupéré sur le web directement en spécifiant une url. Si le fichier est sur votre compte, vous pouvez aussi le charger bien entendu en donnant son nom (qui ne débutera donc pas par http://... dans ce cas-là).

Vous pouvez maintenant taper jeu1 pour visualiser le tableau de données que vous venez de charger dans cette variable. Vous obtenez :

> jeu1
  p1.palmitic oleic l1.linoleic arachidic eicosenoic
1        1075  7823         672        60         29
2        1088  7709         781        61         NA
3         911    NA         549        63         29
4         966  7952         619        78         35
5        1051  7771         672        NA         46
6         911    NA         678        70         44
7         922  7990         618        56         29

La première ligne indique le nom des attributs ; les lignes sont numérotées.

On peut alors accéder à ces données de différentes manières :

Pour résumer :

Du moment que l'on sait spécifier la donnée ou l'attribut qui nous intéresse, on peut lui appliquer toutes les opérations et fonctions déjà vues. Ainsi,

> mean (jeu1$l1.linoleic)

donne la moyenne de l'attribut l1.linoleic.
Très utile, la fonction summary() s'applique à tous les attributs d'un jeu de données à la fois :

> summary (jeu1)
  p1.palmitic         oleic       l1.linoleic      arachidic
 Min.   : 911.0   Min.   :7709   Min.   :549.0   Min.   :56.00
 1st Qu.: 916.5   1st Qu.:7771   1st Qu.:618.5   1st Qu.:60.25
 Median : 966.0   Median :7823   Median :672.0   Median :62.00
 Mean   : 989.1   Mean   :7849   Mean   :655.6   Mean   :64.67
 3rd Qu.:1063.0   3rd Qu.:7952   3rd Qu.:675.0   3rd Qu.:68.25
 Max.   :1088.0   Max.   :7990   Max.   :781.0   Max.   :78.00
                  NA's   :   2                   NA's   : 1.00
   eicosenoic
 Min.   :29.00
 1st Qu.:29.00
 Median :32.00
 Mean   :35.33
 3rd Qu.:41.75
 Max.   :46.00
 NA's   : 1.00

Quelques fonctions utiles sur les data frames :

Attributs qualitatifs

Naturellement, un attribut peut être qualitatif. Par exemple, le fichier disponible en cliquant ici contient le même jeu de données, si ce n'est que le 5e attribut est qualitatif.

Pour un attribut qualitatif, la commande :

> levels (jeu2$eicosenoic)

fournit la liste des valeurs possibles de cet attribut :

[1] "beaucoup" "moyen"    "pas-mal"  "un-peu"

Dans R, un attribut qualitatif est dénommé un facteur.
On peut très facilement obtenir une table de contingence pour un attribut qualitatif (c'est-à-dire, la répartition des données entre chacune de ses valeurs) par :

> table (jeu2$eicosenoic)

beaucoup    moyen  pas-mal   un-peu
       1        1        1        3

Les NA

La fonction is.na() produit un booléen qui vaut TRUE si son paramètre est une valeur NA. Ainsi,

> is.na (jeu2$eicosenoic)
[1] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE

Quelques graphiques

Les graphiques sont un élément essentiel d'un travail de fouille de données ou de statistique. R permet de faire des tas de graphiques. Nous en voyons quelques uns ici ; nous en verrons d'autres par la suite.

Chargeons un data frame :

> olives <- read.table ("http://www.grappa.univ-lille3.fr/~ppreux/ensg/miashs/datasets/olive.dat")

Pour prendre un peu connaissance avec ce jeu de données, regardez combien il contient de données, ainsi que les attributs. Remarquons qu'ici, les attributs ne portent pas de nom. Par défaut, R leur donne donc les noms V1, V2, ...

Si l'on veut visualiser l'attribut V3, on tape la commande :

> plot (olives$V3)

On obtient ainsi une représentation planaire de cet attribut : en abscisses, on a simplement le numéro de la donnée, et en ordonnées, la valeur de cet attribut pour cette donnée.

On peut alors éventuellement distinguer des tendances. Vous voyez quelque chose ici ?

(On y reviendra durant le cours régulièrement mais disons-le dès maintenant : face à un jeu de données que l'on doit étudier, il est toujours bon de commencer par y jeter un coup d'œil. Parfois, des propriétés remarquables sautent aux yeux ; l'analyse permettra de quantifier ces choses qui auront été vues, voire, parfois, de démontrer que ce que l'on a cru voir n'existe pas, du moins qu'il n'est pas statistiquement significatif.)

Pour faire un travail sérieux, il convient de mettre des légendes à ce graphique : une légende sur chacun des deux axes, un titre et les points en bleu :

> plot (olives$V3, main = "attribut 3 du jeu de données olives", xlab = "numéro de la donnée", ylab = "V3", col = "blue")

On peut aussi vouloir obtenir le graphe de l'attribut V6 en fonction de l'attribut V3 (n'oublions pas qu'en fouille de données, l'activité de base consiste à trouver des corrélations entre attributs, linéaires ou pas). On obtient ce graphe comme suit :

> plot (olives$V3, olives$V6)

où vous ajouterez les options nécessaires pour obtenir les légendes adéquates.

Typiquement, quand vous avez fait un joli graphique, vous avez envie de pouvoir le récupérer dans un fichier pourl'insérer dans un compte-rendu ou autre rapport. R peut ainsi générer des graphiques à l'écran, mais aussi dans des fichiers aux formats jpg, pdf ou png (pour ne citer que les principaux).

Supposons que vous vouliez obtenir un fichier pdf, vous tapez la commande :

> pdf ("mon-graphique.pdf")

Vous retapez la commande qui a généré votre graphique plus haut et celui-ci ira se mettre dans le fichier mon-graphique.pdf.

Ensuite, pour obtenir à nouveau l'affichage à l'écran, vous tapez la commande :

> dev.off()

Si vous voulez obtenir un fichier jpg, vous utilisez la commande jpeg() ; pour un fichier png, vous utilisez la commande png().

Récupérer son travail quand on a quitté R

Comme on l'a vu au début du TP, quand vous quittez R, vous pouvez sauvegarder votre travail pour la prochaine séance ou pour l'emmener chez vous, ...

Pour cela, il faut savoir que lorsque vous quittez R en sauvegardant votre travail, R place celui-ci dans deux fichiers dénommés .RData et .Rhistory. Ce sont ces deux fichiers qu'il vous faut récupérer et mettre sur votre clé USB ou vous envoyez par email en pièces jointes par exemple.

Références

Pour aller plus loin en R, mieux comprendre ce que l'on vient de faire et ce que l'on fera, et mieux connaître R :