[1] TRUE FALSE TRUE FALSE
37 Conditions logiques
Dans ce chapitre, nous allons aborder les conditions et vecteurs logiques qui sont composés de trois valeurs possibles : TRUE
(vrai), FALSE
(faux) et NA
(manquant). Les vecteurs logiques sont notamment utiliser pour sélectionner des observations, par exemple avec dplyr::filter()
.
Nous avons également déjà aborder les conditions pour combiner ensemble plusieurs variables (cf. Chapitre 10), notamment avec dplyr::if_else()
ou dplyr::case_when()
.
37.1 Opérateurs de comparaison
Une manière commune de créer un vecteur logique consiste à utiliser l’un des opérateurs de comparaison suivants : < (strictement inférieur), <=
(inférieur ou égal), >
(strictement supérieur), >=
(supérieur ou égal), ==
(est égal à), !=
(est différent de).
On peut comparer un vecteur de plusieurs valeurs avec une valeur unique.
Si l’on prend deux vecteurs de même longueur, la comparaison se fera ligne à ligne.
[1] TRUE TRUE FALSE FALSE
[1] FALSE TRUE FALSE FALSE
[1] TRUE FALSE TRUE TRUE
On peut ainsi facilement sélectionner des lignes d’un tableau de données à partir d’une condition sur certaines variables.
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
[1] 2000
[1] 1101
[1] 169
Lorsque l’on effectue un test d’égalité avec des valeurs décimales, le test échouera si les deux valeurs ne sont pas parfaitement identique.
Prenons un exemple :
Pourquoi ce test échoue-t-il ? Le nombre de décimales stockées par l’ordinateur est limité et, de ce fait, il peut y avoir quelques écarts d’arrondis. Ainsi, x
n’est pas tout à fait égal à 1
, ce qui devient visible si on l’affiche avec un nombre élevé de décimales.
Dans ce cas là, on pourra avoir recours à dplyr::near()
qui prendra en compte la précision de l’ordinateur dans la comparaison.
On peut aussi utiliser cette fonction en personnalisant le niveau de tolérance pour la comparaison.
37.2 Comparaison et valeurs manquantes
Les valeurs manquantes (NA
) peuvent être parfois problématiques lors d’une comparaison car elles renvoient systématique une valeur manquante.
Lorsque l’on sélectionne des observations avec la syntaxe des crochets ([]
, voir Chapitre 4), cela va générer des lignes vides
/ manquantes
.
# A tibble: 3 × 2
a b
<dbl> <chr>
1 NA <NA>
2 3 x
3 4 y
Le recours à dplyr::filter()
est plus sûr car les lignes pour lesquelles la condition renvoie NA
ne sont pas sélectionnées.
L’opérateur ==
ne peut pas être utilisé pour tester si une valeur est manquante. On utilisera à la place la fonction is.na()
.
Voici deux petites fonctions permettant de tester si deux valeurs sont identiques ou différentes, en tenant compte des NA
comme l’un des valeurs possibles (deux NA
seront alors considérés comme égaux).
is_different <- function(x, y) {
(x != y & !is.na(x) & !is.na(y)) | xor(is.na(x), is.na(y))
}
is_equal <- function(x, y) {
(x == y & !is.na(x) & !is.na(y)) | (is.na(x) & is.na(y))
}
v <- c(1, NA, NA, 2)
w <- c(1, 2, NA, 3)
v == w
[1] TRUE NA NA FALSE
[1] TRUE FALSE TRUE FALSE
[1] FALSE NA NA TRUE
[1] FALSE TRUE FALSE TRUE
37.3 Opérateurs logiques (algèbre booléenne)
Les opérateurs logiques permettent de combiner ensemble plusieurs vecteurs logiques :
&
: opérateuret
(x & y
est vrai si à la foisx
ety
sont vrais) ;|
: opérateurou
(x | y
est vrai six
ouy
ou les deux sont vrais) ;xor()
: opérateurou exclusif
(xor(x, y)
est vrai si seulementx
ou seulementy
est vrai, mais pas les deux) ;!
: opérateurnon
(!x
est vrai six
est faux).
Ils permettent de combiner plusieurs conditions entre elles.
[1] 93
[1] 1177
Pour des conditions complexes, on utilisera des parenthèses pour indiquer dans quel ordre effectuer les opérations.
# sélectionne les jeunes femmes et les hommes âgés
hdv2003 |>
filter(
(sexe == "Femme" & age < 25) |
(sexe == "Homme" & age > 60)) |>
nrow()
[1] 315
37.3.1 Opérations logiques et Valeurs manquantes
On sera vigilant·e avec les valeurs manquantes. Cela peut paraître un peu obscur au premier abord, mais est en fait parfaitement logique.
# A tibble: 3 × 3
x et_na ou_na
<lgl> <lgl> <lgl>
1 TRUE NA TRUE
2 FALSE FALSE NA
3 NA NA NA
TRUE | NA
vaut TRUE
car la condition reste vrai quelle que soit la valeur du deuxième paramètre, tandis que FALSE | NA
renvoie NA
car le résultat est indéterminé (il dépend du deuxième paramètre).
37.3.2 L’opérateur %in%
Il est fréquent de vouloir tester simultanément plusieurs égalités. Par exemple :
On aura alors avantageusement recours à l’opérateur %in% que l’on peut traduire par appartient à
et qui teste si les éléments appartiennent à un certain ensemble.
37.4 Aggrégation
Pour résumer un ensemble de valeurs logiques en une seule, on utilisera les fonction all()
et any()
qui teste si toutes les valeurs / au moins une valeur est vrai. Ces deux fonctions acceptent un argument na.rm
permettant de ne pas tenir compte des valeurs manquantes.
Un vecteur logique peut-être vu comme un vecteur de valeur binaire (0
si FALSE
, 1
si TRUE
). On peut dès lors effectuer des opérations comme la somme ou la moyenne.
37.5 Programmation
Lorsque l’on programme avec R
, notamment avec des structures conditionnelles telles que if ... else ...
, on a besoin d’écrire des conditions qui ne renvoient qu’une et une seule valeur logique.
Les opérateurs &
et |
s’appliquent sur des vecteurs et donc renvoient potentiellement plusieurs valeurs. On privilégiera alors les variantes &&
et ||
qui ne renvoient qu’une seule valeur et produise une erreur sinon.
De même, pour vérifier qu’un objet est bien égal à TRUE
ou à FALSE
, n’est pas nul, n’est pas manquant et est de longueur 1, on utilisera isTRUE()
et isFALSE()
.