Le langage de pro­gram­ma­tion en R est un langage de pro­gram­ma­tion sta­tis­tique populaire utilisé prin­ci­pa­le­ment en sciences et en ma­thé­ma­tiques pour le calcul sta­tis­tique. R est un langage in­té­res­sant com­por­tant des ca­rac­té­ris­tiques dis­tinctes. Une fois que vous vous y êtes habitués, tra­vail­ler avec ce langage est assez amusant.

Qu’est-ce que le langage de pro­gram­ma­tion en R ?

R n’est pas un langage de pro­gram­ma­tion général tel que Java ou Python. Au contraire, celui-ci est spé­cia­le­ment utile dans le domaine par­ti­cu­lier du Sta­tis­ti­cal Computing, ou calcul sta­tis­tique en français. Dans ce domaine, R figure depuis des années parmi les 20 langages de pro­gram­ma­tion les plus po­pu­laires, et ce malgré une forte con­cur­rence.

Ce qui rend R spécial n’est pas seulement le langage en lui-même, mais l’ensemble de ses ca­rac­té­ris­tiques. La pro­gram­ma­tion en R a gé­né­ra­le­ment lieu dans un en­vi­ron­ne­ment in­te­rac­tif, com­por­tant lecture, éva­lua­tion, im­pres­sion en boucle (Read-Eval-Print Loop ou REPL) et aide intégrée. Le langage Open Source est pris en charge par un éco­sys­tème so­phis­ti­qué ; la com­mu­nauté gère le ré­fé­ren­tiel The Com­pre­hen­sive R Archive Network (CRAN). Les ensembles de données, les livres blancs scien­ti­fiques sur les nouvelles approches et les nouveaux ensembles de données sont également con­ti­nuel­le­ment mis à jour.

Ensemble, ces fonc­tion­na­li­tés font du R l’en­vi­ron­ne­ment de pro­gram­ma­tion idéal pour les sta­tis­tiques et la science des données. En par­ti­cu­lier, la nature in­te­rac­tive de l’en­vi­ron­ne­ment vous invite à la recherche et vous permet d’apprendre le langage et les ma­thé­ma­tiques sous-jacentes de manière ludique.

R est un langage de pro­gram­ma­tion de sta­tis­tique et de données

R est un langage de pro­gram­ma­tion sta­tis­tique qui utilise divers concepts tels que la dis­tri­bu­tion normale, les tests sta­tis­tiques, les modèles et la ré­gres­sion. En plus du R, il existe un certain nombre de langages scien­ti­fiques com­pa­rables. Outre le produit com­mer­cial Matlab, le plus récent langage Julia doit tout par­ti­cu­liè­re­ment être mentionné. De plus, un autre con­cur­rent important ces dernières années est Python.

Con­trai­re­ment à Python, R intègre un support natif pour la pro­gram­ma­tion sta­tis­tique. La dif­fé­rence réside dans la façon dont le langage fonc­tionne par rapport aux valeurs. Les données sont le plus souvent multiples, de sorte que R calcule gé­né­ra­le­ment plusieurs valeurs à la fois. Alors que dans presque tous les autres langages la valeur la plus simple est un nombre unique, R est un cas par­ti­cu­lier.

Les opé­ra­tions ma­thé­ma­tiques peuvent être ef­fec­tuées dans n’importe quel langage de pro­gram­ma­tion. Il­lus­trons l’approche du R en matière de trai­te­ment de données avec un exemple simple. Ici, nous ajoutons deux nombres :

# returns 15
10 + 5
R

Jusqu’à présent rien d’in­ha­bi­tuel. Toutefois, la même opération d’ajout peut être appliquée à une liste de numéros dans R. Nous combinons deux nombres dans une liste et ajoutons une valeur constante :

# returns 15, 25
c(10, 20) + 5
R

Un résultat sur­pre­nant pour les pro­gram­meurs ex­pé­ri­men­tés. Même un langage moderne et dynamique comme Python ne permet pas ceci :

# throws an error
[10, 20] + 5
R

