Débuts avec les données

Last updated on 2026-11-07 | Edit this page

Overview

Questions

  • Première analyse de données dans R

Objectives

  • Décrivez ce qu’est un data.frame.
  • Charger des données externes depuis un fichier .csv dans un tableau de données.
  • Résumer le contenu d’un tableau de données.
  • Décrivez ce qu’est un facteur.
  • Convertir entre chaînes de caractères et facteurs.
  • Réordonner et renommer les facteurs.
  • Formater les dates.
  • Exporter et enregistrer les données.

Cet épisode est basé sur la leçon Data Analysis and Visualisation in R for Ecologists de Data Carpentries.

Présentation des données d’expression génique


Nous allons utiliser une partie des données publiées par Blackmore et al. (2017), The effect of upper-respiratory infection on transcriptomic changes in the CNS. L’objectif de l’étude était de déterminer l’effet d’une infection des voies respiratoires supérieures sur les modifications de la transcription de l’ARN dans le cervelet et la moelle épinière après l’infection. Des souris C57BL/6 âgées de huit semaines et appariées selon le sexe ont reçu, par voie intranasale, du sérum physiologique ou le virus de la grippe A. Les modifications transcriptomiques dans les tissus du cervelet et de la moelle épinière ont été évaluées par RNA-seq aux jours 0 (souris non infectées), 4 et 8.

L’ensemble de données est stocké sous la forme d’un fichier de valeurs séparées par des virgules (CSV). Chaque ligne contient des informations concernant une seule mesure d’expression ARN, et les onze premières colonnes représentent :

Colonne Description
gene Le nom du gène mesuré
sample Le nom de l’échantillon dans lequel l’expression génique a été mesurée
expression La valeur de l’expression génique
organism L’organisme/l’espèce - ici, toutes les données proviennent de souris
age L’âge de la souris (ici, toutes les souris avaient 8 semaines)
sex Le sexe de la souris
infection L’état infectieux de la souris, c’est-à-dire infectée par le virus de la grippe A ou non infectée.
strain La souche du virus de la grippe A.
time La durée de l’infection (en jours).
tissue Le tissu utilisé pour l’expérience d’expression génique, c’est-à-dire le cervelet ou la moelle épinière.
mouse L’identifiant unique de la souris.

Nous allons utiliser la fonction R download.file() pour télécharger le fichier CSV contenant les données d’expression génique, et nous utiliserons read.csv() pour charger dans la mémoire le contenu du fichier CSV sous la forme d’un objet de classe data.frame. Dans la commande download.file, la première entrée est une chaîne de caractères contenant l’URL de la source. Cette URL de source télécharge un fichier CSV depuis un dépôt GitHub. Le texte après la virgule ("data/rnaseq.csv") correspond à la destination du fichier sur votre machine locale. Vous devrez disposer d’un dossier sur votre machine nommé "data" où vous téléchargerez le fichier. Ainsi, cette commande télécharge le fichier distant, le nomme "rnaseq.csv" et l’ajoute à un dossier déjà existant nommé "data".

R

download.file(url = "https://github.com/carpentries-incubator/bioc-intro/raw/main/episodes/data/rnaseq.csv",
              destfile = "data/rnaseq.csv")

Vous êtes désormais prêt à charger les données :

R

rna <- read.csv("data/rnaseq.csv")

Cette instruction ne produit aucun résultat car, comme vous vous en souvenez peut-être, les affectations n’affichent rien. Si nous voulons vérifier que nos données ont été chargées, nous pouvons consulter le contenu du tableau de données en saisissant son nom :

R

rna

Waouh… c’était beaucoup de résultats. Au moins, cela signifie que les données ont été chargées correctement. Vérifions le début (les 6 premières lignes) de ce tableau de données à l’aide de la fonction head() :

R

head(rna)

OUTPUT

     gene     sample expression     organism age    sex  infection  strain time
1     Asl GSM2545336       1170 Mus musculus   8 Female InfluenzaA C57BL/6    8
2    Apod GSM2545336      36194 Mus musculus   8 Female InfluenzaA C57BL/6    8
3 Cyp2d22 GSM2545336       4060 Mus musculus   8 Female InfluenzaA C57BL/6    8
4    Klk6 GSM2545336        287 Mus musculus   8 Female InfluenzaA C57BL/6    8
5   Fcrls GSM2545336         85 Mus musculus   8 Female InfluenzaA C57BL/6    8
6  Slc2a4 GSM2545336        782 Mus musculus   8 Female InfluenzaA C57BL/6    8
      tissue mouse ENTREZID
