IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours complet pour débutants pour apprendre la programmation en R


précédentsommairesuivant

3. Opérateurs et fonctions

Objectifs du chapitre

  • Tirer profit de l'arithmétique vectorielle caractéristique du langage R dans les calculs.
  • Utiliser les opérateurs R les plus courants, notamment pour le traitement des vecteurs, le calcul de sommaires et la manipulation des matrices et tableaux.
  • Faire l'appel d'une fonction dans R ; concevoir comment les arguments sont passés à la fonction et le traitement des valeurs par défaut.
  • Utiliser la fonction if pour l'exécution conditionnelle de commandes R.
  • Distinguer la construction if() … else de la fonction ifelse.
  • Faire des boucles en R.
  • Choisir entre les opérateurs for, while et repeat lors de la construction d'une boucle R.

Ce chapitre présente les principaux opérateurs arithmétiques, fonctions mathématiques et structures de contrôle disponibles dans R. La liste est évidemment loin d'être exhaustive, surtout étant donné l'évolution rapide du langage. Un des meilleurs endroits pour découvrir de nouvelles fonctions demeure la section See Also des rubriques d'aide, qui offre des hyperliens vers des fonctions apparentées au sujet de la rubrique.

Énoncé du problème

On s'intéresse à la somme des résultats du lancer de deux dés. Le premier dé compte 8 faces et le deuxième, 6. On souhaite calculer la moyenne des résultats de la somme supérieurs à 7.

3-1. Opérations arithmétiques

L'unité de base en R est le vecteur.

  • Les opérations sur les vecteurs sont effectuées élément par élément :

     
    Sélectionnez
    1.
    2.
    3.
    4.
    > c(1, 2, 3) + c(4, 5, 6)
    [1] 5 7 9
    > 1:3 * 4:6
    [1] 4 10 18
    
  • Si les vecteurs impliqués dans une expression arithmétique ne sont pas de la même longueur, les plus courts sont recyclés de façon à correspondre au plus long vecteur. Cette règle est particulièrement apparente avec les vecteurs de longueur 1 :

     
    Sélectionnez
    1.
    2.
    3.
    4.
    > 1:10 + 2
    [1] 3 4 5 6 7 8 9 10 11 12
    > 1:10 + rep(2, 10)
    [1] 3 4 5 6 7 8 9 10 11 12
    
  • Si la longueur du plus long vecteur est un multiple de celle du ou des autres vecteurs, ces derniers sont recyclés un nombre entier de fois :

     
    Sélectionnez
    1.
    2.
    3.
    4.
    > 1:10 + 1:5 + c(2, 4) # vecteurs recyclés 2 et 5 fois
    [1] 4 8 8 12 12 11 11 15 15 19
    > 1:10 + rep(1:5, 2) + rep(c(2, 4), 5) # équivalent
    [1] 4 8 8 12 12 11 11 15 15 19
    
  • Sinon, le plus court vecteur est recyclé un nombre fractionnaire de fois, mais comme ce résultat est rarement souhaité et provient généralement d'une erreur de programmation, un avertissement est affiché :
 
Sélectionnez
1.
2.
3.
4.
5.
> 1:10 + c(2, 4, 6)
[1] 3 6 9 6 9 12 9 12 15 12
Message d′avis :
In 1:10 + c(2, 4, 6) :
la taille d′un objet plus long n′est pas un multiple de la taille d′un objet plus court
Tab. 3.1 - Principaux opérateurs du langage R, en ordre décroissant de priorité

Opérateur

Fonction

$

extraction d'une liste

^

puissance

-

changement de signe

:

génération de suites

%*% %% %/%

produit matriciel, modulo, division entière

* /

multiplication, division

+ -

addition, soustraction

< <= == >= > !=

plus petit, plus petit ou égal, égal, plus grand ou égal, plus grand, différent de

!

négation logique

& &&

« et » logique

|, ||

« ou » logique

-> ->>

assignation

<- <<-

assignation

Grâce à la propriété d'opération élément par élément de R, il devrait être possible — en fait, il est souhaitable — de résoudre le problème sans avoir recours à des boucles.

3-2. Opérateurs

Le tableau 3.1 présente les opérateurs mathématiques et logiques les plus fréquemment employés, en ordre décroissant de priorité des opérations. Le tableau contient également les opérateurs d'assignation et d'extraction présentés au chapitre précédent ; il est utile de connaître leur niveau de priorité dans les expressions R.

Les opérateurs de puissance (^) et d'assignation à gauche (<-, <<-) sont évalués de droite à gauche ; tous les autres de gauche à droite. Ainsi, 2^2^3 est 2^8, et non 4^3, alors que 1 - 1 - 1 vaut -1, et non 1.

3-3. Appels de fonctions

