Dans cette partie du cours vous allez apprendre des restructurations plus complexes des tables dans R. Ces changement sont parfois nécessaire pour mettre les données dans le format adapté au graphique que vous voulez réaliser.
Aujourd’hui nous allons voir comment:
Concaténer ou séparer des colonnes
Passer d’un format large à un format long
Combiner 2 tableaux en un seul
Tout d’abord, créez un nouveau script R et préparez votre environnement de travail:
# Chargez la librairie `tidyverse`
# Changez votre répertoire de travail pour être dans `session4_reorganisation_suite`
# Importer `burghardt_et_al_2015_expt1.txt` et mettez le dans un objet appelé `expt1`
unite()
et
separate()
Pour concaténer deux ou plusieurs colonnes ensemble, utilisez la
fonction unite()
. Par exemple, pour concaténer
vernalization
, survival.bolt
et
bolt
:
# Créez deux nouvelles colonnes
expt1.concatenated <- unite(expt1, "Vern_survival_bolt",vernalization,bolt.survival,bolt)
# Vérifier que la nouvelles colonnes sont bien là
colnames(expt1.concatenated)
## [1] "plant_nb" "genotype" "background"
## [4] "temperature" "fluctuation" "day.length"
## [7] "Vern_survival_bolt" "days.to.bolt" "days.to.flower"
## [10] "rosette.leaf.num" "cauline.leaf.num" "blade.length.mm"
## [13] "total.leaf.length.mm"
A contrario, pour séparer une colonne en deux ou plusieurs colonnes,
utilisez la fonction separate()
. Par exemple, pour séparer
la colonne barkground
:
# Créez deux nouvelles colonnes
expt1.separated <- separate(expt1, background, into=c("genotype_background", "FRI_mutation"))
# Vérifier que la nouvelles colonnes sont bien là
colnames(expt1.separated)
## [1] "plant_nb" "genotype" "genotype_background"
## [4] "FRI_mutation" "temperature" "fluctuation"
## [7] "day.length" "vernalization" "bolt.survival"
## [10] "bolt" "days.to.bolt" "days.to.flower"
## [13] "rosette.leaf.num" "cauline.leaf.num" "blade.length.mm"
## [16] "total.leaf.length.mm"
Exercice 1:
Reproduisez cette figure de Burghard et al 2015
Aide:
Créez une nouvelle colonne (blade.ratio) avec le ratio de
blade.length.mm
ettotal.leaf.length.mm
Créez une nouvelle colonne (nommée par exemple
condition
) en concaténantday.length
,temperature
etfluctuation
Sélectionnez les background
Col
etLer
Faites un boxplot du ratio de
blade.length.mm
ettotal.leaf.length.mm
en fonction de lacondition
, en créant des facets en fonction du backgroundPas besoin de mettre de la couleur qui n’apporte rien au graphique
N’essayez pas de reproduire l’ordre des conditions (sur l’axe x). Nous verrons comment le faire à la prochaine séance
BONUS: Ce bonus vous permettra d’avoir des valeurs de x plus proches du graphique
- Avant de créer la nouvelle colonne en concaténant
day.length
,temperature
etfluctuation
, créer une colonneLD.SD
dans laquelle vous aurez “LD” à la place de la valeur “16” de la colonneday.length
, et “SD” à la place de la valeur “8” de la colonneday.length
. Utilisez ensuite cette colonneLD.SD
pour la concaténation avectemperature
etfluctuation
pour créer la colonnecondition
- Changez le thème du graphique pour enlever la grille et avoir un fond blanc.
pivot_longer()
et
pivot_wider()
pivot_longer()
Imaginons que nous souhaitons faire un boxplot pour le
days.to.bolt
et le days.to.flower
.
Pour faire ce boxplot il nous faut réorganiser le tableau pour avoir
les données pour ces deux mesures dans la même colonnes
(trait
) et une colonne indiquant s’il s’agit de la mesure
de days.to.bolt
ou days.to.flower
(time.in.days
).
Pour cela nous utilisons la fonction pivot_longer()
qui
permet de passer d’un format “wide” (large) à un format “long”.
Dans ce cas, le nom des colonnes sélectionnées servent à remplir les catégories dans la première colonne crée (en violet dans l’illustration). Et les valeurs de toutes ces colonnes sélectionnées vont remplir la deuxième colonne crée (en bleu dans l’illustration).
pivot_longer()
à besoin de trois informations:
le nom de la nouvelle colonne contenant les catégories prises à
parttir du nom des vieilles colonnes (dans notre cas trait
)
: names_to
le nom de la nouvelle colonne contenant les valeurs des anciennes
colonnes (dans notre cas time.in.days
) :
values_to
le nom des anciennes colonnes que l’ont veut rassembler : cols
Voici comment restructurer notre tableau avec
pivot_longer()
:
expt1_long <- pivot_longer(expt1, names_to = "trait", values_to = "time.in.days", cols=c(days.to.bolt, days.to.flower))
Nous pouvons maintenant faire notre boxplot
ggplot(expt1_long, aes(x=trait, y=time.in.days, color=genotype)) +
geom_boxplot()
## Warning: Removed 83 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
Afin d’exporter ce graphique et de le sauver, nous utilisons la
fonction ggsave()
:
ggplot(expt1_long, aes(x=trait, y=time.in.days, color=genotype)) +
geom_boxplot()
## Warning: Removed 83 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
ggsave("boxplot_daystobolt_daystoflower_genotypes.pdf")
## Saving 7 x 5 in image
## Warning: Removed 83 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
Exercice 2:
- Utilisez la fonction
pivot_longer()
pour restructurer le tableau afin de faire un boxplot deblade.length.mm
ettotal.leaf.length.mm
, coloré parfluctuation
.
- Ajoutez aux boxplots des encoches indiquant l’étendue de l’intervalle de confiance à 95% de la médiane (voir l’option
notch
dansgeom_boxplot
). Si les encoches sont étroite, il y a peu d’incertitude sur la médiane, si les encoches sont large, il y a une forte incertitude sur la médiane. Si les encoches de boxplots que nous comparons se chevauchent, alors nous ne pouvons pas conclure à une différence de médiane entre les médiane des deux groupes.
- Interprétez le graphique: Y a t’il un effet de la fluctuation de température sur la longueur de blade ou de la feuille? Pourquoi?
BONUS Optimisez le graphique obtenu en jouant sur le thème, les couleurs utilisée (visibles par des daltoniens), le titre et la valeur des axes et de la légende, de manière à avoir un graphique similaire au graphique suivant:
pivot_wider()
ATTENTION,
CETTE PARTIE NE SERA PAS VUE EN COURS FAUTE DE TEMPS MAIS VOUS ETES TRES
FORTEMENT RECOMMANDE DE LA TRAVAILLER PAR VOUS MEME!!Parfois, le format de vos données ne vous permet pas de faire l’analyse ou le graphique que vous voulez.
Par exemple, essayons de reproduire le graphique suivant extrait de Burghard et al 2015
Pour faire cette figure il nous faut une colonne avec le temps de
floraison pour les plantes en conditions constante et une autre colonne
avec le temps de floraison pour les plantes en condition variable. Le
temps de floraison pour toutes les plantes sont dans la même colonne
dans notre tableau. Par contre, l’information sur le type de traitement
(variable ou constant) est dans une autre colonne. Ce n’est pas ce que
nous voulons! Heureusement, nous pouvons utiliser la fonction
pivot_wider()
pour reformater notre tableau.
Pour y voir plus clair, ne gardons que les colonnes qui vont nous être utiles à la création du tableau:
expt1_subset <- select(expt1, plant_nb:vernalization, days.to.bolt)
Maintenant nous devons changer la structure de la table pour avoir une colonne avec le temps de floraison pour les plantes en conditions constante et une autre colonne avec le temps de floraison pour les plantes en condition variable. Un peu comme dans le schéma ci-dessous (pour aller du format “long” au format “wide”).
La fonction spread()
a besoin de deux informations:
Le nom de la colonne qui va permettre de créer les noms de
colonnes dans la nouvelle table. Dans notre cas fluctuation
: names_from
Le nom de la colonne qui contient les valeurs qui vont remplir
les nouvelles colonnes. Dans notre cas days.to.bolt
:
values_from
Voici comment restructurer notre tableau avec
pivot_wider()
:
expt1_wide <- pivot_wider(expt1_subset, names_from =fluctuation, values_from = days.to.bolt)
Afin de pouvoir reproduire les couleurs du graphique, nous devons
concaténer les colonnes temperature
et
day.length
. Et nous pouvons enfin faire le graphique:
unite(expt1_wide, "treatment", temperature, day.length) %>%
ggplot(aes(x=Con, y=Var, col=treatment, shape=treatment)) +
geom_point()
## Warning: Removed 51 rows containing missing values or values outside the scale range
## (`geom_point()`).
Comme vous avez vu, changer la structure du tableau nous a permis de faire un graphique que nous n’aurions pas pu faire autrement. Cela peut aussi permettre de faire des analyses supplémentaires.
*_join()
)Quand nous analysons des données, il n’est pas rare que nous ayons plusieurs tableaux contenant des informations de différents types mais qui sont liées les unes aux autres. Afin de répondre à certaines questions, nous devons parfois combiner ces différents tableau en un seul, à l’aide d’une certaine colonne.
Pour cela nous pouvons utiliser une des fonction de la famille
*_join
.
Toutes ces fonctions ont besoin de trois choses: - Le nom du premier tableau (celui de gauche) - Le nom du second tableau (celui de droite) - Le nom de la colonne qui est utilisée pour combiner les tableaux ensemble (il est aussi possible d’utiliser plus d’une colonne)
Afin de comprendre comment ces fonctions marchent, nous allons utiliser deux jeux de données qui sont déjà présent dans R:
band_members
band_members
## # A tibble: 3 × 2
## name band
## <chr> <chr>
## 1 Mick Stones
## 2 John Beatles
## 3 Paul Beatles
band_instruments
band_instruments
## # A tibble: 3 × 2
## name plays
## <chr> <chr>
## 1 John guitar
## 2 Paul bass
## 3 Keith guitar
La fonction full_join()
, permet de garder toutes les
lignes et toutes les colonnes des deux tableaux dans le nouveau tableau
créé en les combinant. Dans notre cas, pour avoir toutes les information
sur le groupe de musique et l’instrument pour chaque musicien, nous
utilisons:
full_join(band_members, band_instruments, by="name")
## # A tibble: 4 × 3
## name band plays
## <chr> <chr> <chr>
## 1 Mick Stones <NA>
## 2 John Beatles guitar
## 3 Paul Beatles bass
## 4 Keith <NA> guitar
Vous pouvez voir que quand le groupe de musique ou l’instrument d’un musicien est manquante, un ‘NA’ est utilisé à la place.
Regardons les autres fonctions de la famille
*_join()
band_members
(table de gauche dans la fonction), nous
utilisons left_join()
:left_join(band_members, band_instruments, by="name")
## # A tibble: 3 × 3
## name band plays
## <chr> <chr> <chr>
## 1 Mick Stones <NA>
## 2 John Beatles guitar
## 3 Paul Beatles bass
band_instruments
(table de droite dans la fonction), nous
utilisons right_join()
:right_join(band_instruments, band_members, by="name")
## # A tibble: 3 × 3
## name plays band
## <chr> <chr> <chr>
## 1 John guitar Beatles
## 2 Paul bass Beatles
## 3 Mick <NA> Stones
inner_join()
:inner_join(band_members, band_instruments, by="name")
## # A tibble: 2 × 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
Dans ce cas il n’y a pas de ‘NA’
Ces fonctions peuvent être utiles pour comparer de gros jeux de données :
inner_join()
est l’équivalent de
l’intersection entre deux jeux de données.
full_join()
est l’équivalent de l’union de
deux jeux de données.