source | title | teaching | exercises |
---|---|---|---|
Rmd |
Manipulation et analyse de données avec dplyr |
75 |
75 |
::::::::::::::::::::::::::::::::::::::: objectives
- Décrivez l'objectif des packages
dplyr
ettidyr
. - Décrivez plusieurs de leurs fonctions extrêmement utiles pour manipuler des données.
- Décrivez le concept d'un format de tableau large et long, et voyez comment remodeler un bloc de données d'un format à l'autre.
- Montrez comment joindre des tables.
::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::: questions
- Analyse de données dans R à l'aide du méta-paquet Tidyverse
::::::::::::::::::::::::::::::::::::::::::::::::::
if (!file.exists("data/rnaseq.csv"))
download.file(url = "https://github.com/carpentries-incubator/bioc-intro/raw/main/episodes/data/rnaseq.csv",
destfile = "data/rnaseq.csv")
Cet épisode est basé sur la leçon Analyse des données et Visualisation dans R pour les écologistes de Data Carpentries.
Le sous-ensemble entre crochets est pratique, mais il peut être fastidieux et difficile à lire, en particulier pour les opérations compliquées.
Certains packages peuvent grandement faciliter notre tâche lorsque nous manipulons des données.
Les packages dans R sont essentiellement des ensembles de fonctions supplémentaires qui vous permettent
de faire plus de choses. Les fonctions que nous avons utilisées jusqu'à présent, comme str()
ou
data.frame()
, sont intégrées à R ; Le chargement de packages peut vous donner accès à d'autres
fonctions spécifiques. Avant d'utiliser un package pour la première fois, vous devez l'installer
sur votre machine, puis vous devez l'importer à chaque
session R suivante lorsque vous en avez besoin.
-
Le package
dplyr
fournit des outils puissants pour les tâches de manipulation de données. Il est conçu pour fonctionner directement avec des trames de données, avec de nombreuses tâches de manipulation optimisées. -
Comme nous le verrons plus loin, nous souhaitons parfois qu'un bloc de données soit remodelé pour pouvoir effectuer des analyses spécifiques ou pour la visualisation. Le package
tidyr
résout ce problème courant de remodelage des données et fournit des outils pour manipuler les données de manière ordonnée.
Pour en savoir plus sur dplyr
et tidyr
après l'atelier,
vous voudrez peut-être consulter ceci transformation de données pratique avec
**
et ceci celui sur
.
- Le package
tidyverse
est un "package parapluie" qui installe plusieurs packages utiles pour l'analyse des données qui fonctionnent bien ensemble, tels quetidyr
, * *dplyr
**,ggplot2
,tibble
, etc. Ces packages nous aident à travailler et à interagir avec les données. Ils nous permettent de faire beaucoup de choses avec vos données, comme le sous-ensemble, la transformation, la visualisation, etc.
Si vous avez effectué la configuration, vous devriez déjà avoir installé le package Tidyverse. Vérifiez si vous l'avez en essayant de le charger depuis la bibliothèque :
## load the tidyverse packages, incl. dplyr
library("tidyverse")
Si vous recevez un message d'erreur il n'y a pas de package appelé 'tidyverse'
alors vous n'avez pas
installé le package pour cette version de R. Pour installer le package tidyverse
, tapez :
BiocManager::install("tidyverse")
Si vous avez dû installer le package tidyverse
, n'oubliez pas de le charger dans cette session R en utilisant la commande library()
ci-dessus !
Instead of read.csv()
, we will read in our data using the read_csv()
function (notice the _
instead of the .
), from the tidyverse package
readr
.
rna <- read_csv("data/rnaseq.csv")
## view the data
rna
Notez que la classe des données est désormais appelée « tibble ».
Tibbles modifie certains des comportements des objets de trame de données que nous avons introduits dans le précédemment. La structure des données est très similaire à une trame de données. Pour nos besoins , les seules différences sont les suivantes :
-
Il affiche le type de données de chaque colonne sous son nom. Notez que <
dbl
> est un type de données défini pour contenir des valeurs numériques avec points décimaux. -
Il imprime uniquement les premières lignes de données et seulement autant de colonnes que peuvent contenir un écran.
Nous allons maintenant apprendre certaines des fonctions dplyr
les plus courantes :
select()
: sous-ensemble de colonnesfilter()
: sous-ensemble de lignes sur conditionsmutate()
: crée de nouvelles colonnes en utilisant les informations d'autres colonnesgroup_by()
etsummarise()
: créent des statistiques récapitulatives sur des données groupéesarrange()
: trier les résultatscount()
: compte les valeurs discrètes
Pour sélectionner les colonnes d'un bloc de données, utilisez select()
. Le premier argument
de cette fonction est la trame de données (rna
), et les arguments
suivants sont les colonnes à conserver.
select(rna, gene, sample, tissue, expression)
Pour sélectionner toutes les colonnes sauf certaines, mettez un "-" devant la variable pour l'exclure.
select(rna, -tissue, -organism)
Cela sélectionnera toutes les variables de rna
sauf tissu
et organism
.
Pour choisir des lignes en fonction d'un critère spécifique, utilisez filter()
:
filter(rna, sex == "Male")
filter(rna, sex == "Male" & infection == "NonInfected")
Imaginons maintenant que nous nous intéressions aux homologues humains des gènes
de souris analysés dans cet ensemble de données. Ces informations se trouvent dans la
dernière colonne du tibble rna
, nommée
hsapiens_homolog_associated_gene_name
. Pour le visualiser facilement, nous
allons créer un nouveau tableau contenant uniquement les 2 colonnes gene
et
hsapiens_homolog_associated_gene_name
.
genes <- select(rna, gene, hsapiens_homolog_associated_gene_name)
genes
Certains gènes de souris n'ont pas d'homologues humains. Ceux-ci peuvent être récupérés en utilisant
filter()
et la fonction is.na()
, qui détermine si
quelque chose est un NA
.
filter(genes, is.na(hsapiens_homolog_associated_gene_name))
Si on veut conserver uniquement les gènes de souris qui ont un homologue humain, on peut
insérer un "!" symbole qui annule le résultat, nous demandons donc
chaque ligne où hsapiens_homolog_associated_gene_name n'est pas un
NA
.
filter(genes, !is.na(hsapiens_homolog_associated_gene_name))
Et si vous souhaitez sélectionner et filtrer en même temps ? Il existe trois façons de procéder : utiliser des étapes intermédiaires, des fonctions imbriquées ou des tuyaux.
Avec des étapes intermédiaires, vous créez un bloc de données temporaire et l'utilisez comme entrée de la fonction suivante, comme ceci :
rna2 <- filter(rna, sex == "Male")
rna3 <- select(rna2, gene, sample, tissue, expression)
rna3
Ceci est lisible, mais peut encombrer votre espace de travail avec de nombreux objets intermédiaires que vous devez nommer individuellement. Avec plusieurs étapes , cela peut être difficile à suivre.
Vous pouvez également imbriquer des fonctions (c'est-à-dire une fonction dans une autre), comme ceci :
rna3 <- select(filter(rna, sex == "Male"), gene, sample, tissue, expression)
rna3
C'est pratique, mais peut être difficile à lire si trop de fonctions sont imbriquées, car R évalue l'expression de l'intérieur vers l'extérieur (dans ce cas, filtrer, puis sélectionner).
La dernière option, pipes, est un ajout récent à R. Pipes vous permet de prendre la sortie d'une fonction et de l'envoyer directement à la suivante, ce qui est utile lorsque vous devez faire beaucoup de choses dans le même ensemble de données.
Les tuyaux dans R ressemblent à %>%
(mis à disposition via le package magrittr
) ou |>
(via la base R). If you use RStudio, you can type
the pipe with Ctrl + Shift + M if you
have a PC or Cmd + Shift + M if you
have a Mac.
Dans le code ci-dessus, nous utilisons le tube pour envoyer l'ensemble de données rna
d'abord
via filter()
pour conserver les lignes où sex
est Homme, puis via
select()
pour conserver uniquement les colonnes gène
, échantillon
, tissu
et
expression
.
Le tube %>%
prend l'objet à sa gauche et le passe directement comme
le premier argument de la fonction à sa droite, nous n'avons pas besoin de
inclure explicitement le bloc de données comme un argument pour les fonctions filter()
et
select()
.
rna %>%
filter(sex == "Male") %>%
select(gene, sample, tissue, expression)
Certains trouveront peut-être utile de lire le tube comme le mot « alors ». Par exemple,
dans l'exemple ci-dessus, nous avons pris la trame de données rna
, puis nous avons filtré
pour les lignes avec sex == "Male"
, puis nous avons « sélectionné les colonnes « gène », « échantillon »,
« tissu » et « expression ».
Les fonctions dplyr
en elles-mêmes sont quelque peu simples, mais en
les combinant dans des flux de travail linéaires avec le tube, nous pouvons accomplir
des manipulations plus complexes de trames de données.
Si nous voulons créer un nouvel objet avec cette version plus petite des données, nous pouvons lui attribuer un nouveau nom :
rna3 <- rna %>%
filter(sex == "Male") %>%
select(gene, sample, tissue, expression)
rna3
::::::::::::::::::::::::::::::::::::::: challenge
À l'aide de tuyaux, sous-ensemblez les données rna
pour conserver les observations chez les souris femelles au temps 0,
où le gène a une expression supérieure à 50 000, et ne conservez que les colonnes
gene
, sample
, time
, expression
et age
.
::::::::::::::: solution
rna %>%
filter(expression > 50000,
sex == "Female",
time == 0 ) %>%
select(gene, sample, time, expression, age)
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::
Vous souhaiterez fréquemment créer de nouvelles colonnes basées sur les valeurs des colonnes
existantes, par exemple pour effectuer des conversions d'unités ou pour trouver le rapport des valeurs dans deux colonnes
. Pour cela, nous utiliserons mutate()
.
Pour créer une nouvelle colonne de temps en heures :
rna %>%
mutate(time_hours = time * 24) %>%
select(time, time_hours)
Vous pouvez également créer une deuxième nouvelle colonne basée sur la première nouvelle colonne dans le même appel de mutate()
:
rna %>%
mutate(time_hours = time * 24,
time_mn = time_hours * 60) %>%
select(time, time_hours, time_mn)
::::::::::::::::::::::::::::::::::::::: challenge
Créez un nouveau bloc de données à partir des données rna
qui répond aux critères
suivants : contient uniquement le gène
, le nom_chromosome
,
phenotype_description
, sample
et expression
Colonnes. Les valeurs de l'expression
doivent être transformées en log. Cette trame de données doit
contenir uniquement des gènes situés sur les chromosomes sexuels, associés à un phénotype
_description, et avec une expression log supérieure à 5.
Astuce : réfléchissez à la façon dont les commandes doivent être ordonnées pour produire ce bloc de données !
::::::::::::::: solution
rna %>%
mutate(expression = log(expression)) %>%
select(gene, chromosome_name, phenotype_description, sample, expression) %>%
filter(chromosome_name == "X" | chromosome_name == "Y") %>%
filter(!is.na(phenotype_description)) %>%
filter(expression > 5)
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::
De nombreuses tâches d'analyse de données peuvent être abordées à l'aide du paradigme
split-apply-combine : divisez les données en groupes, appliquez une analyse
à chaque groupe, puis combinez les résultats. dplyr
rend cela très facile grâce à l'utilisation de la fonction group_by()
.
rna %>%
group_by(gene)
La fonction group_by()
n'effectue aucun traitement de données, elle
regroupe les données en sous-ensembles : dans l'exemple ci-dessus, notre
tibble
initial de r nrow(rna)
les observations sont divisées en
r length(unique(rna$gene))
en fonction de la variable gene
.
On pourrait de même décider de regrouper les tibbles par échantillons :
rna %>%
group_by(sample)
Ici, notre tibble
initial d'observations r nrow(rna)
est divisé en groupes
r length(unique(rna$sample))
en fonction de la variable sample
.
Une fois les données regroupées, les opérations suivantes seront appliquées sur chaque groupe indépendamment.
group_by()
est souvent utilisé avec summarise()
, qui
réduit chaque groupe en un résumé sur une seule ligne de ce groupe.
group_by()
prend comme arguments les noms de colonnes qui contiennent les variables
catégorielles pour lesquelles vous souhaitez calculer les statistiques récapitulatives
. Donc, pour calculer l'expression moyenne par gène :
rna %>%
group_by(gene) %>%
summarise(mean_expression = mean(expression))
Nous pourrions également vouloir calculer les niveaux d’expression moyens de tous les gènes dans chaque échantillon :
rna %>%
group_by(sample) %>%
summarise(mean_expression = mean(expression))
Mais on peut aussi regrouper par plusieurs colonnes :
rna %>%
group_by(gene, infection, time) %>%
summarise(mean_expression = mean(expression))
Une fois les données regroupées, vous pouvez également résumer plusieurs variables en même temps (et pas nécessairement sur la même variable). Par exemple, nous pourrions ajouter une colonne indiquant l'expression médiane par gène et par condition :
rna %>%
group_by(gene, infection, time) %>%
summarise(mean_expression = mean(expression),
median_expression = median(expression))
::::::::::::::::::::::::::::::::::::::: challenge
Calculer le niveau d’expression moyen du gène « Dok3 » par points temporels.
::::::::::::::: solution
rna %>%
filter(gene == "Dok3") %>%
group_by(time) %>%
summarise(mean = mean(expression))
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::
Lorsque nous travaillons avec des données, nous souhaitons souvent connaître le nombre d'observations trouvées
pour chaque facteur ou combinaison de facteurs. Pour cette tâche, dplyr
fournit
count()
. Par exemple, si nous voulions compter le nombre de lignes de données pour
chaque échantillon infecté et non infecté, nous ferions :
rna %>%
count(infection)
La fonction count()
est un raccourci pour quelque chose que nous avons déjà vu : regrouper par une variable et le résumer en comptant le nombre d'observations dans ce groupe. En d'autres termes, « rna %>% count(infection) » équivaut à :
rna %>%
group_by(infection) %>%
summarise(n = n())
L'exemple précédent montre l'utilisation de count()
pour compter le nombre de lignes/observations
pour un facteur (c'est-à-dire infection
).
Si nous voulions compter une combinaison de facteurs, telle que infection
et time
,
nous spécifierions le premier et le deuxième facteur comme arguments de count()
:
rna %>%
count(infection, time)
ce qui équivaut à ceci :
rna %>%
group_by(infection, time) %>%
summarise(n = n())
Il est parfois utile de trier le résultat pour faciliter les comparaisons.
Nous pouvons utiliser arrange()
pour trier le tableau.
Par exemple, nous pourrions vouloir organiser le tableau ci-dessus par heure :
rna %>%
count(infection, time) %>%
arrange(time)
ou par comptages :
rna %>%
count(infection, time) %>%
arrange(n)
Pour trier par ordre décroissant, nous devons ajouter la fonction desc()
:
rna %>%
count(infection, time) %>%
arrange(desc(n))
::::::::::::::::::::::::::::::::::::::: challenge
- Combien de gènes ont été analysés dans chaque échantillon ?
- Utilisez
group_by()
etsummarise()
pour évaluer la profondeur de séquençage (la somme de tous les comptes) dans chaque échantillon. Quel échantillon a la profondeur de séquençage la plus élevée ? - Choisissez un échantillon et évaluez le nombre de gènes par biotype.
- Identifiez les gènes associés à la description du phénotype « méthylation anormale de l’ADN » et calculez leur expression moyenne (en log) au temps 0, au temps 4 et au temps 8.
::::::::::::::: solution
## 1.
rna %>%
count(sample)
## 2.
rna %>%
group_by(sample) %>%
summarise(seq_depth = sum(expression)) %>%
arrange(desc(seq_depth))
## 3.
rna %>%
filter(sample == "GSM2545336") %>%
count(gene_biotype) %>%
arrange(desc(n))
## 4.
rna %>%
filter(phenotype_description == "abnormal DNA methylation") %>%
group_by(gene, time) %>%
summarise(mean_expression = mean(log(expression))) %>%
arrange()
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::
Dans le tibble rna
, les lignes contiennent des valeurs d'expression (l'unité) qui sont
associées à une combinaison de 2 autres variables : gene
et sample
.
Toutes les autres colonnes correspondent à des variables décrivant soit l'échantillon (organisme, âge, sexe, ...) soit le gène (gène_biotype, ENTREZ_ID, produit, ...). Les variables qui ne changent pas avec les gènes ou avec les échantillons auront la même valeur dans toutes les lignes.
rna %>%
arrange(gene)
Cette structure est appelée « format long », car une colonne contient toutes les valeurs, et d'autres colonnes répertorient le contexte de la valeur.
Dans certains cas, le « format long » n'est pas vraiment « lisible par l'homme », et un autre format, un « format large » est préféré, comme manière plus compacte de représenter les données. This is typically the case with gene expression values that scientists are used to look as matrices, were rows represent genes and columns represent samples.
Dans ce format, il deviendrait donc simple d'explorer la relation entre les niveaux d'expression génique au sein et entre les échantillons.
rna %>%
select(gene, sample, expression) %>%
pivot_wider(names_from = sample,
values_from = expression)
Pour convertir les valeurs d'expression génique de rna
en un format large,
nous devons créer une nouvelle table où les valeurs de la colonne sample
deviendraient
les noms des variables de colonne.
The key point here is that we are still following a tidy data structure, but we have reshaped the data according to the observations of interest: expression levels per gene instead of recording them per gene and per sample.
La transformation inverse serait de transformer les noms de colonnes en valeurs d'une nouvelle variable.
Nous pouvons effectuer ces deux transformations avec deux fonctions tidyr
,
pivot_longer()
et pivot_wider()
(voir
[ici](https://tidyr.tidyverse.org /dev/articles/pivot.html) pour
détails).
Sélectionnons les 3 premières colonnes de rna
et utilisons pivot_wider()
pour transformer les données en grand format.
rna_exp <- rna %>%
select(gene, sample, expression)
rna_exp
pivot_wider
prend trois arguments principaux :
- les données à transformer ;
- le
names_from
: la colonne dont les valeurs deviendront de nouveaux noms de colonne ; - les
values_from
: la colonne dont les valeurs rempliront les nouvelles colonnes .
```{r, fig.cap="Grand pivot des données rna
.", echo=FALSE, message=FALSE}
knitr::include_graphics("fig/pivot_wider.png")
```{r, purl=TRUE}
rna_wide <- rna_exp %>%
pivot_wider(names_from = sample,
values_from = expression)
rna_wide
Notez que par défaut, la fonction pivot_wider()
ajoutera NA
pour les valeurs manquantes.
Imaginons que, pour une raison quelconque, nous ayons des valeurs d'expression manquantes pour certains gènes dans certains échantillons. In the following fictive example, the gene Cyp2d22 has only one expression value, in GSM2545338 sample.
rna_with_missing_values <- rna %>%
select(gene, sample, expression) %>%
filter(gene %in% c("Asl", "Apod", "Cyp2d22")) %>%
filter(sample %in% c("GSM2545336", "GSM2545337", "GSM2545338")) %>%
arrange(sample) %>%
filter(!(gene == "Cyp2d22" & sample != "GSM2545338"))
rna_with_missing_values
Par défaut, la fonction pivot_wider()
ajoutera NA
pour les valeurs
manquantes. Ceci peut être paramétré avec l'argument values_fill
de
la fonction pivot_wider()
.
rna_with_missing_values %>%
pivot_wider(names_from = échantillon,
values_from = expression)
rna_with_missing_values %>%
pivot_wider(names_from = échantillon,
values_from = expression,
valeurs_fill = 0)
Dans la situation inverse, nous utilisons les noms de colonnes et les transformons en une paire de nouvelles variables. Une variable représente les noms de colonnes sous forme de valeurs , et l'autre variable contient les valeurs précédemment associées aux noms de colonnes.
pivot_longer()
prend quatre arguments principaux :
- les données à transformer ;
- le
names_to
: le nouveau nom de colonne que nous souhaitons créer et remplir avec les noms de colonnes actuels ; - les
values_to
: le nouveau nom de colonne que nous souhaitons créer et remplir avec valeurs actuelles ; - les noms des colonnes à utiliser pour renseigner les variables
names_to
etvalues_to
(ou à supprimer).
```{r, fig.cap="Pivot long des données rna
.", echo=FALSE, message=FALSE}
knitr::include_graphics("fig/pivot_longer.png")
To recreate `rna_long` from `rna_wide` we would create a key
called `sample` and value called `expression` and use all columns
except `gene` for the key variable. Here we drop `gene` column
with a minus sign.
Notice how the new variable names are to be quoted here.
```{r}
rna_long <- rna_wide %>%
pivot_longer(names_to = "sample",
values_to = "expression",
-gene)
rna_long
Nous aurions également pu utiliser une spécification indiquant les colonnes à
inclure. Cela peut être utile si vous disposez d'un grand nombre de colonnes d'identification
, et il est plus facile de spécifier ce qu'il faut rassembler que ce qu'il faut laisser
seul. Ici, la fonction starts_with()
peut aider à récupérer des exemples de noms
sans avoir à tous les lister !
Une autre possibilité serait d'utiliser l'opérateur :
!
rna_wide %>%
pivot_longer(names_to = "sample",
values_to = "expression",
cols = start_with("GSM"))
rna_wide %> %
pivot_longer(names_to = "échantillon",
valeurs_to = "expression",
GSM2545336:GSM2545380)
Notez que si nous avions des valeurs manquantes dans le format large, le « NA » serait inclus dans le nouveau format long.
Souvenez-vous de notre précédent tibble fictif contenant des valeurs manquantes :
rna_with_missing_values
wide_with_NA <- rna_with_missing_values %>%
pivot_wider(names_from = sample,
values_from = expression)
wide_with_NA
wide_with_NA %>%
pivot_longer(names_to = "sample",
values_to = "expression",
-gene)
Passer à des formats plus larges et plus longs peut être un moyen utile d'équilibrer un ensemble de données afin que chaque réplique ait la même composition.
::::::::::::::::::::::::::::::::::::::: challenge
A partir de la table arn, utilisez la fonction pivot_wider()
pour créer
un tableau grand format donnant les niveaux d'expression génique chez chaque souris.
Utilisez ensuite la fonction pivot_longer()
pour restaurer un tableau au format long.
::::::::::::::: solution
rna1 <- rna %>%
select(gène, souris, expression) %>%
pivot_wider(names_from = souris, valeurs_from = expression)
rna1
rna1 %>%
pivot_longer(names_to = "mouse_id", valeurs_to = "counts", -gene)
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::: challenge
Sous-ensemble de gènes situés sur les chromosomes X et Y de la trame de données « rna » et répartissent la trame de données avec « sexe » en colonnes, « nom_chromosome » en lignes et l'expression moyenne des gènes localisés dans chaque chromosome comme valeurs, comme dans le tableau suivant :
knitr::include_graphics("fig/Exercise_pivot_W.png")
Il faudra résumer avant de remodeler !
::::::::::::::: solution
Calculons d'abord le niveau d'expression moyen des gènes liés X et Y à partir de échantillons mâles et femelles...
arn %>%
filter(chromosome_name == "Y" | chromosome_name == "X") %>%
group_by(sex, chromosome_name) %>%
résumé(moyenne = moyenne(expression))
Et faites pivoter le tableau au format large
rna_1 <- rna %>%
filter(chromosome_name == "Y" | chromosome_name == "X") %>%
group_by(sex, chromosome_name) %>%
summarise(mean = moyenne(expression)) %>%
pivot_wider(names_from = sexe,
valeurs_from = moyenne)
rna_1
Maintenant, prenez cette trame de données et transformez-la avec pivot_longer()
afin que
chaque ligne soit une combinaison unique de chromosome_name
par gender
.
rna_1 %>%
pivot_longer(names_to = "gender",
valeurs_to = "mean",
-chromosome_name)
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::: challenge
Utilisez l'ensemble de données rna
pour créer une matrice d'expression où chaque ligne
représente les niveaux d'expression moyens des gènes et les colonnes représentent
les différents moments.
::::::::::::::: solution
Calculons d'abord l'expression moyenne par gène et par temps
arn %>%
group_by(gène, temps) %>%
résumé(mean_exp = moyenne(expression))
avant d'utiliser la fonction pivot_wider()
rna_time <- rna %>%
group_by(gene, time) %>%
summarise(mean_exp = mean(expression)) %>%
pivot_wider(names_from = time,
values_from = mean_exp)
rna_time
Notez que cela génère un tibble avec certains noms de colonnes commençant par un nombre. Si nous voulions sélectionner la colonne correspondant aux points temporels, nous ne pourrions pas utiliser directement les noms de colonnes... Que se passe-t-il lorsque l'on sélectionne la colonne 4 ?
rna %>%
group_by(gene, time) %>%
summarise(mean_exp = mean(expression)) %>%
pivot_wider(names_from = time,
values_from = mean_exp) %>%
select(gene, 4)
Pour sélectionner le timepoint 4, il faudrait citer le nom de la colonne, avec des backticks "\`"
rna %>%
group_by(gene, time) %>%
summarise(mean_exp = mean(expression)) %>%
pivot_wider(names_from = time,
values_from = mean_exp) %>%
select(gene, `4`)
Une autre possibilité serait de renommer la colonne, en choisissant un nom qui ne commence pas par un chiffre :
rna %>%
group_by(gene, time) %>%
summarise(mean_exp = mean(expression)) %>%
pivot_wider(names_from = time,
values_from = mean_exp) %>%
rename("time0" = `0`, "time4" = `4`, "time8" = `8`) %>%
select(gene, time4)
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::: challenge
Utilisez la trame de données précédente contenant les niveaux d'expression moyens par point temporel et créez une nouvelle colonne contenant les changements de pli entre le point temporel 8 et le point temporel 0, et les changements de pli entre le point temporel 8 et le point temporel 4. Convertissez ce tableau en un tableau au format long regroupant les changements de pli calculés.
::::::::::::::: solution
À partir du tibble rna_time :
arn_time
Calculer les changements de plis :
rna_time %>%
muter (time_8_vs_0 = `8` / `0`, time_8_vs_4 = `8` / `4`)
Et utilisez la fonction pivot_longer() :
rna_time %>%
mutate(time_8_vs_0 = `8` / `0`, time_8_vs_4 = `8` / `4`) %>%
pivot_longer(names_to = "comparisons",
values_to = "Fold_changes",
time_8_vs_0:time_8_vs_4)
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::
Dans de nombreuses situations réelles, les données sont réparties sur plusieurs tables. Cela se produit généralement parce que différents types d’informations sont collectés à partir de différentes sources.
Il peut être souhaitable que certaines analyses combinent les données de deux ou plusieurs tables en une seule trame de données basée sur une colonne qui serait commune à toutes les tables.
Le package dplyr
fournit un ensemble de fonctions de jointure pour combiner deux trames de données
basées sur des correspondances dans des colonnes spécifiées. Ici, nous
fournissons une brève introduction aux jointures. Pour en savoir plus, veuillez
vous référer au chapitre sur les jointures de table
. La
Data Transformation Cheat
Sheet
fournit également un bref aperçu sur les jointures de table.
Nous allons illustrer la jointure en utilisant une petite table, rna_mini
que
nous allons créer en sous-définissant la table rna
d'origine, en ne gardant que 3
colonnes et 10 lignes.
rna_mini <- rna %>%
select(gène, échantillon, expression) %>%
head(10)
rna_mini
Le deuxième tableau, annot1
, contient 2 colonnes, gene et
gene_description. Vous pouvez soit
télécharger annot1.csv
en cliquant sur le lien puis en vous déplaçant dans le dossier data/
, ou
vous pouvez utiliser le code R ci-dessous pour le télécharger directement dans le dossier.
download.file(url = "https://carpentries-incubator.github.io/bioc-intro/data/annot1.csv",
destfile = "data/annot1.csv")
annot1 <- read_csv(file = "data/annot1.csv")
annot1
Nous voulons maintenant joindre ces deux tables en une seule contenant toutes les
variables en utilisant la fonction full_join()
du package dplyr
. La fonction
trouvera automatiquement la variable commune correspondant aux colonnes
de la première et de la deuxième table. Dans ce cas, « gène » est la variable commune
. Ces variables sont appelées clés. Les clés sont utilisées pour faire correspondre
observations dans différentes tables.
full_join(rna_mini, annot1)
Dans la vraie vie, les annotations génétiques sont parfois étiquetées différemment.
La table annot2
est exactement la même que annot1
sauf que la variable
contenant les noms de gènes est étiquetée différemment. Encore une fois, soit
télécharger annot2.csv
vous-même et déplacez-le vers data/
ou utilisez le code R ci-dessous.
download.file(url = "https://carpentries-incubator.github.io/bioc-intro/data/annot2.csv",
destfile = "data/annot2.csv")
annot2 <- read_csv(file = "data/annot2.csv")
annot2
Si aucun des noms de variables ne correspond, nous pouvons définir manuellement les variables
à utiliser pour la correspondance. Ces variables peuvent être définies en utilisant
l'argument by
, comme indiqué ci-dessous avec les tables rna_mini
et annot2
.
full_join(rna_mini, annot2, by = c("gene" = "external_gene_name"))
Comme on peut le voir ci-dessus, le nom de variable de la première table est conservé dans celle jointe.
::::::::::::::::::::::::::::::::::::::: challenge
Téléchargez la table annot3
en cliquant sur
ici
et placez la table dans votre Dépôt de données. À l'aide de la fonction full_join()
, joignez les tables rna_mini
et annot3
. Que s'est-il passé pour les gènes
Klk6, mt-Tf, mt-Rnr1, mt-Tv, mt-Rnr2 et mt-Tl1 ?
::::::::::::::: solution
annot3 <- read_csv("data/annot3.csv")
full_join(rna_mini, annot3)
Les gènes Klk6 ne sont présents que dans rna_mini
, tandis que les gènes mt-Tf, mt-Rnr1, mt-Tv,
mt-Rnr2 et mt-Tl1 sont présent uniquement dans la table annot3
. Leurs valeurs respectives pour les variables
du tableau ont été codées comme manquantes.
:::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::
Maintenant que vous avez appris à utiliser dplyr
pour extraire des informations de
ou résumer vos données brutes, vous souhaiterez peut-être exporter ces nouveaux ensembles de données pour les partager
avec vos collaborateurs ou pour les archiver.
Semblable à la fonction read_csv()
utilisée pour lire les fichiers CSV dans R, il existe
une fonction write_csv()
qui génère des fichiers CSV à partir de trames de données.
Avant d'utiliser write_csv()
, nous allons créer un nouveau dossier, data_output
,
dans notre répertoire de travail qui stockera cet ensemble de données généré. Nous ne voulons pas que
écrive les ensembles de données générés dans le même répertoire que nos données brutes.
C'est une bonne pratique de les garder séparés. Le dossier data
ne doit contenir que
les données brutes et non modifiées, et doit être laissé seul pour nous assurer que nous ne supprimons pas
ou ne le modifions pas. En revanche, notre script générera le contenu du répertoire data_output
, donc même si les fichiers qu'il contient sont supprimés, nous pouvons toujours
les régénérer.
Utilisons write_csv()
pour sauvegarder la table rna_wide que nous avons créée précédemment.
write_csv(rna_wide, file = "data_output/rna_wide.csv")
:::::::::::::::::::::::::::::::::::::::: keypoints
- Données tabulaires dans R utilisant le méta-paquet Tidyverse
::::::::::::::::::::::::::::::::::::::::::::::::::