1 Cerebellum    14   109900
2 Cerebellum    14    11815
3 Cerebellum    14    56448
4 Cerebellum    14    19144
5 Cerebellum    14    80891
6 Cerebellum    14    20528
                                                                       product
1                               argininosuccinate lyase, transcript variant X1
2                                       apolipoprotein D, transcript variant 3
3 cytochrome P450, family 2, subfamily d, polypeptide 22, transcript variant 2
4                         kallikrein related-peptidase 6, transcript variant 2
5                Fc receptor-like S, scavenger receptor, transcript variant X1
6          solute carrier family 2 (facilitated glucose transporter), member 4
     ensembl_gene_id external_synonym chromosome_name   gene_biotype
1 ENSMUSG00000025533    2510006M18Rik               5 protein_coding
2 ENSMUSG00000022548             <NA>              16 protein_coding
3 ENSMUSG00000061740             2D22              15 protein_coding
4 ENSMUSG00000050063             Bssp               7 protein_coding
5 ENSMUSG00000015852    2810439C17Rik               3 protein_coding
6 ENSMUSG00000018566           Glut-4              11 protein_coding
                            phenotype_description
1           abnormal circulating amino acid level
2                      abnormal lipid homeostasis
3                        abnormal skin morphology
4                         abnormal cytokine level
5 decreased CD8-positive alpha-beta T cell number
6              abnormal circulating glucose level
  hsapiens_homolog_associated_gene_name
1                                   ASL
2                                  APOD
3                                CYP2D6
4                                  KLK6
5                                 FCRL2
6                                SLC2A4

R

## Try also
## View(rna)

Note

read.csv() suppose que les champs sont séparés par des virgules ; cependant, dans plusieurs pays, la virgule est utilisée comme séparateur décimal et le point-virgule (;) comme séparateur de champs. Si vous souhaitez lire ce type de fichiers dans R, vous pouvez utiliser la fonction read.csv2(). Elle se comporte exactement comme read.csv(), mais utilise des paramètres différents pour les séparateurs décimaux et de champs. Si vous travaillez avec un autre format, ces deux paramètres peuvent être spécifiés par l’utilisateur. Consultez l’aide de read.csv() en saisissant ?read.csv pour en savoir plus. Il existe également la fonction read.delim() pour lire des fichiers de données séparés par des tabulations. Il est important de noter que toutes ces fonctions sont en réalité des fonctions wrapper pour la fonction principale read.table() avec des arguments différents. Ainsi, les données ci-dessus auraient également pu être chargées en utilisant read.table() avec le paramètre de séparation ,. Le code est le suivant :

R

rna <- read.table(file = "data/rnaseq.csv",
                  sep = ",",
                  header = TRUE)

L’argument header doit être défini à TRUE pour pouvoir lire les en-têtes, car par défaut, read.table() a l’argument header défini à FALSE.

Qu’est-ce que des tableaux de données ?


Les tableaux de données sont la structure de données de facto pour la plupart des données tabulaires, et ce que nous utilisons pour la statistique et la représentation graphique.

Un tableau de données peut être créé manuellement, mais il est le plus souvent généré par les fonctions read.csv() ou read.table() ; en d’autres termes, lors de l’importation de feuilles de calcul depuis votre disque dur (ou le Web).

Un tableau de données est la représentation de données sous la forme d’un tableau où les colonnes sont des vecteurs de longueur identique. Comme les colonnes sont des vecteurs, chacune d’elles doit contenir un seul type de données (par exemple, des caractères, des entiers, des facteurs). Voici, par exemple, une figure illustrant un tableau de données comprenant un vecteur numérique, un vecteur de caractères et un vecteur logique.

Schematic representation of a tablular structure with different colours representing different columns and variables types.
Conceptual representation of a data.frame

Nous pouvons le constater en examinant la structure d’un tableau de données avec la fonction str() :

R

str(rna)

OUTPUT