Avec R, vous pouvez même ajouter deux listes. Les éléments de liste ne sont pas combinés, mais l’opération ma­thé­ma­tique ap­pro­priée est exécutée pour chaque élément :

# returns 42, 69
c(40, 60) + c(2, 9)
R

Dans les langages plus anciens tels que Java ou C++, vous avez besoin d’une boucle pour traiter plusieurs éléments d’une liste. Ces langages séparent stric­te­ment les valeurs in­di­vi­duelles, les scalaires, les struc­tures de données com­po­sites et les vecteurs. Avec R, le vecteur est l’unité de base. Un scalaire est un cas par­ti­cu­lier dans la pro­gram­ma­tion en R en tant que vecteur à élément unique.

Pour les sta­tis­tiques, la précision ma­thé­ma­tique a été adoucie, car on s’attend à ce qu’il y ait des in­cer­ti­tudes et des données im­par­faites par rapport à la réalité. Quelque chose peut toujours mal tourner. Heu­reu­se­ment, R est tolérant aux problèmes dans une certaine mesure. Le langage peut traiter les valeurs man­quantes sans provoquer le blocage d’un script en cours d’exécution.

Il­lus­trons la ro­bus­tesse de ce langage avec un exemple. Nor­ma­le­ment, vous pouvez provoquer une erreur dans n’importe quel langage de pro­gram­ma­tion en divisant un nombre par zéro. Cependant, avec R, la valeur Inf est notée comme résultat de la division par zéro, ce qui permet de la filtrer fa­ci­le­ment des données lors d’une étape de nettoyage ul­té­rieure :

# list of divisors, containing zero
divisors = c(2, 4, 0, 10)
# returns `c(50, 25, Inf, 10)`
quotients = 100 / divisors
# filter out Inf; returns `c(50, 25, 10)`
cleaned_quotients = quotients[quotients != Inf]
R

R prend en charge la pro­gram­ma­tion OOP et fonc­tion­nelle

La pro­gram­ma­tion avec R est ex­trê­me­ment flexible, ce langage ne peut pas être clai­re­ment classé dans la hié­rar­chie des pa­ra­digmes de pro­gram­ma­tion. Il est pris en charge par un système OOP, mais les dé­fi­ni­tions de classe ha­bi­tuelles ne seront pas trouvées. Dans le cadre d’une uti­li­sa­tion quo­ti­dienne, les approches fonc­tion­nelles et im­pé­ra­tives sont prin­ci­pa­le­ment utilisées, en par­ti­cu­lier les ca­rac­té­ris­tiques fonc­tion­nelles, qui sont bien adaptées au trai­te­ment des données, sont par­ti­cu­liè­re­ment marquées.

Semblable au Ja­vaS­cript,ce système objet brille par sa flexi­bi­lité. Les fonctions gé­né­riques qui peuvent être ap­pli­quées à des objets de dif­fé­rents types sont si­mi­laires à Python. Par exemple, dans la pro­gram­ma­tion en R se retrouve la fonction length(), semblable à len() de Python.

Comment fonc­tionne la pro­gram­ma­tion en R ?

D La pro­gram­ma­tion en R concerne les données, car c’est sur elles que reposent les sta­tis­tiques. Pour dé­ve­lop­per une solution à un problème, vous avez besoin d’un ensemble de données. Mal­heu­reu­se­ment, cet ensemble n’existe souvent pas au moment du dé­ve­lop­pe­ment. On commence donc souvent un projet de pro­gram­ma­tion en R en simulant des données. Nous écrivons le code, testons la fonc­tion­na­lité et échan­geons ul­té­rieu­re­ment les données de test pour des données réelles.

Comment le code R est-il exécuté ?

Comme Ruby ou Python, R est un langage de script dynamique et in­ter­prété. Con­trai­re­ment au langage C, R ne sépare pas le code source et le code exé­cu­table. Le dé­ve­lop­pe­ment est prin­ci­pa­le­ment in­te­rac­tif, c’est-à-dire qu’on alimente l’in­ter­pré­ta­tion ligne par ligne avec le code source, exécuté en temps réel. Les variables sont générées au­to­ma­ti­que­ment selon les besoins et les noms sont liés au moment de l’exécution.

