Boucle et évaluation conditionnelle

L3 économie-finance

Elias Bouacida

Université Paris 8

15 octobre 2024

Introduction

2 outils pour contrôler l’évaluation :

  1. Les évaluations conditionnelles
  2. les boucles

Conditions

Condition if

Deux types de conditions if :

if (condition) action_true
if (condition) action_true else action_false

Condition typique

Exemple :

mention <- function(x) {
  if (x > 16) {
    "Très bien"
  } else if (x > 14) {
    "Bien"
  } else if (x > 12) {
    "Assez bien"
  } else {
    ""
  }
}

if renvoie un résultat, il est donc possible d’assigner le résultat :

x1 <- if (TRUE) 1 else 2
x2 <- if (FALSE) 1 else 2

c(x1, x2)
[1] 1 2

Quand else n’est pas explicitement renseigné mais la condition est fausse, if renvoie NULL.

Et si condition n’est pas TRUE ou FALSE ?

if ("x") 1
Error in if ("x") 1: argument is not interpretable as logical
if (logical()) 1
Error in if (logical()) 1: argument is of length zero
if (NA) 1
Error in if (NA) 1: missing value where TRUE/FALSE needed
if (c(TRUE, FALSE)) 1
Error in if (c(TRUE, FALSE)) 1: the condition has length > 1

if vectoriel : ifelse()

Dans le cas où vous avez besoin de conditions vectorielles, il faut utiliser ifelse() :

x <- 1:10
ifelse(x %% 5 == 0, "XXX", as.character(x))
 [1] "1"   "2"   "3"   "4"   "XXX" "6"   "7"   "8"   "9"   "XXX"
ifelse(x %% 2 == 0, "even", "odd")
 [1] "odd"  "even" "odd"  "even" "odd"  "even" "odd"  "even" "odd"  "even"

switch()

On peut remplacer ceci :

x_option <- function(x) {
  if (x == "a") {
    "option 1"
  } else if (x == "b") {
    "option 2" 
  } else if (x == "c") {
    "option 3"
  } else {
    stop("Invalid `x` value")
  }
}

Par ceci :

x_option <- function(x) {
  switch(x,
    a = "option 1",
    b = "option 2",
    c = "option 3",
    stop("Invalid `x` value") 
  )
}

Le dernier composant de switch() doit renvoyer une erreur, sinon les conditions non vérifiées renverront NULL, ce qui est rarement le comportement désiré. C’est à ça que sert stop().

Boucles

Boucles for

La boucle la plus simple est la boucle for :

for (item in vecteur) action

Exemple :

for (i in 1:3) {
  print(i)
}
[1] 1
[1] 2
[1] 3

Interruption anticipée

On peut interrompre l’exécution d’une boucle for de manière anticipée :

  • next sort de l’itération actuelle ;
  • break sort de la boucle for en entier.
for (i in 1:10) {
  if (i < 3) 
    next

  print(i)
  
  if (i >= 5)
    break
}
[1] 3
[1] 4
[1] 5

Boucles alternatives

Quand on ne sait pas les valeurs sur lesquelles on itère, on utilise :

  • while(condition) action : l’action est effectuée tant que la condition est TRUE
  • repeat(action) : répète l’action indéfiniment (tant que break n’apparaît pas)

for est moins flexible que while qui est moins flexible que repeat, mais il vaut mieux utiliser la version la moins flexible.

Le grand danger des boucles while et repeat est la boucle infinie : une boucle qui n’est jamais interrompue, entraînant le plantage de l’ordinateur par manque de mémoire.

3 Codes alternatifs

for (i in 1:10) {
  if (i < 3) 
    next

  print(i)
  
  if (i >= 5)
    break
}
[1] 3
[1] 4
[1] 5
i <- 0
while (i < 10) {
  i <- i + 1 ## Attention à ne pas oublier l'incrémentation, sinon on crée une boucle infinie
  if (i < 3) 
    next

  print(i)
  
  if (i >= 5)
    break
}
[1] 3
[1] 4
[1] 5
i <- 0
repeat ({
  i <- i + 1 ## Attention à ne pas oublier l'incrémentation, sinon on crée une boucle infinie
  if (i < 3) 
    next

  print(i)
  
  if (i >= 5)
    break ## Attention à ne pas oublier break, sinon on crée une boucle infinie
})
[1] 3
[1] 4
[1] 5

Exemple : while, mais pas for

Vous avez acheté une action au prix de 50€ et vous voulez la vendre dès que le prix dépasse les 55€ ou descend sous les 45€. On fait l’hypothèse que le prix change chaque jour de manière aléatoire de +1 ou -1.

# Prix d'origine
prix <- 50

# L'objet jour nous sert à compter le nombre de jours
jour <- 1

# Conditions utilisées dans while, remarquez le &&
while ((45 <= prix) && (prix <= 55)){
  
  # Evolution du prix de +1 ou -1 chaque jour
  prix <- prix + sample(c(-1, 1), 1)
  
  # Compte le nombre de jours et ajoute un jour supplémentaire
  jour = jour + 1 
}

print(paste0("Nous avons gardé l'action ",jour," jours avant de la vendre, au prix de ", prix, "€."))
[1] "Nous avons gardé l'action 25 jours avant de la vendre, au prix de 44€."