'data.frame':	32428 obs. of  19 variables:
 $ gene                                 : chr  "Asl" "Apod" "Cyp2d22" "Klk6" ...
 $ sample                               : chr  "GSM2545336" "GSM2545336" "GSM2545336" "GSM2545336" ...
 $ expression                           : int  1170 36194 4060 287 85 782 1619 288 43217 1071 ...
 $ organism                             : chr  "Mus musculus" "Mus musculus" "Mus musculus" "Mus musculus" ...
 $ age                                  : int  8 8 8 8 8 8 8 8 8 8 ...
 $ sex                                  : chr  "Female" "Female" "Female" "Female" ...
 $ infection                            : chr  "InfluenzaA" "InfluenzaA" "InfluenzaA" "InfluenzaA" ...
 $ strain                               : chr  "C57BL/6" "C57BL/6" "C57BL/6" "C57BL/6" ...
 $ time                                 : int  8 8 8 8 8 8 8 8 8 8 ...
 $ tissue                               : chr  "Cerebellum" "Cerebellum" "Cerebellum" "Cerebellum" ...
 $ mouse                                : int  14 14 14 14 14 14 14 14 14 14 ...
 $ ENTREZID                             : int  109900 11815 56448 19144 80891 20528 97827 118454 18823 14696 ...
 $ product                              : chr  "argininosuccinate lyase, transcript variant X1" "apolipoprotein D, transcript variant 3" "cytochrome P450, family 2, subfamily d, polypeptide 22, transcript variant 2" "kallikrein related-peptidase 6, transcript variant 2" ...
 $ ensembl_gene_id                      : chr  "ENSMUSG00000025533" "ENSMUSG00000022548" "ENSMUSG00000061740" "ENSMUSG00000050063" ...
 $ external_synonym                     : chr  "2510006M18Rik" NA "2D22" "Bssp" ...
 $ chromosome_name                      : chr  "5" "16" "15" "7" ...
 $ gene_biotype                         : chr  "protein_coding" "protein_coding" "protein_coding" "protein_coding" ...
 $ phenotype_description                : chr  "abnormal circulating amino acid level" "abnormal lipid homeostasis" "abnormal skin morphology" "abnormal cytokine level" ...
 $ hsapiens_homolog_associated_gene_name: chr  "ASL" "APOD" "CYP2D6" "KLK6" ...

Inspection des objets data.frame


Nous avons déjà vu comment les fonctions head() et str() peuvent être utiles pour vérifier le contenu et la structure d’un tableau de données. Voici une liste non exhaustive de fonctions permettant de se faire une idée du contenu et de la structure des données. Essayons-les !

Taille :

  • dim(rna) - retourne un vecteur dont le premier élément est le nombre de lignes et le second le nombre de colonnes (les dimensions de l’objet).
  • nrow(rna) - renvoie le nombre de lignes.
  • ncol(rna) - renvoie le nombre de colonnes.

Contenu :

  • head(rna) - affiche les 6 premières lignes.
  • tail(rna) - affiche les 6 dernières lignes.

Noms :

  • names(rna) - renvoie les noms des colonnes (synonyme de colnames() pour les objets data.frame).
  • rownames(rna) - renvoie les noms de lignes.

Résumé :

  • str(rna) - structure de l’objet et informations sur la classe, la longueur et le contenu de chaque colonne.
  • summary(rna) - statistiques de synthèse pour chaque colonne.

Note : la plupart de ces fonctions sont « génériques » ; elles peuvent être utilisées sur d’autres types d’objets en plus de data.frame.

Challenge

Défi :

Sur la base de la sortie de str(rna), pouvez-vous répondre aux questions suivantes ?

  • Quelle est la classe de l’objet rna ?
  • Combien y a-t-il de lignes et de colonnes dans cet objet ?
  • classe : tableau de données
  • nombre de lignes : 32428, nombre de colonnes : 19

Indexation et extraction de sous-ensembles de tableaux de données


Notre tableau de données rna possède des lignes et des colonnes (il a 2 dimensions) ; si nous souhaitons en extraire certaines données spécifiques, nous devons spécifier les « coordonnées » souhaitées. Les numéros de ligne viennent en premier, suivis des numéros de colonne. Notez toutefois que différentes manières de spécifier ces coordonnées donnent des résultats de classes différentes.

R