Les opérateurs du tableau 3.1 constituent des raccourcis utiles pour accéder aux fonctions les plus courantes de R. Pour toutes les autres, il faut appeler la fonction directement. Cette section passe en revue les règles d'appels d'une fonction et la façon de spécifier les arguments, qu'il s'agisse d'une fonction interne de R ou d'une fonction personnelle (voir le chapitre 5Fonctions définies par l'usager).

  • Il n'y a pas de limite pratique quant au nombre d'arguments que peut avoir une fonction.
  • Les arguments d'une fonction peuvent être spécifiés selon l'ordre établi dans la définition de la fonction. Cependant, il est beaucoup plus prudent et fortement recommandé de spécifier les arguments par leur nom, avec une construction de la forme nom = valeur, surtout après les deux ou trois premiers arguments.
  • L'ordre des arguments est important ; il est donc nécessaire de les nommer s'ils ne sont pas appelés dans l'ordre.
  • Certains arguments ont une valeur par défaut qui sera utilisée si l'argument n'est pas spécifié dans l'appel de la fonction.

Par exemple, la définition de la fonction matrix est la suivante :

 
Sélectionnez
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,
dimnames = NULL)
  • La fonction compte cinq arguments : data, nrow, ncol, byrow et dimnames.
  • Ici, chaque argument a une valeur par défaut (ce n'est pas toujours le cas). Ainsi, un appel à matrix sans argument résulte en une matrice 1 × 1 remplie par colonne (sans importance, ici) de l'objet NA et dont les dimensions sont dépourvues d'étiquettes :
 
Sélectionnez
> matrix()
[,1]
[1,] NA
  • Appel plus élaboré utilisant tous les arguments. Le premier argument est rarement nommé :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
> matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE,
+ dimnames = list(c("Gauche", "Droit"),
+ c("Rouge", "Vert", "Bleu")))
       Rouge Vert Bleu
Gauche     1    2    3
 Droit     4    5    6

3-4. Quelques fonctions utiles

Le langage R compte un très grand nombre (des milliers !) de fonctions internes. Cette section en présente quelques-unes seulement, les fonctions de base les plus souvent utilisées pour programmer en R et pour manipuler des données.

Pour chaque fonction présentée dans les sections suivantes, on fournit un ou deux exemples d'utilisation. Ces exemples sont souvent loin de couvrir toutes les utilisations possibles d'une fonction. La section 3.7Exemples fournit des exemples additionnels, mais il est recommandé de consulter les diverses rubriques d'aide pour connaître toutes les options des fonctions.

3-4-1. Manipulation de vecteurs

seq

génération de suites de nombres

 
Sélectionnez
> seq(1, 9, by = 2)
[1] 1 3 5 7 9

seq_len

version plus rapide de seq pour générer la suite des nombres de 1 à la valeur de l'argument

 
Sélectionnez
> seq_len(10)
[1] 1 2 3 4 5 6 7 8 9 10

rep

répétition de valeurs ou de vecteurs

 
Sélectionnez
> rep(2, 10)
[1] 2 2 2 2 2 2 2 2 2 2

sort

tri en ordre croissant ou décroissant

 
Sélectionnez
> sort(c(4, -1, 2, 6))
[1] -1 2 4 6

rank

rang des éléments d'un vecteur dans l'ordre croissant ou décroissant

 
Sélectionnez
> rank(c(4, -1, 2, 6))
[1] 3 1 2 4

Image non disponible order

ordre d'extraction des éléments d'un vecteur pour les placer en ordre croissant ou décroissant

 
Sélectionnez
> order(c(4, -1, 2, 6))
[1] 2 3 1 4

rev

renverser un vecteur

 
Sélectionnez
> rev(1:10)
[1] 10 9 8 7 6 5 4 3 2 1

head

extraction des n premiers éléments d'un vecteur (n > 0) ou suppression des n derniers (n < 0)

 
Sélectionnez
> head(1:10, 3); head(1:10, -3)
[1] 1 2 3
[1] 1 2 3 4 5 6 7

tail

extraction des n derniers éléments d'un vecteur (n > 0) ou suppression des n premiers (n < 0)

 
Sélectionnez
> tail(1:10, 3); tail(1:10, -3)
[1]  8  9 10
[1]  4  5  6  7  8  9 10

unique

extraction des éléments différents d'un vecteur

 
Sélectionnez
> unique(c(2, 4, 2, 5, 9, 5, 0))
[1] 2 4 5 9 0

3-4-2. Recherche d'éléments dans un vecteur

Les fonctions de cette sous-section sont toutes illustrées avec le vecteur

 
Sélectionnez
> x
[1] 4 -1 2 -3 6

which

positions des valeurs TRUE dans un vecteur booléen

 
Sélectionnez
> which(x < 0)
[1] 2 4

which.min

position du minimum dans un vecteur

 
Sélectionnez
> which.min(x)
[1] 4

which.max

position du maximum dans un vecteur

 
Sélectionnez
> which.max(x)
[1] 5

match

position de la première occurrence d'un élément dans un vecteur

 
Sélectionnez
> match(2, x)
[1] 3

%in%

appartenance d'une ou plusieurs valeurs à un vecteur

 
Sélectionnez
> -1:2 %in% x
[1] TRUE FALSE FALSE TRUE

3-4-3. Arrondi

Les fonctions de cette sous-section sont toutes illustrées avec le vecteur

 
Sélectionnez
> x
[1] -3.6800000 -0.6666667 3.1415927 0.3333333
[5]  2.5200000

round

arrondi à un nombre défini de décimales (par défaut 0)

 
Sélectionnez
> round(x)
[1] -4 -1 3 0 3
> round(x, 3)
[1] -3.680 -0.667 3.142 0.333 2.520

