Les données R
Analytique et exploration de données | |
---|---|
Module: Tutoriels R | |
▲ | |
◀▬▬▶ | |
⚐ brouillon | ☸ intermédiaire |
⚒ 2022/04/15 | ⚒⚒ 2014/11/18 |
Prérequis | |
Voir aussi | |
Catégorie: R |
Introduction aux données R
Pour profiter pleinement de divers paquets il faut comprendre (a) les types de structures de données de R et (b) les structures de données implémentés par divers paquets et (c) comment passer d'une structure à l'autre et finalement (d) comment lire des données depuis des fichiers ou d'autres sources.
Plusieurs paquets utilisent des simples structures de données de base comme les vecteurs ou les matrices. D'autres utilisent des structures plus sophistiqués
Cet article essaye de présenter de façon systématique les différents types de données, y compris le système des "classes".
A notre avis, il n'est pas nécessaire de lire ou comprendre tout en détail, mais le lecteur peut revenir plus tard. Contrairement à d'autres logiciels d'analyse de données R n'utilise pas une seule structure centrale, mais une multitude de représentations. Cela rend R plus flexible, mais plus difficile à aborder au début.
Les types de données
Il existe 3 grandes classes de données:
- Vecteurs simples: Ce sont des simples listes ordonnées de valeurs simples
- Données composites (listes, data frames, etc.)
- Données "spéciales" pour programmeurs
Il existe 6 types de valeurs simples: "logical", "integer", "double", "complex", "character", "raw"
- Comment savoir le type d'une donnée ?
- Utilisez la fonction
typeof
typeof (truc)
nom <- "DKS"
typeof (nom)
[1] "character"
Lorsqu'on utilise cette fonction avec un vecteur (voir ci-dessous pour une explication de ce terme), le résultat ne montre pas "vector", mais le type de données utilisées, tout simplement parce que l'objet le plus simple est un vecteur. Les deux expressions suivante sont équivalentes:
v1 = "Simple"
v2 = c ("Simple") # on construit explicitement un vecteur
D'où la décision des gens de R de ne pas afficher "vector", mais simplement le type de données qui se trouvent dans le vecteur.
> typeof ( c("DKS", "TECFA"))
[1] "character"
Il existe plusieurs types de structures de données, dont nous présentons certains.
Type | Définition | Exemples | Utilisation |
---|---|---|---|
vector | Liste indexée du même type de données | Ex: "ceci" "est" "une" Ex: 1 2 3 Ex: "ceci" |
Structure de base pour représenter des données, par exemple une seule valeur ou encore une variable statistique avec 10'137 entrées. Voir les data frame qui sont composés de vecteurs. |
matrix | Tableau typé à 2 dimensions | Exemple:1 2 3
4 5 6
17 18 19
|
On peut penser une matrice comme un vecteur à 2 dimensions. Les utilisateurs de R semblent utiliser plus souvent des data frame pour représenter des données, car on peut (1) annoter les colonnes et (2) avoir des types de vecteurs différents. |
factor | Vecteur pour variables nominales | mot image mot image mot Levels: image mot |
Utile pour stocker et analyser des valeurs nominales (mots au lieu de chiffres) |
array | ... | ... | ... |
list | Une liste de données qui peut contenir d'autres structures de données complexes | Ex:"un" "mot" "dit" | Structure la plus flexible. On peut tout représenter avec une liste de listes de listes ... |
list (associative) | même type que la liste | Ex:art="un", sujet="mot", verbe="dit" | Permet d'indexer / chercher / tagger des données |
data frame | Tableau composé de type de données différentes. | phrase_courte phrase_courte2 phrase_courte3
art un une une
sujet mot image idee
verbe dit parle est
|
On peut penser à une liste de vecteurs ou de facteurs ou un tableau de type Excel. |
Note: Etant donné que R possède une sémantique inspiré de langages puissants comme Scheme, tout est données, y compris les fonctions.
Les classes
Pour chaque type, R définit aussi une classe. Un type représente l'organisation des données et la classe ce qu'on peut faire avec.
Pour identifier le type de structure de données, il faut plutôt utiliser class
à la place de typeof, car la classe nous renseigne sur les méthodes que l'on peut utiliser pour manipuler un objet. Enfin le résultat n'est pas toujours intuitif. Par défaut tout est un vecteur et donc R au lieu de dire "ceci un caracter vector" dit simplement "character"....
noms_11 <- ( c("DKS", "TECFA"))
> class (noms_11)
[1] "character"
> is.vector(noms_11)
[1] TRUE
L'exemple suivant montre la différence entre structure de données (un data frame est effectivement une liste d'un point de vue structurel) et une classe:
# df_mots est un data frame
> typeof (df_mots3)
[1] "list"
> class (df_mots3)
[1] "data.frame"
Voir aussi les explications plus loin qui montrent que R possède plusieurs types de classes et correspondent à l'évolution du langage dans le temps...
Les vecteurs
- Contiennent une liste ordonnée de N éléments.
- Ce type de structure de données est fréquent. On l'utilise pour représenter des données d'une variable statistique, par exemple une liste de revenues ou encore une liste de noms.
- Voir les matrice (ci-dessous pour des vecteurs à N dimensions que l'on peut utiliser pour représenter des tableaux de données par exemple)
- Construction manuelle d'une liste
- Il existe plusieurs méthodes. Le plus souvent on voit la fonction combine:
c()
- proverbe = c("un", "mot", "dit", "plus", "que", "une", "image");
Altérnativement, vous pouvez utiliser l'opérateur :
, la fonction seq
et la fonction rep
:
1:15
seq(1,5, by = 0.2)
seq(1,5, length=10)
rep(1,10)
rep(1:3, times = 3)
rep(1:3, each = 3)
rep(1:3, times = 3, each = 2)
La fonction rep()
permet de générer un vecteur avec des éléments identiques
>rep('H', 20)
[1] "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H"
[19] "H" "H"
La fonction seq
permet de générer des vecteurs avec des éléments calculés
1:15
seq(1,5, by = 0.2)
seq(1,5, length=10)
rep(1,10)
rep(1:3, times = 3)
rep(1:3, each = 3)
rep(1:3, times = 3, each = 2)
Pour générer un vecteur logique, utilisez les opérateurs >, >=, <, <=, ==, != :
10 == (2+1) # Donne FALSE car 10 est différent de 3 10 != 3 # Donne TRUE car 10 est différent de 3 10 >= 7 # Donne TRUE car 10 est supérieur égal à 7 1:10 == 6 # Donne un vecteur logique de longueur 10. La valeur TRUE apparaît quand la condition est satisfaite ; la valeur FALSE apparaît quand la condition n'est pas satisfaite
Rappelons que les opérateurs <- et -> permettent de sauvegarder des objets dans la mémoire de R. Créons un vecteur numérique Age et un vecteur alphanumérique Sexe à travers les commandes suivantes :
Age <- c(19, 31, 28, 18, 25, 23, 27, 20) Sexe <- c('F', 'H', 'F', 'H', 'H', 'F', 'H', 'F')
Affichons enfin les deux vecteurs avec les commandes :
Age Sexe
- Sélection d'éléments
Pour sélectionner une partie d'un vecteur, utilisez l'opérateur de sélection [ ]. Etudiez les exemples suivants :
X = 10:20 # crée un vecteur qui contient une série qui va de 10 à 20 X[3] # Donne le troisième élément du vecteur X X[c(6,9)] # Donne le sixième et neuvième élément du vecteur X X[3:5] # Donne le troisième quatrième et cinquième élément du vecteur X X[7:5] # Donne le septième, le sixième et le cinquième élément du vecteur X X[-c(4,7)] # Donne X sans le quatrième et septième élément du vecteur X X[-(1:3)] # Donne X sans les trois premiers éléments X[(X<15)] # Donne les éléments de X inférieur à 15 X[(X<17) & (X>13)] # Donne les éléments de X inférieurs à 17 ET supérieurs à 13 X[(X<13) | (X>17)] # Donne les éléments de X inférieurs à 13 OU supérieurs à 17
- Exemple complet
proverbe = c("un", "mot", "dit", "plus", "que", "une", "image");
> proverbe[1]
[1] "un"
> proverbe[2:3]
[1] "mot" "dit"
Les facteurs
- Il s'agit d'une sorte de vecteur qui stocke de façon un peu plus efficace des chaînes de caractères. C'est surtout utile lorsqu'on a des longues listes de valeurs nominales.
- Construction
- On utilise la fonction
factor
pour transformer un vecteur en facteur
> proverbe2 = c ("mot", "image", "mot", "image", "mot")
> facts = factor(proverbe2)
> facts
[1] mot image mot image mot
Levels: image mot
> proverbe2
[1] "mot" "image" "mot" "image" "mot"
Les listes
Une liste est comme un vecteur, mais peut contenir des données de type différent, y compris des listes. La représentation d'une liste est un peu plus verbeuse.
- Une liste simple se construit comme un vecteur, enfin on utilise la fonction
list
// Un vecteur
>emotions = c ("n", "chaud", "n", "chaud", "n", "froid")
>valeurs = c (0,2,0,1,0,-2)
// Une liste
> emotions2 = list ("n", "chaud", "n", "chaud", "n", "froid")
> emotions
[[1]]
[1] "n"
[[2]]
[1] "chaud"
[[3]]
[1] "n"
[[4]]
[1] "chaud"
[[5]]
[1] "n"
[[6]]
[1] "froid"
Une liste qui contient des listes peut se construire à partir de listes ou de vecteurs. Les listes imbriquées ne doivent pas forcément avoir la même longueur.
- Liste qui contient des vecteurs
> liste_10 = list (proverbe, emotions, valeurs)
> liste_10
[[1]]
[1] "un" "mot" "dit" "plus" "que" "une" "image"
[[2]]
[1] "n" "chaud" "n" "chaud" "n" "froid"
[[3]]
[1] 0 2 0 1 0 -2
- Exemple qui contient une liste
emotions2 = list ("n", "chaud", "n", "chaud", "n", "froid")
> liste_11 = list (proverbe2, emotions, valeurs)
> liste_11
[[1]]
[1] "mot" "image" "mot" "image" "mot" "image"
[[2]]
[[2]][[1]]
[1] "n"
[[2]][[2]]
[1] "chaud"
[[2]][[3]]
[1] "n"
[[2]][[4]]
[1] "chaud"
[[2]][[5]]
[1] "n"
[[2]][[6]]
[1] "froid"
[[3]]
[1] 0 2 0 1 0 -2
> liste_11[2]
[[1]]
[[1]][[1]]
[1] "n"
[[1]][[2]]
[1] "chaud"
[[1]][[3]]
[1] "n"
[[1]][[4]]
[1] "chaud"
[[1]][[5]]
[1] "n"
[[1]][[6]]
[1] "froid"
- Afficher un élément de liste
// Lister le 2ème élément (une liste dans notre cas)
> liste_10[2]
[[1]]
[1] "n" "chaud" "n" "chaud" "n" "froid"
Les listes associatives
On peut donner un nom aux éléments de liste. Cela permet par exemple de faire des simples base de données ou encore de "tagger" les mots d'un texte avec des annotations.
- Construction d'une liste associative
- On utilise la même fonction
list
, mais entre chaque valeur comme une paireclef=valeur
> phrase_courte = list (art="un", sujet="mot", verbe="dit")
> phrase_courte
$art
[1] "un"
$sujet
[1] "mot"
$verbe
[1] "dit"
Les matrices
- Les matrices sont des tableaux à N dimensions, typiquement un tableau à 2 dimensions. Pensez à une feuille de tableur.
- Une matrice contient des éléments du même type, par exemple des nombres ou encore des "strings" (chaîne de caractères) comme dans les exemples ci-dessous. Autrement dit, dans une matrice on ne peut pas retrouve à la fois des nombres et des strings.
- Construction manuelle d'une matrice à partir d'une liste
> m <- matrix(c('ah', 'be', 'cé', 'dé', 'euh', 'eff', 'gé', 'asch'), nrow = 2)
> m
[,1] [,2] [,3] [,4]
[1,] "ah" "cé" "euh" "gé"
[2,] "be" "dé" "eff" "asch"
- Construction d'une matrice à partir de vectors
- Notez que l'on construit d'abord un long vecteur avec la fonction c
mat <-matrix ( c(phrase_courte, phrase_courte2, phrase_courte3), nrow=3)
mat
- Extraire des données
- On utilisela notation
[ligne,colonne]
> m[1,]
[1] "ah" "cé" "euh" "gé"
> m[,2]
[1] "cé" "dé"
> m[2,1]
[1] "be"
Les array
- Les array (tableaux en français) ressemblent à des matrices, mais contiennent des informations supplémentaires
.....
Les data frames
Un data frame est un tableau composé de types de données différentes. On peut conceptualiser cela comme une sorte de combinaison entre une matrice et une liste à N dimensions ou mieux comme une collection de vecteurs la même longueur. Chaque vecteur est représenté comme une colonne et il possède un nom. En gros, on retrouve les tableaux de type Excel, SPSS, etc.
- Exemple de construction manuelle d'un data frame à partir de vecteurs représentation une variable.
- Par définition, R va identifier des "facteurs" (ou "levels"), c-a-d constituer une liste de différentes valeurs
> articles = c( "un", "le", "la", "les")
> sujets = c( "mot", "terme", "chose", "images")
> df_mots <- data.frame (articles, sujets)
> df_mots
articles sujets
1 un mot
2 le terme
3 la chose
4 les images
> typeof(df_mots)
[1] "list"
- Sortir des éléments
df_mots[3,1]
[1] la
Levels: la le les un
- Notez que R indique des "levels". Il s'agit de catégories (strings différents) que l'on retrouve dans un vecteur
- Construire un data frame sans "facteurs"
> df_mots2 <- data.frame (articles, sujets, stringsAsFactors = FALSE)
> df_mots2[3,1]
[1] "la"
- Exemple de construction manuelle d'un data frame à partir de données "cas"
- On construit d'abord des simples vecteurs à clef et ensuite on les combine
phrase_courte = c (art="un", sujet="mot", verbe="dit")
phrase_courte2 = c (art="une", sujet="image", verbe="parle")
phrase_courte3 = c (art="une", sujet="idee", verbe="est")
phr <- data.frame (phrase_courte, phrase_courte2, phrase_courte3)
phr
phrase_courte phrase_courte2 phrase_courte3
art un une une
sujet mot image idee
verbe dit parle est
Cette représentation n'est pas vraiment standarde. Normalement on présenterait chaque phrase en ligne. On peut donc permuter le data frame en utilisation la fonction t
et en spécifiant que le résultat doit de nouveau être un data frame avec la fonction as.data.frame
(sinon cela devient une matrice simple)
> phrases = as.data.frame(t(phr))
> phrases
art sujet verbe
phrase_courte un mot dit
phrase_courte2 une image parle
phrase_courte3 une idee est
- Utilisation de "variables" / vecteurs
- Chaque colonne représente une variable statistique (à ne pas confondre avec une variable de programmation ou "nom d'objet")
- Pour référencer une "colonne" (pensez "variable"), on utilise la notation
votre_data_frame$nom_colonne
> phrases$art
phrase_courte phrase_courte2 phrase_courte3
un une une
Levels: un une
> phrases$sujet
phrase_courte phrase_courte2 phrase_courte3
mot image idee
Levels: idee image mot
- Attacher / détacher un data frame
- Comme le data frame est la structure utilisé pour représenter un jeu de données quantitatif ou qualitatif/quantitatif, R permet permet d'attacher un data frame pour l'analyse.
Exemple d'un data frame:
df_mots3 <- data.frame (art = c( "un", "le", "la", "les"),
adj = c("gros", "petit", "drole de", "belles"),
suj = c( "mot", "terme", "chose", "images"),
stringsAsFactors = FALSE)
> df_mots3
art adj suj
1 un gros mot
2 le petit terme
3 la drole de chose
4 les belles images
Extraire une variable (vecteur):
> df_mot3$art
> df_mots$art
[1] un le la les
Levels: la le les un
Attacher un data frame avec attach()
:
> art
Error: object 'art' not found
> df_mots$art
[1] un le la les
Levels: la le les un
> attach (df_mots3)
> art
[1] "un" "le" "la" "les"
Détachez ensuite data frame avec detach()
detach (df_mots3)
Résumé d'opérations pour accéder aux structures de données
Accéder aux données juste pour voir ce qu'il y a l'intérieur est une des plus grandes frustrations pour le débutant (en cas pour nous). Il existe une panoplie de structures et les messages d'erreur ou les non messages ne renseignent guerre sur ce qu'on a mal fait.
Syntaxe | Type d'objets | Détails | Exemple |
---|---|---|---|
x[i] | Vecteurs et listes | i est un nombre, un string ou un vecteurs des deux. Retourne un vecteur ou une liste d'objets (même pour une seule valeur) | > obj= c(1,2,3,4)
> obj[2]
[1] 2
> obj[2:3]
[1] 2 3
|
x[[i]] | Vecteurs et listes | Retourne un élément singulier | > obj[[2]]
[1] 2
> obj[[2:3]]
Error in obj[[2:3]] : attempt to select more than one element
|
x$nom x["nom"] |
Listes | Retourne un objet nommé "nom" | ma_s3 = list (fleur = "Une jolie fleur rouge", arbre = "Un tronc brun et des feuilles vertes")
> ma_s3$fleur
[1] "Une jolie fleur rouge"
> ma_s3["fleur"]
$fleur
[1] "Une jolie fleur rouge"
|
x@nom | Objets S4 | Retourne un objet nommé "nom" | |
x[[i]][j]
|
liste à vecteurs | Les combinaisons sont difficiles à comprendre. Si on a une liste avec des vecteurs nommées il faut extraire un élément simple de la liste et ensuite l'élément du vecteur | ma_liste_vect = list (fleur = c ("Une", "jolie", "fleur", "rouge"), arbre = c ("Un", "tronc", "brun", "et", "des", "feuilles", "vertes"))
> ma_liste_vect[1]
$fleur
[1] "Une" "jolie" "fleur" "rouge"
> ma_liste_vect[1][2]
$<NA>
NULL
> ma_liste_vect[[1]][2]
[1] "jolie"
> ma_liste_vect[[1]][[2]]
[1] "jolie"
|
Et encore ....
ma_liste_vect = list (fleur = c ("Une", "jolie", "fleur", "rouge"),
arbre = c ("Un", "tronc", "brun", "et", "des", "feuilles", "vertes"))
for (j in seq.int (ma_liste_vect)) {
print (paste ("j=", j, ", Length=", length (ma_liste_vect[[j]])))
}
Les classes
R possède trois différents types de classes et probablement autant d'extensions.
Classes et objets S3
Les objets S3 représentent la "old school object-oriented programming" dans R. A éviter pour tout projet nouveau, mais il faut savoir les utiliser, car beaucoup de paquet utilisent encore cette infrastructure. Les classes S3 implémentent la possibilité de définir des fonctions du même nom qui agissent différemment en fonction du type de input. Les propriétés d'une classe sont des simples attributs.
La fonction unclass()
permet d'inspecter un objet
>unclass(ovid)
content
$content[[1]]
<<PlainTextDocument (metadata: 7)>>
Si quis in hoc artem populo non novit amandi,
hoc legat et lecto carmine doctus amet.
arte citae veloque rates remoque moventur,
[....]
$content[[2]]
<<PlainTextDocument (metadata: 7)>>
quas Hector sensurus erat, poscente magistro
verberibus iussas praebuit ille manus.
[...]
$meta
list()
attr(,"class")
[1] "CorpusMeta"
$dmeta
data frame with 0 columns and 5 rows
La fonction attributes permet de voir les attributs:
> attributes(ovid)
$names
[1] "content" "meta" "dmeta"
$class
[1] "VCorpus" "Corpus"
Examiner un seul document:
<source lang="matlab">
> class(ovid[[1]])
[1] "PlainTextDocument" "TextDocument"
Regarder les colonnes d'un data frame dans une classe S3
> ovid[[1]]$meta
Metadata:
author : character(0)
datetimestamp: 2014-11-25 15:53:09
description : character(0)
heading : character(0)
id : ovid_1.txt
language : lat
origin : character(0)
# Equivalent à
> meta(ovid[[1]])
Metadata:
author : character(0)
datetimestamp: 2014-11-25 15:53:09
description : character(0)
heading : character(0)
id : ovid_1.txt
language : lat
origin : character(0)
- Créer une classe S3
Tout d'abord on peut déclarer qu'un objet appartient à une classe en ajouter un nom avec la fonction class()
> ma_s3 = list (fleur = c ("Une, jolie, fleur, rouge"), arbre = c( "Un, tronc, brun, et, des, feuilles, vertes"))
> class (ma_s3)
[1] "character"
> class (ma_s3) <- append (class (ma_s3), "PhrasesPlantes")
> class (ma_s3)
[1] "character" "PhrasesPlantes"
> ma_s3
$fleur
[1] "Une, jolie, fleur, rouge"
$arbre
[1] "Un, tronc, brun, et, des, feuilles, vertes"
attr(,"class")
[1] "list" "PhrasesPlantes"
Maintenant, on pourrait créer des méthodes pour cette classe inutile.
Classes et objets S4
Les objets S4 sont des structures de données complexes basées sur une une classe, c'est-à-dire une définition abstraite d'une structure de données avec des méthodes associées. Ce type d'objet est produit par certaines analyses, par exemple la fonction treetag()
du paquet koRpus. Ce type de classes et de méthodes ont été introduits dans le language S avec la version 4. D'où leur nom étrange S4. Il s'agit tout simplement de la partie "objets moderne" du langage. Il existe aussi une version plus ancienne, S3.
References classes
Les "reference classes" étendent les classes S4 avec une autre syntaxe et un autre modèle pour les objets
- Les objets utilisent des références. Cela veut dire qu'un changement dans les données est permanent. Un objet S4 retourne juste un résultat changé, mais l'objet reste tel quel.
- Les méthodes sont stockés dans la classe.
... En gros, ces classes fonctionnent comme des classes C++ ou Java
Autres
Il existe d'autres structures de données que l'on introduit pas pour le moment.
Il est par contre important de savoir que certains paquetages (extensions) implémentent leur propre structure de données en utilisant des classes S3, S4 ou reference. C'est notamment le cas de l'extension text mining tm qui implémente Corpus
avec une classe S3.
Conversions
Conversion de types
La fonction as (objet, type)
permet de transformer un type de structure de données en une autre si possible.
> deux <- "2"
> deux2 <- as (deux, "numeric")
> deux
[1] "2"
> deux2
[1] 2
Exemple raté:
> trois <- "3 chats"
> trois3 <- as (trois, "numeric")
Warning message:
In asMethod(object) : NAs introduced by coercion
> trois3
[1] NA
Fonctions de conversion spécialisées
Il existe une panoplie de fonctions qui commencent par as. et qui font la coercition si possible. Par exemple
- as.vector
- as.vector.factor
- as.matrix
- as.array
- as.list
- as.data.frame
Ces fonctions sont bien documentées et prennent plusieurs arguments qu'on peut utiliser dans des cas de conversion plus compliqués.
- Exemple data frame vers matrice
> df_mots3
art adj suj
1 un gros mot
2 le petit terme
3 la drole de chose
4 les belles images
> mat_mots3 <- as.matrix(df_mots3)
> mat_mots3
art adj suj
[1,] "un" "gros" "mot"
[2,] "le" "petit" "terme"
[3,] "la" "drole de" "chose"
[4,] "les" "belles" "images"
La fonction as.matrix
possède plusieurs arguments qui facilite une conversion dans des situations plus compliqués.
Il faut également veilleur à examiner les fonctions de base pour voir si elle ne font pas conversions. Par exemple, pour passe d'un vecteur simple à une matrice, on utilisera matrix
# On définit une liste
liste_bete <- c (1,2,3,4,5,6)
# On matrixifie
matrix ( liste_bete, nrow =2, ncol=3)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
Suject connexes
Gestion de l'encodage
Il est important de bien gérer les encodages. A priori il faut toujour veiller à tout faire en UTF-8. Il arrive malheureusement de
- tomber sur des textes encodés dans un format archaique (comme ISO-latin ou pire une variante Windows)
- tomber sur des paquets R qui par défaut utilisent un encodage ascii ou ISO.
(à compléter)