Chapitre16 Annexe 1 - courte introduction à R

16.1 Les grands principes de R

Le dernier livre de John Chambers (Chambers 2016) insistent beaucoup sur les trois principes fondamentaux de R pour aller plus loin dans la compréhension des mécanismes d’extension de R:

  1. objet: tout ce qui existe dans R est un objet;
  2. function: tout ce qui se passe dans R est un appel à une fonction;
  3. interface: les interfaces avec les autres software sont une partie de R.

Le langage R est performant pour manipuler, analyser et visualiser des données. Utiliser R, c’est utiliser une syntaxe précise pour écrire des requêtes. Ces requêtes induisent, au niveau des unités de calculs de l’ordinateur, la série d’opérations nécessaire pour réaliser les tâches associées aux requêtes soumises. Pour mener une analyse de données avec R, il faut être capable de formuler correctement les requêtes et donc maîtriser la syntaxe de ce langage. Aussi, pour améliorer ces compétences il faut enrichir son vocabulaire (en augmentant ses connaissance des fonctions et packages disponibles) et creuser la question du fonctionnement de R (et se confronter à des questions plus techniques).

L’objectif de cette annexe est de familiariser le lecteur néophyte avec la syntaxe de R en utilisant des exemples de lignes de commande que nous commentons. Nous discutons brièvement de quelques principes fondamentaux du langage et nous couvrons un vocabulaire très limité (nous mentionnons un nombre restreint de fonctions et d’opérateurs). Cette annexe a été conçu pour rendre l’ouvrage autonome. Cependant, cette annexe ne peut constituer à elle seule une introduction au langage R. C’est pourquoi, nous vous recommandons vivement de consulter les trois premiers chapitres de R et espace (REF+ouvrage disponible sur le site de Framabook https://framabook.org/r-et-espace/), et le manuel R pour les débutants d’Emmanuel Paradis (REF+disponible sur le CRAN https://cran.r-project.org/doc/contrib/Paradis-rdebuts_fr.pdf).

16.2 Première commande

Avant de lister les opérations les plus courantes, arrêtons-nous sur cette première ligne de commande pour mieux la comprendre. La première ligne est une assignation, nous demandons à R de réaliser l’opération 1+1 et de stocker le résultat dans une variable, dont le nom est var1. Lorsque la commande est soumise (ce qui correspond à utiliser la touche entrée dans une console R), un certain nombre d’opération ont été réalisées par l’ordinateur, afin que les 1 soient correctement interprétés comme des nombres devant être additionnés (opérateur + qui va engender une addition au niveau des unités de calculs) et finalement le résultat de cette opération va être associé à la variable var1 (opérateur <-)54. Un espace dans la mémoire vive de l’ordinateur a été alloué pour y inclure la variable (incluant son nom et sa valeur) et la variable est disponible dans la session de R.

Il est important de noter dès maintenant que les noms donnés aux variables sont soumis à deux contraintes. Premièrement, un nom de variable doit systématiquement commencer par une lettre latine (minuscule ou majuscule) ou un point (“.”). Deuxièmement, le reste du nom peut-être formé par des lettres latines (minuscules ou majuscules), des chiffres, des points (“.”) et des tirets-bas (“_”). Pour ne pas se perdre dans les noms de vos variables, il est préférable de rester concis et aussi explicite que possible. Notez que si un nom de variable est utilisé dans la console alors que la variable n’a pas été définie, un message d’erreur est retourné.

Si nous rappelons maintenant l’objet var1, il est correctement afficher :

Notons au passage que cette ligne est en réalité équivalent à print(var1), print() étant une fonction (voir le paraphe dédié REF) qui permet d’afficher les objets de R. Parfois, l’utilisateur peut désirer créer une variable et l’afficher immédiatement (ce que nous faisons à plusieurs reprises dans l’ouvrage). Pour ce faire, la ligne de code peut être passer print() :

Pour une économie de cinq lettres, l’utilisateur peut simplement utiliser les parenthèses:

Pour voir l’ensemble des variables utilisé dans la session, utiliser la commande ls() :

Jusqu’ici, nous avons utilisé deux variables: var1 et var2 qui sont donc affichées.

16.3 Pour R, tout est objet

La portion structurée de mémoire vers lequel renvoie un nom de variable est un objet. Pour R, tout est objet, depuis les nombres jusqu’aux fonctions. Pour faire simple, nous pouvons diviser les objets et deux grandes catégories. D’un côté, nous avons les objets de base (p. ex. les vecteurs), de l’autre côté, il y a les objets composés (de type S3 ou S4). Pour se donner une image, les premiers sont les briques élémentaires de R avec lesquelles les seconds (S3 ou S4) sont bâties. Comme nous l’avons énoncé plus haut, les objets S4 étant les plus formels que les S3. Cette distinction technique permet de bien comprendre comment R fonctionne et de mieux comprendre certains messages d’erreur. Nous assignons maintenant différents objets de base à différentes variables tout en excluant les fonctions dont nous parlons plus bas :

votre session de R, la variable

R a été capable de comprendre et d’indexer en mémoire ces différents objets. Ce dernier point enlève une épine du pied de l’utilisateur de R55. Nous pouvons savoir comment R a interprété ces objets avec la fonction typeof()56.

Ces objets sont en fait des vecteurs de différents types et de taille 1. Un vecteur est constitué d’un ou plusieurs éléments de même nature. Il sont construits avec la fonction c(). La taille des vecteurs peut être retournée avec length(). Noter que dans la suite, on ajoute des parenthèses à une ligne donnée pour pouvoir afficher le résultat de l’assignation :

Un ensemble d’objet de même nature peut être contenu dans un tableau doublement indexé, c’est ce qu’on appelle une matrice. Les matrices peuvent être créées à l’aide de la fonction matrix(). Les tableaux peuvent même être indexés dans un nombre quelconque de dimensions grâce aux objets “array” créés avec la fonction array(). Pour appeler une des valeurs de ces tableaux, on utilise les crochets, comme nous le montrons ci-dessous :

Un dernier objet permet de rassembler des objets de nature différentes, il s’agit des listes, pour accéder à l’un de ces objets, on utilise le double crochet et si on souhaite accéder à un objet en particulier dans la liste, on ajoute un crochet.

Nous avons vu les objets de bases les plus importants. Parmi les objets les plus utilisés de R, il y a les “dataframe”. Il s’agit d’objets de type S3, construits avec l’utilisation de la fonction .

Ces objets sont finalement des tableaux dont les colonnes sont des vecteurs. C’est un format très pratique pour travailler sur les données. L’utilisation du \$ vous permet d’accéder à l’un de ces vecteurs, en utilisant le nom de la colonne :

Vous pouvez également utiliser les crochets pour accéder aux différents éléments, comme dans une matrice. Un dernier détail pur savoir s’il s’agit d’un objet S3 ou S4 on utilise la fonction is.object(), si elle retourne TRUE, alors il s’agit d’un objet S3 ou S4. Nous l’utilisons sur notre matrix et notre data.frame.

Pour ces objets composites, une notion importante est la classe de l’objet c’est-à-dire l’espèce à laquelle cet objet appartient. Pour le savoir, il suffit d’utiliser la fonction class().

C’est grâce à la classe que R reconnaît les objets composés. En fait, il est très facile de créer un objet S3 personnalisé dans R grâce à la fonction structure() :

16.3.1 Conditions

Lorsqu’on utilise un langage de programmation, on a souvent besoin de comparer des valeurs. Pour cela, on utilise des tests logiques. Il s’agit de comparaisons entre deux objets dont le résultat est soit “TRUE” (vrai) soit “FALSE” (faux).

Avec R, les tests sont élargis à différents types d’objet. Par exemple, les comparaisons peuvent aussi se faire sur les lettres, c’est alors une question d’ordre alphabétique :

Pour créer des tests logiques un peu plus élaborés et utilisant, on utilise (le “et” logique) et (le “ou” logique).

Avec ces tests logiques, on peut construire des conditons, c’est-à-dire des structure logiques qui permettent de réaliser une opération différente selon le résultat des test.

Selon la valeur de “var1”, l’un des trois messages est affiché. Si c’est la première ou la seconde option qui est choisie, les suivantes ne seront pas explorées. La dernière condition (else seuls) signifie que si les options précédentes n’ont pas été retenues, on utilise celle-ci. La fonction print() permet d’afficher un objet, ici ce sont des chaînes de caractères que l’on affcihe dans la console.

Boucles

Lorsqu’on fait des analyses, il se peut qu’on répète plusieurs fois les mêmes opérations mais pour des données différentes, par exemple pour les différentes colonnes d’un tableaux. Dans ce cas, nous utilisons des boucles. Il existe les boucles for et les boucles while. Les boucles for consiste en une itération de commande sur un ensemble de valeurs pré-déterminée.

L’opérateur est très utile, crée un ensemble de valeur de 1 en 1 depuis “a” jusqu’à “b”. La variable “i” va prendre les valeurs 1,2 et 3 que l’on affiche avec la fonction print(). Il est possible de répéter un ensemble d’opérations qui doivent alors être placées entre accolades. Comme nous l’avons mentionné plus tôt, R dispose d’une structure très flexible de boucle for : une itération sur les valeurs d’un vecteur donnée.

Au contraire des boules for, les boucles while répètent des instructions pour un ensemble de valeur qui n’est pas pré-déterminé. Les instructions sont répétées indéfiniment (donc méfiance avec ces boucles) tant qu’une condition n’est pas respectée.

La manipulation et visualisation des données nécessite rarement l’utilisation des boucles while, les boucles for sont quant à elles fréquemment utilisées.

16.3.2 Les fonctions

De manière générale, en informatique, une fonction est un ensemble de lignes de code dédié à la réalisation d’une tâche spécifique concrétisée par le renvoie d’une valeur (un objet dans R). Nous avons jusqu’ici déjà utiliser différentes fonctions. Le lecteur attentif a certainement remarqué que les fonctions de R présentent toutes une structure commune: elles commencent par une suite de caractères (son nom) suivie de parenthèses à l’intérieur desquelles se trouvent éventuellement un ou plusieurs arguments. Les arguments sont des objets transmis à la fonction qui seront soient ceux manipuler soit précise comment la tâche doit être effectuées. Par exemple, quand nous avons utilisé la ligne :

l’argument “data” sera l’ensemble des valeurs est à utiliser pour remplir la matrice, “ncol” est le nombre de colonne et “nrow”, le nombre de ligne de la matrice. De manière générale, la forme caractéristique de l’appel d’une fonction est :

nomfomction(arg1=obj1, arg2=obj2, arg3=obj3)

Une fonction retourne un objet, et cet objet peut être donnée à une variable. Dans R, c’est un objet qui est retourné que nous pouvons passer à une variable :

var14 <- nomfomction(arg1=obj1, arg2=obj2, arg3=obj3)

Parmi les arguments il existe des argument “par défaut”. Pour ces arguments, il existe un objet prédéfinie qui défini comment la tâche sera réalisée si l’utilisateur ne précise rien. Ainsi, nous n’avons pas défini l’argument “byrow” dont la valeur par défaut est “FALSE”, c’est pourquoi la matrice est remplie colonne par colonne. Pour changer se comportement nous précisons changeons cela :

Dans R, les fonctions sont aussi des objets de type particulier, il existe deux catégories de fonctions :

Pour R, une fonction est un bel et bien un objet dont le contenu est finalement du code. Quand une fonction est appelée sans parenthèse, c’est sont codes qui est renvoyé. De plus, pour une fonction dans un package R, des indications supplémentaires sont retournées entre , pour savoir où cette fonction est localisée.

Cette remarque vous facilitera la compréhension des messages d’erreur : lorsque R parle d’un objet de type “closure” il parle d’une fonction. R est un langage ou votre efficacité repose très fortement sur votre vocabulaire. Pour engranger rapidement un grand nombre de fonctions, la compilation de fonctions proposées par sur le site du CRAN est très utile. Toutes fonctions de R sont assorties d’une documentation qui vous explique, en anglais, comment l’utiliser. Pour y accéder, l’utilisateur a deux possibilités, précéder par un le nom de la fonction ou utiliser la fonction help(), cette dernière permet des recherche plus détaillée.

Les fonctions de R sont très flexible. Avec les arguments par défaut qui permettent de ne pas utiliser l’ensemble des arguments, il y a aussi l’argument sous forme de “…” qui permet de passer des arguments supplémentaires. Ces arguments sont utilisés comme argument de fonctions utilisée à l’intérieur d’une fonction donnée. C’est une utilisation très fréquent dans R.

En utilisant R, on est facilement amené à créer nos propres fonctions, c’est-à-dire des objets de type “closure”. Dans l’exemple ci-dessous, nous créons la fonction affine() qui a trois arguments. Le premier n’a pas de valeur par défaut, l’utilisateur est obligé de le spécifier, pour les deux autres, nous avons ajouté des valeurs par défaut, l’utilisateur à le choix de les changer

Dans une fonction, il n’est pas nécessaire d’écrire tous les noms d’arguments utilisés, nous pouvons simplement indiquer les valeurs. Dans ce cas, l’ordre des valeurs doit être l’ordre des arguments.

L’exemple suivant montre comment profiter des arguments supplémentaires, “…”. Nous créons la fonction affine() qui retourne la valeur de la fonction affine à la puissance n. Nous pourrions ré-écrire l’ensemble des paramètre de la fonction affine mais nous pouvons aussi utiliser les “…”, de la sorte :

Les oublis de l’orthographe exact d’une fonction sont fréquents. Pour chercher efficacement les noms de fonctions par motifs, il existe la fonction apropos() :

References

Chambers, John M. 2016. Extending R. The R Series. Boca Raton London New York: CRC Press.


  1. R propose trois opérateurs d’assignation: <-, = (var1 = 1 + 1) et -> (1 + 1 -> var1) nous utilisons toujours le premier dans cette ouvrage.

  2. C’est un moment difficile à passer quand on utilise des langages de plus bas niveau comme le langage C, sur lequel R repose.

  3. Il est possible d’utiliser la fonction mode() qui est simplement un alias de cette fonction.