floor

plus grand entier inférieur ou égal à l'argument

 
Sélectionnez
> floor(x)
[1] -4 -1 3 0 2

ceiling

plus petit entier supérieur ou égal à l'argument

 
Sélectionnez
> ceiling(x)
[1] -3 0 4 1 3

trunc

troncature vers zéro ; différent de floor pour les nombres négatifs

 
Sélectionnez
> trunc(x)
[1] -3 0 3 0 2

3-4-4. Sommaires et statistiques descriptives

Les fonctions de cette sous-section sont toutes illustrées avec le vecteur

 
Sélectionnez
> x
[1] 14 17 7 9 3 4 25 21 24 11

sum, prod

somme et produit des éléments d'un vecteur

 
Sélectionnez
> sum(x); prod(x)
[1] 135
[1] 24938020800

diff

différences entre les éléments d'un vecteur (opérateur mathématique ∇)

 
Sélectionnez
> diff(x)
[1] 3 -10 2 -6 1 21 -4 3 -13

mean

moyenne arithmétique (et moyenne tronquée avec l'argument trim)

 
Sélectionnez
> mean(x)
[1] 13.5

var, sd

variance et écart type (versions sans biais)

 
Sélectionnez
> var(x)
[1] 64.5

min, max

minimum et maximum d'un vecteur

 
Sélectionnez
> min(x); max(x)
[1] 3
[1] 25

range

vecteur contenant le minimum et le maximum d'un vecteur

 
Sélectionnez
> range(x)
[1] 3 25

median

médiane empirique

 
Sélectionnez
> median(x)
[1] 12.5

quantile

quantiles empiriques

 
Sélectionnez
> quantile(x)
 0% 25%  50%  75% 100%
3.0 7.5 12.5 20.0 25.0

summary

statistiques descriptives d'un échantillon

 
Sélectionnez
> summary(x)
Min. 1st Qu. Median Mean 3rd Qu. Max.
 3.0     7.5   12.5 13.5    20.0 25.0

La fonction mean permettra de calculer la moyenne des résultats supérieurs à 7.

3-4-5. Sommaires cumulatifs et comparaisons élément par élément

Les fonctions de cette sous-section sont toutes illustrées avec le vecteur

 
Sélectionnez
> x
[1] 14 17 7 9 3

cumsum, cumprod

somme et produit cumulatif d'un vecteur

 
Sélectionnez
> cumsum(x); cumprod(x)
[1] 14  31   38    47    50
[1] 14 238 1666 14994 44982

cummin, cummax

minimum et maximum cumulatif

 
Sélectionnez
> cummin(x); cummax(x)
[1] 14 14  7  7  3
[1] 14 17 17 17 17

pmin, pmax

minimum et maximum élément par élément (en parallèle) entre deux vecteurs ou plus

 
Sélectionnez
> pmin(x, 12)
[1] 12 12 7 9 3
> pmax(x, c(16, 23, 4, 12, 3))
[1] 16 23 7 12 3

3-4-6. Opérations sur les matrices

Les fonctions de cette sous-section sont toutes illustrées avec la matrice

 
Sélectionnez
> x
     [,1] [,2]
[1,]    2    4
[2,]    1    3

nrow, ncol

nombre de lignes et de colonnes d'une matrice

 
Sélectionnez
> nrow(x); ncol(x)
[1] 2
[1] 2

rowSums, colSums

sommes par ligne et par colonne, respectivement, des éléments d'une matrice ; voir aussi la fonction apply à la section 6.2Fonction apply

 
Sélectionnez
> rowSums(x)
[1] 6 4

rowMeans, colMeans

moyennes par ligne et par colonne, respectivement, des éléments d'une matrice ; voir aussi la fonction apply à la section 6.2Fonction apply

 
Sélectionnez
> colMeans(x)
[1] 1.5 3.5

t

transposée

 
Sélectionnez
> t(x)
     [,1] [,2]
[1,]    2    1
[2,]    4    3

det

déterminant

 
Sélectionnez
> det(x)
[1] 2

solve

1) avec un seul argument (une matrice carrée) : inverse d'une matrice ; 2) avec deux arguments (une matrice carrée et un vecteur) : solution du système d'équations linéaires Ax = b

 
Sélectionnez
> solve(x)
     [,1] [,2]
[1,]  1.5   -2
[2,] -0.5 1
> solve(x, c(1, 2))
[1] -2.5 1.5

diag

1) avec une matrice en argument : diagonale de la matrice ; 2) avec un vecteur en argument : matrice diagonale formée avec le vecteur ; 3) avec un scalaire p en argument : matrice identité p × p

 
Sélectionnez
> diag(x)
[1] 2 3

3-4-7. Produit extérieur

La Image non disponiblefonction outer calcule le produit extérieur entre deux vecteurs. Ce n'est pas la fonction la plus intuitive à utiliser, mais elle s'avère extrêmement utile pour faire plusieurs opérations en une seule expression tout en évitant les boucles. La syntaxe de outer est :

 
Sélectionnez
outer(X, Y, FUN)

Le résultat est l'application la fonction FUN ("*" par défaut) entre chacun des éléments de X et chacun des éléments de Y, autrement dit

 
Sélectionnez
FUN(X[i], Y[j])