L’effet de cette pro­gram­ma­tion in­te­rac­tive et dynamique est com­pa­rable à être à l’intérieur du programme en cours d’exécution. Les objets déjà créés peuvent être examinés et modifiés, donc les nouvelles idées peuvent être testées im­mé­dia­te­ment. La commande help permet d’accéder à la do­cu­men­ta­tion relative à la syntaxe et à la fonction :

# view help for `for` syntax
help('for')
# view help for `c()` function
help(c)
R

Les fichiers de script peuvent être chargés dy­na­mi­que­ment à partir de l’in­ter­pré­teur. La commande « source » fonc­tionne comme la commande équi­va­lente « shell ». Lorsqu’elle est appelée, le contenu d’un fichier R source est lu et introduit dans la session en cours :

source('path/to/file.r')
R

Quelle est la syntaxe du langage de pro­gram­ma­tion en R ?

Le langage de script utilise les accolades connues de C et Java pour séparer le corps des fonctions et des ins­truc­tions de contrôle. Con­trai­re­ment à Python, l’in­den­ta­tion de code n’affecte pas sa fonc­tion­na­lité. Les com­men­taires com­men­cent par un hachage, comme dans Ruby et Python, et aucun point-virgule n’est requis à la fin d’une ins­truc­tion.

Avec une certaine ex­pé­rience, le code R peut être reconnu fa­ci­le­ment grâce à certaines par­ti­cu­la­ri­tés du langage. En plus du signe égal comme opérateur d’af­fec­ta­tion, deux opé­ra­teurs de type flèche sont utilisés pour les af­fec­ta­tions. Pour inverser le sens de l’af­fec­ta­tion :

# equivalent assignments
age <- 42
'Jack' -> name
person = c(age, name)
R

Une autre ca­rac­té­ris­tique typique du code R est une notation pseudo-objet de type object.method() :

# test if argument is a number
is.numeric(42)
R

La fonction is.numeric() apparaît comme une méthode numeric() qui ap­par­tient à un objet nommé is. Cependant, ce n’est pas le cas. En pro­gram­ma­tion en R, le point est un caractère régulier, la fonction peut donc être appelée is_numeric au lieu de is.numeric.

La fonction de con­ca­té­na­tion c() est utilisée pour générer les vecteurs om­ni­pré­sents dans la pro­gram­ma­tion en R :

people.ages <- c(42, 51, 69)
R

Si la fonction est appliquée aux vecteurs, ils sont combinés pour former un vecteur contigu :

# yields `c(1, 2, 3, 4)`
c(c(1, 2), c(3, 4))
R

Con­trai­re­ment à la plupart des langages de pro­gram­ma­tion, R commence à indexer les éléments d’un vecteur à 1. Cela demande une certaine adap­ta­tion, mais permet d’éviter les re­dou­tables « off-by-one errors ». L’indice le plus élevé d’un vecteur cor­res­pond à la longueur de ce dernier :

# create a vector of names
people <- c('Jack', 'Jim', 'John')
# access the first name
people[1] == 'Jack'
# access the last name
people[length(people)] == 'John'
R

Comme avec Python, la pro­gram­ma­tion en R inclut également le concept de découpage. Une tranche peut être utilisée pour indexer une partie d’un vecteur. Ceci est basé sur des séquences qui sont prises en charge na­ti­ve­ment. Ci-dessous, nous créons une séquence de numéros et en sé­lec­tion­nons une partie :

# create vector of numbers between 42 and 69
nums = seq(42, 69)
# equivalent assignment using sequence notation
nums = 42:69
# using a sequence, slice elements 3 through 7
sliced = nums[3:7]
R

Comment les struc­tures de contrôle fonc­tion­nent-elles dans la pro­gram­ma­tion en R ?