# first element in the first column of the data frame (as a vector)
rna[1, 1]
# first element in the 6th column (as a vector)
rna[1, 6]
# first column of the data frame (as a vector)
rna[, 1]
# first column of the data frame (as a data.frame)
rna[1]
# first three elements in the 7th column (as a vector)
rna[1:3, 7]
# the 3rd row of the data frame (as a data.frame)
rna[3, ]
# equivalent to head_rna <- head(rna)
head_rna <- rna[1:6, ]
head_rna

: est une fonction spéciale qui crée des vecteurs numériques d’entiers en ordre croissant ou décroissant ; voyez par exemple 1:10 et 10:1. Consultez la section Génération de vecteurs pour plus de détails.

Vous pouvez également exclure certains indices d’un tableau de données en utilisant le signe « - » :

R

rna[, -1]          ## The whole data frame, except the first column
rna[-c(7:66465), ] ## Equivalent to head(rna)

On peut extraire des sous-ensembles de tableaux de données en utilisant des indices (comme illustré précédemment), mais aussi directement les noms des colonnes :

R

rna["gene"]       # Result is a data.frame
rna[, "gene"]     # Result is a vector
rna[["gene"]]     # Result is a vector
rna$gene          # Result is a vector

Dans RStudio, vous pouvez utiliser la fonctionnalité d’autocomplétion pour obtenir les noms complets et corrects des colonnes.

Challenge

Défi

  1. Créez un data.frame (rna_200) contenant uniquement les données de la ligne 200 du jeu de données rna.

  2. Remarquez comment nrow() vous a donné le nombre de lignes dans un data.frame ?

  • Utilisez ce nombre pour extraire uniquement cette dernière ligne du tableau de données initial rna.

  • Comparez cela avec ce que vous voyez comme la dernière ligne à l’aide de tail() pour vous assurer que cela correspond aux attentes.

  • Extrayez cette dernière ligne en utilisant nrow() au lieu du numéro de ligne.

  • Créez un nouveau tableau de données (rna_last) à partir de cette dernière ligne.

  1. Utilisez nrow() pour extraire la ligne située au milieu du tableau de données rna. Stockez le contenu de cette ligne dans un objet nommé rna_middle.

  2. Combinez nrow() avec la notation - ci-dessus pour reproduire le comportement de head(rna), en ne gardant que les premières 6 lignes du jeu de données rna.

R

## 1.
rna_200 <- rna[200, ]
## 2.
## Saving `n_rows` to improve readability and reduce duplication
n_rows <- nrow(rna)
rna_last <- rna[n_rows, ]
## 3.
rna_middle <- rna[n_rows / 2, ]
## 4.
rna_head <- rna[-(7:n_rows), ]

Facteurs


Les facteurs représentent des données catégorielles. Ils sont stockés sous forme d’entiers associés à des étiquettes et peuvent être ordonnés ou non. Bien que les facteurs ressemblent (et se comportent souvent) à des vecteurs de caractères, ils sont en réalité traités comme des vecteurs entiers par R. Il faut donc être très prudent lorsque l’on les traite comme des chaînes de caractères.

Une fois créés, les facteurs ne peuvent contenir qu’un ensemble prédéfini de valeurs, appelées niveaux. Par défaut, R trie toujours les niveaux par ordre alphabétique. Par exemple, si vous avez un facteur avec 2 niveaux :

R

sex <- factor(c("male", "female", "female", "male", "female"))

R attribuera 1 au niveau "female" et 2 au niveau "male" (car f précède m, même si le premier élément de ce vecteur est "male"). Vous pouvez vérifier cela en utilisant la fonction levels() et vous pouvez trouver le nombre de niveaux à l’aide de nlevels() :

R

levels(sex)

OUTPUT

[1] "female" "male"  

R

nlevels(sex)

OUTPUT

[1] 2

Parfois, l’ordre des facteurs n’a aucune importance ; d’autres fois, vous souhaiterez peut-être en spécifier l’ordre car celui-ci a un sens (par ex. « low », « medium », « high »), car il améliore votre visualisation ou parce qu’il est requis par un type d’analyse particulier. Ici, l’un des moyens de réordonner nos niveaux dans le vecteur sex serait :

R

sex ## current order

OUTPUT

[1] male   female female male   female
Levels: female male

R

sex <- factor(sex, levels = c("male", "female"))
sex ## after re-ordering

OUTPUT