pour toutes les valeurs des indices i et j.

  • La dimension du résultat est par conséquent c(dim(X), dim(Y)).
  • Par exemple, le résultat du produit extérieur entre deux vecteurs est une matrice contenant tous les produits entre les éléments des deux vecteurs :

     
    Sélectionnez
    > outer(c(1, 2, 5), c(2, 3, 6))
         [,1] [,2] [,3]
    [1,]    2    3    6
    [2,]    4    6   12
    [3,]   10   15   30
  • Lorsque FUN est un opérateur arithmétique du tableau 3.1, on place le symbole entre guillemets : "*", "+", "<=", etc.

  • L'opérateur %o% est un raccourci de outer(X, Y, "*").

Nous avons trouvé ici la fonction clé pour résoudre notre problème sans faire de boucles. La fonction outer permet de calculer facilement tous les résultats possibles de la somme de deux dés :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
> x <- 1:8 # résultats possibles du premier dé
> y <- 1:6 # résultats possibles du second dé
> outer(x, y, "+") # sommes de toutes les combinaisons
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    3    4    5    6    7
[2,]    3    4    5    6    7    8
[3,]    4    5    6    7    8    9
[4,]    5    6    7    8    9   10
[5,]    6    7    8    9   10   11
[6,]    7    8    9   10   11   12
[7,]    8    9   10   11   12   13
[8,]    9   10   11   12   13   14

3-5. Structures de contrôle

Les structures de contrôle sont des commandes qui permettent de déterminer le flux d'exécution d'un programme : choix entre des blocs de code, répétition de commandes ou sortie forcée.

On se contente, ici, de mentionner les structures de contrôle disponibles en R. La section 3.7Exemples fournit des exemples d'utilisation.

3-5-1. Exécution conditionnelle

 
Sélectionnez
if (condition) branche.vrai else branche.faux

Si condition est vraie, branche.vrai est exécutée, sinon ce sera branche.faux. Dans le cas où l'une ou l'autre de branche.vrai ou branche.faux comporte plus d'une expression, regrouper celles-ci dans des accolades { }.

 
Sélectionnez
ifelse(condition, expression.vrai, expression.faux)

Fonction vectorielle qui retourne un vecteur de la même longueur que condition formé ainsi : pour chaque élément TRUE de condition on choisit l'élément correspondant de expression.vrai et pour chaque élément FALSE on choisit l'élément correspondant de expression.faux. L'utilisation n'est pas très intuitive, alors examiner attentivement les exemples de la rubrique d'aide.

 
Sélectionnez
switch(test, cas.1 = action.1, cas.2 = action.2, ...)

Structure utilisée plutôt rarement. Consulter la rubrique d'aide au besoin.

3-5-2. Boucles

Les boucles sont et doivent être utilisées avec parcimonie en R, car elles sont généralement inefficaces. Dans la majeure partie des cas, il est possible de vectoriser les calculs pour éviter les boucles explicites, ou encore de s'en remettre aux fonctions outer, apply, lapplysapply et mapply (section 6.2Fonction apply) pour réaliser les boucles de manière plus efficace.

 
Sélectionnez
for (variable in suite) expression

Exécuter expression successivement pour chaque valeur de variable contenue dans suite. Encore ici, on groupera les expressions dans des accolades { }. À noter que suite n'a pas à être composée de nombres consécutifs, ni même de nombres, en fait.

 
Sélectionnez
while (condition) expression

Exécuter expression tant que condition est vraie. Si condition est fausse lors de l'entrée dans la boucle, celle-ci n'est pas exécutée. Une boucle while n'est par conséquent pas nécessairement toujours exécutée.

 
Sélectionnez
repeat expression

Répéter expression. Cette dernière devra comporter un test d'arrêt qui utilisera la commande break. Une boucle repeat est toujours exécutée au moins une fois.

 
Sélectionnez
break

Sortie immédiate d'une boucle for, while ou repeat.

 
Sélectionnez
next

Passage immédiat à la prochaine itération d'une boucle for, while ou repeat.

3-6. Fonctions additionnelles