Les opé­ra­tions de base en pro­gram­ma­tion en R sont définies pour les vecteurs. Ainsi, les boucles sont rarement né­ces­saires car une opération est effectuée di­rec­te­ment sur l’ensemble du vecteur, les éléments in­di­vi­duels étant modifiés. Mettons au carré les dix premiers nombres positifs sans boucle :

nums <- seq(10)
squares <- nums ** 2
squares[3] == 9
R

Lorsque vous utilisez en pro­gram­ma­tion en R une boucle for, il est important de noter que celles-ci ne fonc­tion­nent pas comme en C, Java ou Ja­vaS­cript. Sans passer par une variable de boucle, on itère di­rec­te­ment sur les éléments, comme en Python :

people = c('Jim', 'Jack', 'John')
for (person in people) {
    print(paste('Here comes', person, sep = ' '))
}
R

Bien sûr, en pro­gram­ma­tion en R, on peut utiliser if-else en tant que structure de contrôle de base. Cependant, dans de nombreux cas, elle peut être remplacé par des fonctions de filtrage ou par l’in­dexa­tion logique des vecteurs. Nous créons un vecteur avec d’âges et filtrons les « plus ou moins de 18 ans » en deux variables sans avoir besoin d’une boucle for ou d’un if else :

# create 20 ages between 1 and 99
ages = as.integer(runif(20, 1, 99))
# filter adults
adults = ages[ages > 18]
# filter children
children = ages[ages < 18]
# make sure everyone is accounted for
length(adults) + length(children) == length(ages)
R

Par souci d’ex­haus­ti­vité, l’approche équi­va­lente avec les struc­tures de contrôle :

# create 20 ages between 1 and 99
ages = as.integer(runif(20, 1, 99))
# start with empty vectors
adults = c()
children = c()
# populate vectors
for (age in ages) {
    if (age > 18) {
        adults = c(adults, age)
    }
    else {
        children = c(children, age)
    }
}
R

Qu’est-ce qui est né­ces­saire pour débuter la pro­gram­ma­tion en R ?

Pour débuter la pro­gram­ma­tion en R, vous n’avez besoin que d’une ins­tal­la­tion R locale. Les pro­grammes d’ins­tal­la­tion de tous les prin­ci­paux systèmes d’ex­ploi­ta­tion sont dis­po­nibles pour le té­lé­char­ge­ment. Une ins­tal­la­tion R standard inclut un in­ter­pré­teur graphique avec REPL, une aide intégrée et un éditeur. Pour un codage productif, vous devez utiliser l’un des éditeurs de code établis. R-Studio offre une al­ter­na­tive in­té­res­sante pour l’en­vi­ron­ne­ment R.

Pour quels projets R convient-il ?

La pro­gram­ma­tion en R est fré­quem­ment utilisée en sciences et en recherche, par exemple, en bio-in­for­ma­tique et en ap­pren­tis­sage machine. Toutefois, le langage convient à tous les projets qui utilisent la mo­dé­li­sa­tion sta­tis­tique ou des modèles ma­thé­ma­tiques. Pour le trai­te­ment de texte, la pro­gram­ma­tion en R est moins avancée que Python.

Les calculs et vi­sua­li­sa­tions habituels dans les feuilles de calcul peuvent être remplacés par du code R. Il en résulte une nette sé­pa­ra­tion des préoc­cu­pa­tions, car les données et le code ne sont pas combinés dans les cellules. Cela vous permet d’écrire le code une fois et de l’appliquer à l’ensemble des données. Il n’y a pas non plus de risque d’écraser la formule d’une cellule lors de mo­di­fi­ca­tions manuelles.

Pour les pu­bli­ca­tions scien­ti­fiques, R est considéré comme la référence. La sé­pa­ra­tion du code et des données permet une re­pro­duc­ti­bi­lité scien­ti­fique. L’éco­sys­tème mature d’outils et de packages permet la création de flux de pu­bli­ca­tion efficaces. Les éva­lua­tions et vi­sua­li­sa­tions sont générées au­to­ma­ti­que­ment à partir du code ainsi que des données, puis intégrées dans des documents LaTeX ou RMarkdown de haute qualité.

Aller au menu principal