[1] male   female female male   female
Levels: male female

Dans la mémoire de R, ces facteurs sont représentés par des entiers (1, 2, 3), mais ils sont plus informatifs que les entiers car les facteurs sont auto-descriptifs : "female", "male" est plus descriptif que 1, 2. Lequel est « mâle » ? Vous ne pourriez pas le déterminer uniquement à partir des données entières. Les facteurs, en revanche, intègrent cette information. Cela est particulièrement utile lorsqu’il y a de nombreux niveaux (comme le biotype génique dans notre jeu de données d’exemple).

Lorsque vos données sont stockées sous forme de facteur, vous pouvez utiliser la fonction plot() pour obtenir un aperçu rapide du nombre d’observations représentées par chaque niveau de facteur. Examinons le nombre de mâles et de femelles dans nos données.

R

plot(sex)
Barplot showing the number of 'male' and 'female' occurrences.
Bar plot of the number of females and males.

Conversion en chaîne de caractères

Si vous devez convertir un facteur en vecteur de caractères, vous utilisez as.character(x).

R

as.character(sex)

OUTPUT

[1] "male"   "female" "female" "male"   "female"

Renommage des facteurs

Si nous souhaitons renommer ce facteur, il suffit de modifier ses niveaux :

R

levels(sex)

OUTPUT

[1] "male"   "female"

R

levels(sex) <- c("M", "F")
sex

OUTPUT

[1] M F F M F
Levels: M F

R

plot(sex)
Barplot showing the number of 'M' and 'F' occurrences.
Challenge

Défi :

  • Remplacez « F » et « M » par « Female » et « Male » respectivement.

R

levels(sex)

OUTPUT

[1] "M" "F"

R

levels(sex) <- c("Male", "Female")
Challenge

Défi :

Nous avons vu comment créer des tableaux de données en utilisant read.csv(), mais ils peuvent également être créés manuellement avec la fonction data.frame(). Il y a quelques erreurs dans ce data.frame conçu à la main. Pouvez-vous les repérer et les corriger ? N’hésitez pas à expérimenter !

R

animal_data <- data.frame(
       animal = c(dog, cat, sea cucumber, sea urchin),
       feel = c("furry", "squishy", "spiny"),
       weight = c(45, 8 1.1, 0.8))
  • absence de guillemets autour des noms des animaux
  • une entrée manquante dans la colonne « feel » (probablement pour l’un des animaux à poils)
  • une virgule manquante dans la colonne du poids
Challenge

Défi :

Pouvez-vous prédire la classe de chacune des colonnes dans l’exemple suivant ?

Vérifiez vos conjectures à l’aide de str(country_climate) :

  • Sont-elles ce que vous attendiez ? Pourquoi ? Pourquoi pas ?

  • Réessayez en ajoutant stringsAsFactors = TRUE après la dernière variable lors de la création du tableau de données. Que se passe-t-il maintenant ? stringsAsFactors peut également être défini lors de la lecture de feuilles de calcul textuelles dans R à l’aide de read.csv().

R

country_climate <- data.frame(
       country = c("Canada", "Panama", "South Africa", "Australia"),
       climate = c("cold", "hot", "temperate", "hot/temperate"),
       temperature = c(10, 30, 18, "15"),
       northern_hemisphere = c(TRUE, TRUE, FALSE, "FALSE"),
       has_kangaroo = c(FALSE, FALSE, FALSE, 1)
       )

R

country_climate <- data.frame(
       country = c("Canada", "Panama", "South Africa", "Australia"),
       climate = c("cold", "hot", "temperate", "hot/temperate"),
       temperature = c(10, 30, 18, "15"),
       northern_hemisphere = c(TRUE, TRUE, FALSE, "FALSE"),
       has_kangaroo = c(FALSE, FALSE, FALSE, 1)
       )
str(country_climate)

OUTPUT

'data.frame':	4 obs. of  5 variables:
 $ country            : chr  "Canada" "Panama" "South Africa" "Australia"
 $ climate            : chr  "cold" "hot" "temperate" "hot/temperate"
 $ temperature        : chr  "10" "30" "18" "15"
 $ northern_hemisphere: chr  "TRUE" "TRUE" "FALSE" "FALSE"
 $ has_kangaroo       : num  0 0 0 1

