Ensembles et dictionnaires
Algo & Prog avec R
A. Malapert, B. Martin, M. Pelleau, et J.-P. Roy 2 décembre 2021
Université Côte d’Azur, CNRS, I3S, France firstname.lastname@univ-cotedazur.fr
Où en sommes-nous des types de données ?
Types simples
> c l a s s( 4 2 ) [1] " n u m e r i c "
> c l a s s(
as . i n t e g e r( 4 2 ) ) [1] " i n t e g e r "
> c l a s s( T R U E ) [1] " l o g i c a l "
> c l a s s(" 42 ") [1] " c h a r a c t e r "
Types composés : séquence d’objets numérotés (vector et list)
> c l a s s(c(1 ,2 ,3) ) [1] " n u m e r i c "
> c l a s s(l i s t(’ a ’,2 ,3) ) [1] " l i s t "
Types composés : ensembles et dictionnaires.
I Disponible dans de nombreux langages, mais pas en R.
I Nous allons les émuler grâce à des vecteurs et des listes nommés.
1/13
Les ensembles
A A∩B B
Figure 1 –
Diagramme de Venn.
Origine : Georg Cantor (1845-1918), mathématicien allemand.
Qu’est-ce qu’un ensemble ?
Ensemble en R
Un ensemble en R est une séquence sans répétition et sans ordre (conceptuellement).
I En théorie, les éléments sont de types quelconques.
I En pratique, on représente un ensemble (type simple) par un vecteur.
L’arithmétique des vecteurs ne suffit pas.
> 1:5 = = 5:1 # # V r a i du p o i n t de v u e e n s e m b l i s t e. [1] F A L S E F A L S E T R U E F A L S E F A L S E
Égalité de deux ensembles
> s e t e q u a l(1:5 , 5:1) [1] T R U E
3/13
Appartenance et cardinal d’un ensemble
Appartenance d’un élément à un ensemble
> is .e l e m e n t (1 , 1:5) [1] T R U E
> is .e l e m e n t (0 , 1:5) [1] F A L S E
Cardinal d’un ensemble Pas de fonction prédéfinie.
> C a r d i n a l < - f u n c t i o n( x ) l e n g t h(u n i q u e( x ) )
> C a r d i n a l (c(1:5 , 1:5) ) [1] 5
Opérations sur les ensembles
Union A ∪ B = {x | x ∈ A ou x ∈ B}
> u n i o n(1:5 , 4:6) [1] 1 2 3 4 5 6
Intersection A ∩ B = {x | x ∈ A et x ∈ B}
> i n t e r s e c t(1:5 , 4:6) [1] 4 5
Différence asymétrique A − B = {x | x ∈ A et x ∈ / B}
> s e t d i f f(1:5 , 4:6) [1] 1 2 3
Inclusion A ⊆ B ⇔ ((∀x ∈ A) ⇒ (x ∈ B))
> I n c l u s i o n < - f u n c t i o n( x , y ) s e t e q u a l( x , i n t e r s e c t( x , y ) )
> I n c l u s i o n s (5:6 , 4:6)
[1] T R U E 5/13
Qu’est-ce qu’un dictionnaire ?
Dictionnaire en R
En théorie, un dictionnaire est une collection non numérotée de couples clé/valeur où la clé est un objet non mutable et la valeur est n’importe quelle valeur.
I Toutes les clés doivent être distinctes !
I R ne propose pas de classe pour les dictionnaires.
En pratique, nous allons émuler un dictionnaire dont les clés sont des chaînes de caractères avec un vecteur nommé ou une liste nommée.
Vecteurs et listes nommées I Écrire un code plus lisible.
I Utiliser les fonctions avancées de R (par ex. graphiques).
Construction d’un dictionnaire
Construction en extension
On fournit tous les couples dans un ordre quelconque.
> s t o c k < - c( p o i r e s=51 , p o m m e s=2 4 3 )
> p r i n t( s t o c k ) p o i r e s p o m m e s 51 243
Construction en deux temps
on fournit toutes les valeurs, puis tous les noms, dans le même ordre.
> s t o c k < - c( 5 1 , 2 4 3 )
> n a m e s( s t o c k ) < - c(" p o i r e s ", " p o m m e s ")
Remarquez que nous affectons les noms aux résultats d’une fonction !
7/13
Accès aux valeurs d’un dictionnaire
Accès par clé
I On peut accéder à la valeur associée à une clé.
I La recherche est pratiquement instantanée ! De la clé vers la valeur ! I La recherche est unidirectionnelle : Français –> Anglais.
> s t o c k [’ p o m m e s ’]
250
> g e t E l e m e n t ( stock ," p o i r e s ") [1] 51
Accès par rang
> s t o c k [1]
p o i r e s 51
Ne pas confondre rang et clé
> s t o c k [’ 1 ’] # ni cl é , ni i n d e x
<NA>
NA
Modification d’un dictionnaire
Modifier la valeur associée à une clé
> s t o c k [" p o m m e s "] < - 250
Ajouter un nouveau couple clé/valeur
> s t o c k [" f r a i s e s "] < - 50
> p r i n t( s t o c k )
p o i r e s p o m m e s f r a i s e s 51 250 50
Attention, un dictionnaire est un vecteur !
> c( stock , s t o c k ) # L e s cl é s ne s o n t p l u s u n i q u e s ! p o i r e s p o m m e s f r a i s e s p o i r e s p o m m e s f r a i s e s
51 250 50 51 250 50
Vérifier la présence d’une clé
> is .e l e m e n t (" f r a i s e s ", n a m e s( s t o c k ) ) [1] T R U E
9/13
Itérer dans un dictionnaire
Accéder aux valeurs et aux clés
> u n n a m e( s t o c k ) # v e c t e u r d e s v a l e u r s s a n s l e s cl é s
[1] 51 250 50
> n a m e s( s t o c k ) # v e c t e u r d e s cl é s [1] " p o i r e s " " p o m m e s " " f r a i s e s "
Par défaut, on itère sur les valeurs
> f o r( i in s t o c k ) {p r i n t( i ) } [1] 51
[1] 250 [1] 50
Mais, on peut itérer sur les clés
> f o r( i in n a m e s( s t o c k ) ) {p r i n t( i ) } [1] " p o i r e s "
[1] " p o m m e s "
[1] " f r a i s e s "
Suppression dans un dictionnaire
Suppression par clé
On ne peut pas directement supprimer la valeur associée à une clé.
> s t o c k [-’ p o m m e s ’]
E r r o r in -" p o m m e s " : i n v a l i d a r g u m e n t to u n a r y o p e r a t o r
Émuler la suppression par clé
On va devoir trouver le rang de la clé, puis la supprimer par rang. Pour cela, on définir une fonction Remove(dict, key) qui renvoie le dictionnaire après suppression du couple key:val du dictionnaire.
R e m o v e < - f u n c t i o n( dict , key ) { d i c t [ n a m e s( d i c t ) ! = key ] }
> R e m o v e ( stock , " p o m m e s ") p o i r e s f r a i s e s
51 25
11/13
De l’utilité des dictionnaire . . .
On considère maintenant différentes variétés de chaque fruit.
On ne peut plus utiliser un vecteur. On doit utiliser une liste.
> s t o c k < - l i s t(
p o m m e s = c( g r a n y=25 , g o l d e n=50 , f u j y=0) , p o i r e s = c( c o m i c e=10 , w i l l i a m s=1 0 0 ) , f r a i s e s = c( m a r a t=0 , g a r i g u e t t e=1 0 0 ) )
Accès par clé
> s t o c k$f r a i s e s # a c c è s p a r cl é m a r a t g a r i g u e t t e
0 100
> s t o c k [[" f r a i s e s "]] # a c c è s p a r cl é m a r a t g a r i g u e t t e
0 100
> s t o c k [" f r a i s e s "] # e x t r a c t i o n d ’ u n e t r a n c h e !
$f r a i s e s
m a r a t g a r i g u e t t e
Pour regarnir ses étals
Trouver les variétés dont le nombre de fruit est en dessous d’un seuil fixé.
C o m m a n d e r V a r i e t e s < - f u n c t i o n( stock , s e u i l ) { c o m m a n d e s < - c()
f o r( f r u i t in s t o c k ) {
v a r i e t e s < - n a m e s(s u b s e t( fruit , f r u i t < s e u i l ) ) c o m m a n d e s < - c( c o m m a n d e s , v a r i e t e s )
}
r e t u r n( c o m m a n d e s ) }
> C o m m a n d e r V a r i e t e s ( stock , 50)
[1] " g r a n y " " f u j y " " c o m i c e " " m a r a t "
> C o m m a n d e r V a r i e t e s ( stock , 10) [1] " f u j y " " m a r a t "
13/13