La bibliothèque des fonctions internes de R est divisée en ensembles de fonctions et de jeux de données apparentés nommés packages (terme que l'équipe de traduction française de R a choisi de conserver tel quel). On démarrage, R charge automatiquement quelques packages de la bibliothèque, ceux contenant les fonctions les plus fréquemment utilisées. On peut voir la liste des packages déjà en mémoire avec la fonction search et le contenu de toute la bibliothèque avec la fonction library (résultat non montré ici) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
> search()
[1]       ".GlobalEnv"     "package:stats"
[3] "package:graphics" "package:grDevices"
[5]    "package:utils"  "package:datasets"
[7]  "package:methods"         "Autoloads"
[9]     "package:base"

Une des grandes forces de R est la facilité avec laquelle on peut ajouter des fonctionnalités au système par le biais de packages externes. Dès les débuts de R, les développeurs et utilisateurs ont mis sur pied le dépôt central de packages Comprehensive R Archive Network (CRAN ; http://cran.r-project.org). Ce site compte aujourd'hui des milliers d'extensions et le nombre ne cesse de croître.

Le système R rend simple le téléchargement et l'installation de nouveaux packages avec la fonction install.packages. L'annexe DInstallation de packages dans R explique plus en détail comment gérer sa bibliothèque personnelle et installer des packages externes.

Solution du problème

Nous savons déjà que l'expression

 
Sélectionnez
> m <- outer(x, y, "+")

calcule tous les résultats de la somme du lancer des deux dés. Il faut maintenant extraire de cette matrice les résultats supérieurs à 7 et en faire la moyenne.
Par la propriété d'opération élément par élément, la comparaison

 
Sélectionnez
> m > 7
      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,] FALSE FALSE FALSE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE  TRUE
[3,] FALSE FALSE FALSE FALSE  TRUE  TRUE
[4,] FALSE FALSE FALSE  TRUE  TRUE  TRUE
[5,] FALSE FALSE  TRUE  TRUE  TRUE  TRUE
[6,] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
[7,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
[8,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

retourne une matrice booléenne de la même dimension que m. Pour extraire les résultats de m supérieurs à 7, il suffit d'indicer m avec la matrice booléenne ci-dessus :

 
Sélectionnez
> m[m > 7]
 [1]  8  9  8  9 10 8  9 10 11  8  9 10 11 12 8 9
[17] 10 11 12 13  8 9 10 11 12 13 14

Le résultat recherché est donc

 
Sélectionnez
> mean(m[m > 7])
[1] 10.07407

Le tout peut s'écrire en une seule expression — quelque peu alambiquée — ainsi :

 
Sélectionnez
> mean((m <- outer(x, y, "+"))[m > 7])
[1] 10.07407

3-7. Exemples

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
###
### OPÉRATIONS ARITHMÉTIQUES
###
## L'arithmétique vectorielle caractéristique du langage R
## rend très simple et intuitif de faire des opérations
## mathématiques courantes. Là où plusieurs langages de
## programmation exigent des boucles, R fait le calcul
## directement. En effet, les règles de l'arithmétique en R
## sont globalement les mêmes qu'en algèbre vectorielle et
## matricielle.
5 * c(2, 3, 8, 10)          # multiplication par une constante
c(2, 6, 8) + c(1, 4, 9)     # addition de deux vecteurs
c(0, 3, -1, 4)^2            # élévation à une puissance

## Dans les règles de l'arithmétique vectorielle, les
## longueurs des vecteurs doivent toujours concorder. R permet
## plus de flexibilité en recyclant les vecteurs les plus
## courts dans une opération. Il n'y a donc à peu près jamais
## d'erreurs de longueur en R! C'est une arme à deux
## tranchants: le recyclage des vecteurs facilite le codage,
## mais peut aussi résulter en des réponses complètement
## erronées sans que le système ne détecte d'erreur.
8 + 1:10                    # 8 est recyclé 10 fois
c(2, 5) * 1:10              # c(2, 5) est recyclé 5 fois
c(-2, 3, -1, 4)^1:4         # quatre puissances différentes

## On se rappelle que les matrices (et les tableaux) sont des
## vecteurs. Les règles ci-dessus s'appliquent donc aussi aux
## matrices, ce qui résulte en des opérateurs qui ne sont pas
## définis en algèbre linéaire usuelle.
(x <- matrix(1:4, 2))       # matrice 2 x 2
(y <- matrix(3:6, 2))       # autre matrice 2 x 2
5 * x                       # multiplication par une constante
x + y                       # addition matricielle
x * y                       # produit *élément par élément*
x %*% y                     # produit matriciel
x / y                       # division *élément par élément*
x * c(2, 3)                 # produit par colonne

###
### OPÉRATEURS
###

## Seuls les opérateurs %%, %/% et logiques sont illustrés
## ici. Premièrement, l'opérateur modulo retourne le reste
## d'une division.
5 %% 2                      # 5/2 = 2 reste 1
5 %% 1:5                    # remarquer la périodicité
10 %% 1:15                  # x %% y = x si x < y

## Le modulo est pratique dans les boucles, par exemple pour
## afficher un résultat à toutes les n itérations seulement.
for (i in 1:50)
{
    ## Affiche la valeur du compteur toutes les 5 itérations.
    if (0 == i %% 5)
        print(i)
}

##La division entière retourne la partie entière de la
## division d'un nombre par un autre.
5 %/% 1:5
10 %/% 1:15

## Le ET logique est vrai seulement lorsque les deux
## expressions sont vraies.
c(TRUE, TRUE, FALSE) & c(TRUE, FALSE, FALSE)

## Le OU logique est faux seulement lorsque les deux
## expressions sont fausses.
c(TRUE, TRUE, FALSE) | c(TRUE, FALSE, FALSE)

## La négation logique transforme les vrais en faux et vice
## versa.
! c(TRUE, FALSE, FALSE, TRUE)

## On peut utiliser les opérateurs logiques &, | et !
## directement avec des nombres. Dans ce cas, le nombre zéro
## est traité comme FALSE et tous les autres nombres comme
## TRUE.
0:5 & 5:0
0:5 | 5:0
!0:5

## Ainsi, dans une expression conditionnelle, inutile de
## vérifier si, par exemple, un nombre est égal à zéro. On
## peut utiliser le nombre directement et sauver des
## opérations de comparaison qui peuvent devenir coûteuses en
## temps de calcul.
x <- 1                      # valeur quelconque
if (x != 0) x + 1           # TRUE pour tout x != 0
if (x) x + 1                # tout à fait équivalent!

## L'exemple de boucle ci-dessus peut donc être légèrement
## modifié.
for (i in 1:50)
{
    ## Affiche la valeur du compteur toutes les 5 itérations.
    if (!i %% 5)
        print (i)
}

## Dans les calculs numériques, TRUE vaut 1 et FALSE vaut 0.
a <- c("Impair", "Pair")
x <- c(2, 3, 6, 8, 9, 11, 12)
x %% 2
(!x %% 2) + 1
a[(!x %% 2) + 1]

## Un mot en terminant sur l'opérateur '=='. C'est l'opérateur
## à utiliser pour vérifier si deux valeurs sont égales, et
## non '='. C'est là une erreur commune --- et qui peut être
## difficile à détecter --- lorsque l'on programme en R.
5 = 2                       # erreur de syntaxe
5 == 2                      # comparaison

###
### APPELS DE FONCTIONS
###

## Les invocations de la fonction 'matrix' ci-dessous sont
## toutes équivalentes. On remarquera, entre autres, comment
## les arguments sont spécifiés (par nom ou par position).
matrix(1:12, 3, 4)
matrix(1:12, ncol = 4, nrow = 3)
matrix(nrow = 3, ncol = 4, data = 1:12)
matrix(nrow = 3, ncol = 4, byrow = FALSE, 1:12)
matrix(nrow = 3, ncol = 4, 1:12, FALSE)

###
### QUELQUES FONCTIONS UTILES
###

## MANIPULATION DE VECTEURS
x <- c(50, 30, 10, 20, 60, 30, 20, 40) # vecteur non ordonné

## Séquences de nombres.
seq(from = 1, to = 10)          # équivalent à 1:10
seq_len(10)                     # plus rapide que 'seq'
seq(-10, 10, length = 50)       # incrément automatique
seq(-2, by = 0.5, along = x)    # même longueur que 'x'
seq_along(x)                    # plus rapide que 'seq'

## Répétition de nombres ou de vecteurs complets.
rep(1, 10)                  # utilisation de base
rep(x, 2)                   # répéter un vecteur
rep(x, times = 2, each = 4) # combinaison des arguments
rep(x, times = 1:8)         # nombre de répétitions différent
                            # pour chaque élément de 'x'

## Classement en ordre croissant ou décroissant.
sort(x)                     # classement en ordre croissant
sort(x, decr = TRUE)        # classement en ordre décroissant
sort(c("abc", "B", "Aunt", "Jemima")) # chaînes de caractères
sort(c(TRUE, FALSE))        # FALSE vient avant TRUE

## La fonction 'order' retourne la position, dans le vecteur
## donné en argument, du premier élément selon l'ordre
## croissant, puis du deuxième, etc. Autrement dit, on obtient
## l'ordre dans lequel il faut extraire les données du vecteur
## pour les obtenir en ordre croissant.
order(x)                    # regarder dans le blanc des yeux
x[order(x)]                 # équivalent à 'sort(x)'

## Rang des éléments d'un vecteur dans l'ordre croissant.
rank(x)                     # rang des éléments de 'x'

## Renverser l'ordre d'un vecteur.
rev(x)

## Extraction ou suppression en tête ou en queue de vecteur.
head(x, 3)                  # trois premiers éléments
head(x, -2)                 # tous sauf les deux derniers
tail(x, 3)                  # trois derniers éléments
tail(x, -2)                 # tous sauf les deux premiers

## Expressions équivalentes sans 'head' et 'tail'
x[1:3]                      # trois premiers éléments
x[1:(length(x) - 2)]        # tous sauf les deux derniers
x[(length(x)-2):length(x)]  # trois derniers éléments
rev(rev(x)[1:3])            # avec petits vecteurs seulement
x[c(-1, -2)]                # tous sauf les deux premiers

## Seulement les éléments différents d'un vecteur.
unique(x)

## RECHERCHE D'ÉLÉMENTS DANS UN VECTEUR
which(x >= 30)              # positions des éléments >= 30
which.min(x)                # position du minimum
which.max(x)                # position du maximum
match(20, x)                # position du premier 20 dans 'x'
match(c(20, 30), x)         # aussi pour plusieurs valeurs
60 %in% x                   # 60 appartient à 'x'
70 %in% x                   # 70 n'appartient pas à 'x'

## ARRONDI
(x <- c(-21.2, -pi, -1.5, -0.2, 0, 0.2, 1.7823, 315))
round(x)                    # arrondi à l'entier
round(x, 2)                 # arrondi à la seconde décimale
round(x, -1)                # arrondi aux dizaines
ceiling(x)                  # plus petit entier supérieur
floor(x)                    # plus grand entier inférieur
trunc(x)                    # troncature des décimales

## SOMMAIRES ET STATISTIQUES DESCRIPTIVES
sum(x)                      # somme des éléments
prod(x)                     # produit des éléments
diff(x)                     # x[2] - x[1], x[3] - x[2], etc.
mean(x)                     # moyenne des éléments
mean(x, trim = 0.125)       # moyenne sans minimum et maximum
var(x)                      # variance (sans biais)
(length(x) - 1)/length(x) * var(x) # variance biaisée
sd(x)                       # écart type
max(x)                      # maximum
min(x)                      # minimum
range(x)                    # c(min(x), max(x))
diff(range(x))              # étendue de 'x'
median(x)                   # médiane (50e quantile) empirique
quantile(x)                 # quantiles empiriques
quantile(x, 1:10/10)        # on peut spécifier les quantiles
summary(x)                  # plusieurs des résultats ci-dessus

## SOMMAIRES CUMULATIFS ET COMPARAISONS ÉLÉMENT PAR ÉLÉMENT
(x <- sample(1:20, 6))
(y <- sample(1:20, 6))
cumsum(x)                   # somme cumulative de 'x'
cumprod(y)                  # produit cumulatif de 'y'
rev(cumprod(rev(y)))        # produit cumulatif renversé
cummin(x)                   # minimum cumulatif
cummax(y)                   # maximum cumulatif
pmin(x, y)                  # minimum élément par élément
pmax(x, y)                  # maximum élément par élément

## OPÉRATIONS SUR LES MATRICES
(A <- sample(1:10, 16, replace = TRUE)) # avec remise
dim(A) <- c(4, 4)           # conversion en une matrice 4 x 4
b <- c(10, 5, 3, 1)         # un vecteur quelconque
A                           # la matrice 'A'
t(A)                        # sa transposée
solve(A)                    # son inverse
solve(A, b)                 # la solution de Ax = b
A %*% solve(A, b)           # vérification de la réponse
diag(A)                     # extraction de la diagonale de 'A'
diag(b)                     # matrice diagonale formée avec 'b'
diag(4)                     # matrice identité 4 x 4
(A <- cbind(A, b))          # matrice 4 x 5
nrow(A)                     # nombre de lignes de 'A'
ncol(A)                     # nombre de colonnes de 'A'
rowSums(A)                  # sommes par ligne
colSums(A)                  # sommes par colonne
apply(A, 1, sum)            # équivalent à 'rowSums(A)'
apply(A, 2, sum)            # équivalent à 'colSums(A)'
apply(A, 1, prod)           # produit par ligne avec 'apply'

## PRODUIT EXTÉRIEUR
x <- c(1, 2, 4, 7, 10, 12)
y <- c(2, 3, 6, 7, 9, 11)
outer(x, y)                 # produit extérieur
x %o% y                     # équivalent plus court
outer(x, y, "+")            # « somme extérieure »
outer(x, y, "<=")           # toutes les comparaisons possibles
outer(x, y, pmax)           # idem

###
### STRUCTURES DE CONTRÔLE
###

## Pour illustrer les structures de contrôle, on a recours à
## un petit exemple tout à fait artificiel : un vecteur est
## rempli des nombres de 1 à 100, à l'exception des multiples
## de 10. Ces derniers sont affichés à l'écran.
##
## À noter qu'il est possible --- et plus efficace --- de
## créer le vecteur sans avoir recours à des boucles.
(1:100)[-((1:10) * 10)]              # sans boucle !
rep(1:9, 10) + rep(0:9*10, each = 9) # une autre façon !

## Bon, l'exemple proprement dit...
x <- numeric(0)             # initialisation du contenant 'x'
j <- 0                      # compteur pour la boucle
for (i in 1:100)
{
    if (i %% 10)            # si i n'est pas un multiple de 10
        x[j <- j + 1] <- i  #     stocker sa valeur dans 'x'
    else                    # sinon
        print(i)            #     afficher la valeur à l'écran
}
x                           # vérification

## Même chose que ci-dessus, mais sans le compteur 'j' et les
## valeurs manquantes aux positions 10, 20, ... , 100 sont
## éliminées à la sortie de la boucle.
x <- numeric(0)
for (i in 1:100)
{
    if (i %% 10)
        x[i] <- i
    else
        print(i)
}
x <- x[!is.na(x)]
x

## On peut refaire l'exemple avec une boucle 'while', mais
## cette structure n'est pas naturelle ici puisque l'on sait
## d'avance qu'il faudra faire la boucle exactement 100
## fois. Le 'while' est plutôt utilisé lorsque le nombre de
## répétitions est inconnu. De plus, une boucle 'while' n'est
## pas nécessairement exécutée puisque le critère d'arrêt est
## évalué dès l'entrée dans la boucle.
x <- numeric(0)
j <- 0
i <- 1                      # pour entrer dans la boucle [*]
while (i <= 100)
{
    if (i %% 10)
        x[j <- j + 1] <- i
    else
        print(i)
    i <- i + 1              # incrémenter le compteur!
}
x

## La remarque faite au sujet de la boucle 'while' s'applique
## aussi à la boucle 'repeat'. Par contre, le critère d'arrêt
## de la boucle 'repeat' étant évalué à la toute fin, la
## boucle est exécutée au moins une fois. S'il faut faire la
## manœuvre marquée [*] ci-dessus pour s'assurer qu'une
## boucle 'while' est exécutée au moins une fois... c'est
## qu'il faut utiliser 'repeat'.
x <- numeric(0)
j <- 0
i <- 1
repeat
{
    if (i %% 10)
        x[j <- j + 1] <- i
    else
        print(i)
    if (100 < (i <- i + 1)) # incrément et critère d'arrêt
        break
}
x

###
### FONCTIONS ADDITIONNELLES
###

## La fonction 'search' retourne la liste des environnements
## dans lesquels R va chercher un objet (en particulier une
## fonction). '.GlobalEnv' est l'environnement de travail.
search()

## Liste de tous les packages installés sur votre système.
library()

## Chargement du package 'MASS', qui contient plusieurs
## fonctions statistiques très utiles.
library("MASS")

3-8. Exercices

3.1 (solution) À l'aide des fonctions rep, seq et c seulement, générer les séquences suivantes.

  1. 0 6 0 6 0 6
  2. 1 4 7 10
  3. 1 2 3 1 2 3 1 2 3 1 2 3
  4. 1 2 2 3 3 3
  5. 1 1 1 2 2 3
  6. 1 5.5 10
  7. 1 1 1 1 2 2 2 2 3 3 3 3

3.2 (solution) Générer les suites de nombres suivantes à l'aide des fonctions : et rep seulement, donc sans utiliser la fonction seq.

  1. 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2
  2. 1 3 5 7 9 11 13 15 17 19
  3. -2 -1 0 1 2 -2 -1 0 1 2
  4. -2 -2 -1 -1 0 0 1 1 2 2
  5. 10 20 30 40 50 60 70 80 90 100

3.3 (solution) À l'aide de la commande apply, écrire des expressions R qui remplaceraient les fonctions suivantes.

  1. rowSums
  2. colSums
  3. rowMeans
  4. colMeans

3.4 (solution) Sans utiliser les fonctions factorial, lfactorial, gamma ou lgamma, générer la séquence 1! , 2! … , 10!.

3.5 (solution) Trouver une relation entre x, y, x %% y (modulo) et x %/% y (division entière), où y != 0.

3.6 (solution) (Simuler un échantillon kitxmlcodeinlinelatexdvpx = (x_1, x_2, x_3,\dots\ , x_{20})finkitxmlcodeinlinelatexdvp) avec la fonction sample.

Écrire une expression R permettant d'obtenir ou de calculer chacun des résultats demandés ci-dessous.

  1. Les cinq premiers éléments de l'échantillon.
  2. La valeur maximale de l'échantillon.
  3. La moyenne des cinq premiers éléments de l'échantillon.
  4. La moyenne des cinq derniers éléments de l'échantillon.

3.7 (solution)

  1. Trouver une formule pour calculer la position, dans le vecteur sous-jacent, de l'élément kitxmlcodeinlinelatexdvp(i,j)finkitxmlcodeinlinelatexdvp d'une matrice kitxmlcodeinlinelatexdvpI\times Jfinkitxmlcodeinlinelatexdvp remplie par colonne.
  2. Répéter la partie a) pour l'élément kitxmlcodeinlinelatexdvp(i,j,k)finkitxmlcodeinlinelatexdvp d'un tableau kitxmlcodeinlinelatexdvpI \times J \times Kfinkitxmlcodeinlinelatexdvp.

3.8 (solution) Simuler une matrice mat 10×7, puis écrire des expressions R permettant d'effectuer les tâches demandées ci-dessous.

  1. Calculer la somme des éléments de chacune des lignes de la matrice.
  2. Calculer la moyenne des éléments de chacune des colonnes de la matrice.
  3. Calculer la valeur maximale de la sous-matrice formée par les trois premières lignes et les trois premières colonnes.
  4. Extraire toutes les lignes de la matrice dont la moyenne des éléments est supérieure à 7.

3.9 (solution) On vous donne la liste et la date des 31 meilleurs temps enregistrés au 100 mètres homme entre 1964 et 2005 :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
> temps <- c(10.06, 10.03, 10.02,  9.95, 10.04, 10.07,
+            10.08, 10.05,  9.98, 10.09, 10.01, 10.00,
+             9.97,  9.93,  9.96,  9.99,  9.92,  9.94,
+             9.90,  9.86,  9.88,  9.87,  9.85,  9.91,
+             9.84,  9.89,  9.79,  9.80,  9.82,  9.78,
+             9.77)
> names(temps) <- c("1964-10-15", "1968-06-20",
+     "1968-10-13", "1968-10-14", "1968-10-14",
+     "1968-10-14", "1968-10-14", "1975-08-20",
+     "1977-08-11", "1978-07-30", "1979-09-04",
+     "1981-05-16", "1983-05-14", "1983-07-03",
+     "1984-05-05", "1984-05-06", "1988-09-24",
+     "1989-06-16", "1991-06-14", "1991-08-25",
+     "1991-08-25", "1993-08-15", "1994-07-06",
+     "1994-08-23", "1996-07-27", "1996-07-27",
+     "1999-06-16", "1999-08-22", "2001-08-05",
+     "2002-09-14", "2005-06-14")

Extraire de ce vecteur les records du monde seulement, c'est-à-dire la première fois que chaque temps a été réalisé.


précédentsommairesuivant

Licence Creative Commons
Le contenu de cet article est rédigé par Vincent Goulet et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2018 Developpez.com.