La conversion automatique du type de données est parfois une chance, parfois une source de frustration. Sachez qu’elle existe, apprenez les règles et vérifiez à nouveau que les données que vous importez dans R sont du type correct au sein de votre tableau de données. Si ce n’est pas le cas, utilisez-la à votre avantage pour détecter des erreurs qui auraient pu être introduites lors de la saisie des données (par exemple, une lettre dans une colonne qui ne devrait contenir que des nombres).

En savoir plus dans ce tutoriel RStudio

Matrices


Avant de poursuivre, maintenant que nous avons découvert les tableaux de données, rappelons l’installation des packages et apprenons un nouveau type de données, à savoir le matrix. Comme le data.frame, une matrice possède deux dimensions : des lignes et des colonnes. Mais la différence majeure est que toutes les cellules d’une matrix doivent être du même type : numeric, character, logical, … À cet égard, les matrices sont plus proches d’un vector que d’un data.frame.

Le constructeur par défaut pour une matrice est matrix. Il prend un vecteur de valeurs pour remplir la matrice ainsi que le nombre de lignes et/ou de colonnes1. Les valeurs sont disposées colonne par colonne, comme illustré ci-dessous.

R

m <- matrix(1:9, ncol = 3, nrow = 3)
m

OUTPUT

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
Challenge

Défi :

À l’aide de la fonction installed.packages(), créez une matrice character contenant les informations sur tous les packages actuellement installés sur votre ordinateur. Analysez-la.

R

## create the matrix
ip <- installed.packages()
head(ip)
## try also View(ip)
## number of package
nrow(ip)
## names of all installed packages
rownames(ip)
## type of information we have about each package
colnames(ip)

Il est souvent utile de créer de grandes matrices de données aléatoires pour servir de données de test. L’exercice ci-dessous vous demande de créer une telle matrice avec des données aléatoires tirées d’une distribution normale de moyenne 0 et d’écart-type 1, ce qui peut être réalisé avec la fonction rnorm().

Challenge

Défi :

Construisez une matrice de 1000 lignes et 3 colonnes contenant des données suivant une loi normale de moyenne 0 et d’écart-type 1.

R

set.seed(123)
m <- matrix(rnorm(3000), ncol = 3)
dim(m)

OUTPUT

[1] 1000    3

R

head(m)

OUTPUT

            [,1]        [,2]       [,3]
[1,] -0.56047565 -0.99579872 -0.5116037
[2,] -0.23017749 -1.03995504  0.2369379
[3,]  1.55870831 -0.01798024 -0.5415892
[4,]  0.07050839 -0.13217513  1.2192276
[5,]  0.12928774 -2.54934277  0.1741359
[6,]  1.71506499  1.04057346 -0.6152683

Mise en forme des dates


L’un des problèmes les plus fréquents rencontrés par les nouveaux utilisateurs de R (ainsi que par les utilisateurs expérimentés !) est la conversion des informations de date et d’heure en une variable appropriée et utilisable lors des analyses.

Note sur les dates dans les logiciels de feuilles de calcul

Les dates dans les feuilles de calcul sont généralement stockées dans une seule colonne. Bien que cela semble être la manière la plus naturelle de consigner les dates, il ne s’agit en réalité pas d’une bonne pratique. Une application de feuille de calcul affichera les dates d’une manière apparemment correcte (pour un observateur humain), mais la façon dont elle gère et stocke réellement les dates peut s’avérer problématique. Il est souvent bien plus sûr de stocker les dates avec l’ANNÉE, le MOIS et le JOUR dans des colonnes distinctes, ou sous la forme d’ANNÉE et de JOUR DE L’ANNÉE dans des colonnes distinctes.

Les logiciels de feuilles de calcul tels que LibreOffice, Microsoft Excel, OpenOffice, Gnumeric, … utilisent des méthodes d’encodage des dates différentes (et souvent incompatibles) (même au sein d’un même logiciel entre les versions et les systèmes d’exploitation). De plus, Excel peut convertir des éléments qui ne sont pas des dates en dates ( Zeeberg et al. (2004) ), par exemple des noms ou des identifiants tels que MAR1, DEC1, OCT4. Ainsi, si vous évitez globalement le format de date, il est plus facile d’identifier ces problèmes.

La section Dates as data de la leçon Data Carpentry apporte des informations complémentaires sur les pièges liés aux dates dans les feuilles de calcul.

Nous allons utiliser la fonction ymd() du package lubridate (qui appartient au tidyverse ; en savoir plus sur le site web de tidyverse). lubridate est installé dans le cadre de l’installation de tidyverse. Lorsque vous chargez tidyverse (library(tidyverse)), les packages principaux (les packages utilisés dans la plupart des analyses de données) sont chargés. lubridate ne fait cependant pas partie du tidyverse principal, vous devez donc le charger explicitement avec library(lubridate).

Commencez par charger le package requis :

R

library("lubridate")

ymd() prend en entrée un vecteur représentant l’année, le mois et le jour, et le convertit en vecteur Date. Date est une classe de données reconnue par R comme étant une date et peut être manipulée en tant que telle. L’argument requis par la fonction est flexible, mais, selon les bonnes pratiques, il s’agit d’un vecteur de caractères formaté sous la forme « YYYY-MM-DD ».

Créons un objet date et examinons sa structure :

R

my_date <- ymd("2015-01-01")
str(my_date)

OUTPUT

 Date[1:1], format: "2015-01-01"

Concaténons maintenant l’année, le mois et le jour fournis séparément : nous obtenons le même résultat.

R

# sep indicates the character to use to separate each component
my_date <- ymd(paste("2015", "1", "1", sep = "-"))
str(my_date)

OUTPUT

 Date[1:1], format: "2015-01-01"

Familiarisons-nous maintenant avec un pipeline typique de manipulation de dates. Le petit jeu de données ci-dessous contient des dates stockées dans des colonnes distinctes year, month et day.

R

x <- data.frame(year = c(1996, 1992, 1987, 1986, 2000, 1990, 2002, 1994, 1997, 1985),
                month = c(2,  3,  3, 10,  1,  8,  3,  4,  5,  5),
                day = c(24,  8,  1,  5,  8, 17, 13, 10, 11, 24),
                value = c(4,  5,  1,  9,  3,  8, 10,  2,  6,  7))
x

OUTPUT

   year month day value
1  1996     2  24     4
2  1992     3   8     5
3  1987     3   1     1
4  1986    10   5     9
5  2000     1   8     3
6  1990     8  17     8
7  2002     3  13    10
8  1994     4  10     2
9  1997     5  11     6
10 1985     5  24     7

Nous appliquons maintenant cette fonction au jeu de données x. Nous créons d’abord un vecteur de caractères à partir des colonnes year, month et day de x en utilisant paste() :

R

paste(x$year, x$month, x$day, sep = "-")

OUTPUT

 [1] "1996-2-24" "1992-3-8"  "1987-3-1"  "1986-10-5" "2000-1-8"  "1990-8-17"
 [7] "2002-3-13" "1994-4-10" "1997-5-11" "1985-5-24"

Ce vecteur de caractères peut être utilisé comme argument pour ymd() :

R

ymd(paste(x$year, x$month, x$day, sep = "-"))

OUTPUT

 [1] "1996-02-24" "1992-03-08" "1987-03-01" "1986-10-05" "2000-01-08"
 [6] "1990-08-17" "2002-03-13" "1994-04-10" "1997-05-11" "1985-05-24"

Le vecteur Date obtenu peut être ajouté à x sous la forme d’une nouvelle colonne appelée date :

R

x$date <- ymd(paste(x$year, x$month, x$day, sep = "-"))
str(x) # notice the new column, with 'date' as the class

OUTPUT

'data.frame':	10 obs. of  5 variables:
 $ year : num  1996 1992 1987 1986 2000 ...
 $ month: num  2 3 3 10 1 8 3 4 5 5
 $ day  : num  24 8 1 5 8 17 13 10 11 24
 $ value: num  4 5 1 9 3 8 10 2 6 7
 $ date : Date, format: "1996-02-24" "1992-03-08" ...

Vérifions que tout a bien fonctionné. L’un des moyens d’examiner la nouvelle colonne est d’utiliser summary() :

R

summary(x$date)

OUTPUT

        Min.      1st Qu.       Median         Mean      3rd Qu.         Max.
"1985-05-24" "1988-01-11" "1993-03-24" "1993-03-18" "1997-01-20" "2002-03-13" 

Notez que ymd() attend l’année, le mois et le jour, dans cet ordre. Si vous avez, par exemple, le jour, le mois et l’année, vous aurez besoin de dmy().

R

dmy(paste(x$day, x$month, x$year, sep = "-"))

OUTPUT

 [1] "1996-02-24" "1992-03-08" "1987-03-01" "1986-10-05" "2000-01-08"
 [6] "1990-08-17" "2002-03-13" "1994-04-10" "1997-05-11" "1985-05-24"

lubdridate dispose de nombreuses fonctions pour gérer toutes les variations de dates.

Résumé des objets R


Jusqu’à présent, nous avons vu plusieurs types d’objets R, différant par le nombre de dimensions et par le fait qu’ils pouvaient stocker un seul ou plusieurs types de données :

  • vector : une dimension (une longueur), un seul type de données.
  • matrix : deux dimensions, un seul type de données.
  • data.frame : deux dimensions, un type par colonne.

Listes


Les listes sont un type de données que nous n’avons pas encore vu, mais qu’il est utile de connaître et qui complète le résumé que nous venons de voir :

  • list : une dimension, chaque élément peut être d’un type de données différent.

Ci-dessous, créons une liste contenant un vecteur de nombres, des caractères, une matrice, un tableau de données et une autre liste :

R

l <- list(1:10, ## numeric
          letters, ## character
          installed.packages(), ## a matrix
          cars, ## a data.frame
          list(1, 2, 3)) ## a list
length(l)

OUTPUT

[1] 5

R

str(l)

OUTPUT

List of 5
 $ : int [1:10] 1 2 3 4 5 6 7 8 9 10
 $ : chr [1:26] "a" "b" "c" "d" ...
 $ : chr [1:190, 1:17] "abind" "askpass" "assertthat" "backports" ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:190] "abind" "askpass" "assertthat" "backports" ...
  .. ..$ : chr [1:17] "Package" "LibPath" "Version" "Priority" ...
 $ :'data.frame':	50 obs. of  2 variables:
  ..$ speed: num [1:50] 4 4 7 7 8 9 10 10 10 11 ...
  ..$ dist : num [1:50] 2 10 4 22 16 10 18 26 34 17 ...
 $ :List of 3
  ..$ : num 1
  ..$ : num 2
  ..$ : num 3

La sous-sélection de listes s’effectue à l’aide de [] pour créer une nouvelle sous-liste ou de [[]] pour extraire un seul élément de cette liste (en utilisant des indices ou des noms, si la liste est nommée).

R

l[[1]] ## first element

OUTPUT

 [1]  1  2  3  4  5  6  7  8  9 10

R

l[1:2] ## a list of length 2

OUTPUT

[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10

[[2]]
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x" "y" "z"

R

l[1]   ## a list of length 1

OUTPUT

[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10

Exportation et sauvegarde de données tabulaires


Nous avons vu comment importer une feuille de calcul textuelle dans R à l’aide de la famille de fonctions read.table. Pour exporter un data.frame vers une feuille de calcul textuelle, nous pouvons utiliser l’ensemble de fonctions write.table (write.csv, write.delim, …). Elles prennent toutes en argument la variable à exporter et le fichier de destination. Par exemple, pour exporter les données rna vers le fichier my_rna.csv dans le répertoire data_output, nous exécuterions :

R

write.csv(rna, file = "data_output/my_rna.csv")

Ce nouveau fichier CSV peut désormais être partagé avec d’autres collaborateurs qui ne maîtrisent pas R. Notez que, bien qu’il y ait des virgules dans certains champs du data.frame (voir par exemple la colonne « product »), R entourera par défaut chaque champ de guillemets, et nous pourrons donc le lire correctement dans R, malgré l’utilisation également de virgules comme séparateurs de colonnes.

Key Points
  • Données tabulaires dans R
Zeeberg, Barry R., Joseph Riss, David W. Kane, et al. 2004. “Mistaken Identifiers: Gene Name Errors Can Be Introduced Inadvertently When Using Excel in Bioinformatics.” BMC Bioinformatics 5 (1): 80. https://doi.org/10.1186/1471-2105-5-80.

  1. Le nombre de lignes ou de colonnes suffit, car l’autre peut être déduit de la longueur des valeurs. Essayez de voir ce qui se passe si les valeurs et le nombre de lignes/colonnes ne correspondent pas.↩︎