Dans cette partie du cours vous allez apprendre à réorganiser des tables dans R. Cela peur être utile si vous ne devez travailler que sur une partie des données.
Aujourd’hui nous allons voir:
Comment filtrer des lignes ou des colonnes dans un tableau
Exporter le nouveau tableau créé dans R
Combiner une filtration de lignes avec un graphique
Ajouter ou modifier des colonnes
Tout d’abord, créez un nouveau script R et préparez votre environnement de travail:
# Chargez la librairie `tidyverse` (aide: utilisez la fonction `library()`)
# Changez votre répertoire de travail pour être dans `session3_plots_reorganisation`
#(aide: utilisez la fonction `setwd()`)
# Importer `burghardt_et_al_2015_expt1.txt` et mettez le dans un objet appelé `expt1`
#(aide: utilisez la fonction `read_tsv()`)
select()
Tout d’abord, utilisons les fonctions dim()
et
names()
afin de connaitre les dimensions du tableau et le
nom des colonnes.
dim(expt1)
## [1] 957 15
names(expt1)
## [1] "plant_nb" "genotype" "background"
## [4] "temperature" "fluctuation" "day.length"
## [7] "vernalization" "bolt.survival" "bolt"
## [10] "days.to.bolt" "days.to.flower" "rosette.leaf.num"
## [13] "cauline.leaf.num" "blade.length.mm" "total.leaf.length.mm"
Il y a beaucoup de colonnes dans ce tableau. Afin de ne garder que
les colonnes genotype
et temperature
, nous
pouvons utiliser la fonction select()
select(expt1, genotype, temperature)
## # A tibble: 957 × 2
## genotype temperature
## <chr> <dbl>
## 1 Col Ama 12
## 2 Col Ama 12
## 3 Col Ama 12
## 4 Col Ama 12
## 5 Col Ama 12
## 6 Col Ama 12
## 7 Col Ama 12
## 8 Col Ama 12
## 9 Col Ama 12
## 10 Col Ama 12
## # ℹ 947 more rows
Il est aussi possible de ne garder que les colonnes qui contiennent le mot “bolt” dans leur nom:
select(expt1, contains("bolt"))
## # A tibble: 957 × 3
## bolt.survival bolt days.to.bolt
## <chr> <chr> <dbl>
## 1 Y Y 28
## 2 Y Y 29
## 3 Y Y 31
## 4 Y Y 31
## 5 Y Y 32
## 6 Y Y 33
## 7 Y Y 34
## 8 Y Y 35
## 9 Y Y 69
## 10 Y Y 72
## # ℹ 947 more rows
Exercice 1 : Sélectionnez les colonnes qui contiennent des données mesurées en mm
BONUS:
1. Sélectionnez les colonnes dont le titre finit par “bolt”
2. Sélectionnez les colonnes qui ne sont pasplant_nb
etgenotype
Aide: Regardez les exemples dans l’aide de R ou cherchez dans google
filter()
Avec la fonction filter()
, nous pouvons garder toutes
les lignes de notre table qui correspondent à des plantes qui ont subies
une vernalisation.
Tout d’abord, nous devons connaitre les différentes valeurs de la
colonne vernalization
. Comme nous pouvons voir, il y a deux
options: ‘NV’ et ‘V’.
distinct(expt1, vernalization)
## # A tibble: 2 × 1
## vernalization
## <chr>
## 1 NV
## 2 V
Comme nous voulons garder les plantes qui ont subies une
vernalisation, nous devons filtrer les données pour garder les lignes
pour lesquelles il y a “V” dans la colonne
vernalization
:
filter(expt1, vernalization == "V")
## # A tibble: 330 × 15
## plant_nb genotype background temperature fluctuation day.length vernalization
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr>
## 1 1 Col Ama Col 12 Con 16 V
## 2 2 Col Ama Col 12 Con 16 V
## 3 3 Col Ama Col 12 Con 16 V
## 4 4 Col Ama Col 12 Con 16 V
## 5 5 Col Ama Col 12 Con 16 V
## 6 6 Col Ama Col 12 Con 16 V
## 7 7 Col Ama Col 12 Con 16 V
## 8 8 Col Ama Col 12 Con 16 V
## 9 1 Col Ama Col 12 Con 8 V
## 10 2 Col Ama Col 12 Con 8 V
## # ℹ 320 more rows
## # ℹ 8 more variables: bolt.survival <chr>, bolt <chr>, days.to.bolt <dbl>,
## # days.to.flower <dbl>, rosette.leaf.num <dbl>, cauline.leaf.num <dbl>,
## # blade.length.mm <dbl>, total.leaf.length.mm <dbl>
Nous pouvons utiliser les opérateurs suivant pour définir les conditions pour filtrer les données:
Opérateur | Condition de sélection | Exemple |
---|---|---|
< |
inférieur à | filter(expt1, days.to.bolt < 20) |
<= |
inférieur ou égal à | filter(expt1, days.to.bolt <= 20) |
> |
supérieur à | filter(expt1, days.to.bolt > 20) |
>= |
supérieur ou égal à | filter(expt1, days.to.bolt >= 20) |
== |
égal à | filter(expt1, days.to.bolt == 20) |
!= |
différent de | filter(expt1, days.to.bolt != 20) |
%in% |
est contenu dans | filter(expt1, genotype %in% c("Col FRI", "Ler-1")) |
Il est aussi possible de combiner plusieurs conditions de sélection avec les opérateurs suivant:
Opérateur | Signification | Exemple |
---|---|---|
& |
ET | filter(expt1, days.to.bolt == 20 & genotype == "Ler-1") |
| |
OU | filter(expt1, rosette.leaf.num < 8 | rosette.leaf.num > 100) |
Nous pouvons aussi identifier les données manquantes
(NA
) avec la fonction is.na()
ou sa négation
(en utilisant !
):
Opérateur | Signification | Exemple |
---|---|---|
is.na() |
données manquante | filter(expt1, is.na(rosette.leaf.num)) |
!is.na() |
donnée non manquante | filter(expt1, !is.na(rosette.leaf.num)) |
Par exemple, nous pouvons sélectionner les plantes qui ont été vernalisées ET qui ont poussées avec une température fluctuante:
filter(expt1, vernalization == "V" & fluctuation == "Var")
Il est aussi possible de sélectionner les plantes qui ont poussées avec 8h de jours OU qui fleurissent tardivement:
filter(expt1, day.length == "8" | days.to.bolt > 85)
Exercice 2: Filtrez les données pour garder les plantes selon les 3 cas de figures suivant (indépendants les uns des autres):
- Plantes qui ne sont pas du background Ler et qui ont été traitées avec une température fluctuante.
- Plantes qui ont fleuries (bolt) en moins de 57 jours et qui ont moins de 40 feuilles de rosette
- Plantes du génotype fca-6 pour qui le blade.length.mm n’est pas manquant
BONUS:
Filtrez les données pour garder les lignes pour lesquelles le background contient Col
Sauvez le résultat dans un nouvel objet et vérifier quelles valeurs distinctes sont dans la colonne background en utilisant le fonctiondistinct()
Aide: Faites un recherche sur google pour trouver le résultat
Aujourd’hui, nous avons fortement restructuré notre tableau. Nous pouvons le sauver pour le réutiliser ultérieurement.
Pour cela nous utilisons la fonction write_tsv()
Par exemple, imaginons que nous voulons enlever des données manquantes et partager les données avec un collaborateurs (ou les réutiliser nous même plus tard):
expt1.days.to.flower.clean <- expt1 %>%
filter(!is.na(days.to.flower))
write_tsv(expt1.days.to.flower.clean, file = "../data/expt1_days_to_flower_clean.txt")
Afin de pouvoir combiner la sélection de données avec un graphique, nous devons d’abord apprendre à faire des chaines de commandes.
%>%
Les “pipes” (%>%
) permettent de faire une séquence
d’opération sur des données, sans avoir besoin de créer des objets
intermédiaires (ou de faire des commandes imbriquées très
compliquées)
Imaginons que nous voulions faire les sélections suivantes sur notre table:
Filtrer des données pour ne garder que les plantes qui ont été vernalisées
Ne garder que deux colonnes: le génotype et la taille totale des feuilles
Grace au symbole %>%
pipe, nous pouvons créer une
chaîne de commandes. Pour cela nous devons d’abord faire une commande et
ajouter %>%
à la fin de la ligne qui va utiliser le
résultat de cette commande comme input pour la fonction à la ligne
suivante. Voici comment faire:
expt1 %>%
filter(vernalization == "V") %>%
select(genotype, total.leaf.length.mm)
## # A tibble: 330 × 2
## genotype total.leaf.length.mm
## <chr> <dbl>
## 1 Col Ama 22.1
## 2 Col Ama 26.8
## 3 Col Ama 27.9
## 4 Col Ama 22.8
## 5 Col Ama 24.9
## 6 Col Ama 22.2
## 7 Col Ama 24.1
## 8 Col Ama 21.4
## 9 Col Ama 36
## 10 Col Ama 29.9
## # ℹ 320 more rows
Exercice 3: Utilisez
%>%
pour faire la suite de sélections suivantes surexpt1
:
- Gardez les plantes qui ne sont pas du background Ler, et qui ont été traitées avec la température fluctuante.
- Ne gardez que les colonnes qui contiennent le génotype, la longueur de “blade” et des information sur le “bolting”
BONUS: Transformez l’enchainement de commandes afin d’utiliser des pipes
%>%
plutôt que objets intermédiaires
expt1 <- read_tsv("../data/burghardt_et_al_2015_expt1.txt")
expt1_filtered <- filter(expt1, fluctuation=="Con" & day.length=="16")
expt1_selected <- select(expt1_filtered,days.to.bolt:total.leaf.length.mm)
summary(expt1_selected)
## days.to.bolt days.to.flower rosette.leaf.num cauline.leaf.num
## Min. : 15.00 Min. : 21.0 Min. : 6.00 Min. : 1.000
## 1st Qu.: 26.75 1st Qu.: 39.0 1st Qu.:14.00 1st Qu.: 4.000
## Median : 41.50 Median : 49.0 Median :30.00 Median : 7.000
## Mean : 45.00 Mean : 53.6 Mean :31.67 Mean : 6.827
## 3rd Qu.: 57.00 3rd Qu.: 70.0 3rd Qu.:46.00 3rd Qu.: 9.000
## Max. :152.00 Max. :135.0 Max. :91.00 Max. :13.000
## NA's :7 NA's :9 NA's :9
## blade.length.mm total.leaf.length.mm
## Min. : 8.20 Min. :10.90
## 1st Qu.:14.45 1st Qu.:22.12
## Median :19.20 Median :30.50
## Mean :18.39 Mean :29.01
## 3rd Qu.:21.57 3rd Qu.:34.52
## Max. :28.20 Max. :47.00
## NA's :78 NA's :62
Avec le pipe nous pouvons aussi utiliser l’output d’une commande (ou
d’une chaîne de commandes) comme un input pour ggplot
afin
de faire un graphique sur les données sélectionnées. Ceci est très utile
lors de la phase d’exploration des données (sans avoir à créer de
nouveaux objets avec en permanence <-
).
Nous pouvons par exemple faire un box plot pour le temps de floraison en fonction de la fluctuation de température, mais celle fois uniquement pour les plantes qui ont été vernalisées:
expt1 %>%
filter(vernalization == "V") %>%
ggplot(aes(fluctuation, days.to.flower)) +
geom_boxplot()
Exercice 4: Faite un violon plot du temps de floraison pour les différents génotypes, mais uniquement pour les plantes ayant poussées en jours court (8h de lumière).
Aide: Utilisez
filter()
pour sélectionner les données et ensuite un pipe (%>%
) pour utiliser l’output pour le graphique.
BONUS
Représentez, uniquement pour les plantes qui contiennent le mot “Col” dans le background, et qui ont poussée à 22°C, un box plot de days.to.bolt en fonction du vernalization, coloré en fonction de la fluctuation. Séparez les graphiques pour avoir une facet par génotype. Utilisez un thème de type theme_bw.
Interprétez le résultat Est-ce que le temps de floraison de certains génotypes est affecté par la fluctuation de température. Si oui lesquels?
mutate()
La fonction mutate()
permet d’ajouter de nouvelles
variables (i.e. nouvelles colonnes) dans une table, ou de modifier des
colonnes déjà existantes.
Par exemple, ajoutons une colonne leaf.length.cm
qui va
contenir la longueur des feuilles en cm. Pour cela nous devons créer une
nouvelle colonne en utilisant la colonne leaf.length.mm
qui
existe dans la table.
# Créez une nouvelle table avec la colonne supplémentare
expt1.cm <- mutate(expt1, total.leaf.length.cm = total.leaf.length.mm/10)
# Vérifier que la nouvelle colonne est bien là
colnames(expt1.cm)
## [1] "plant_nb" "genotype" "background"
## [4] "temperature" "fluctuation" "day.length"
## [7] "vernalization" "bolt.survival" "bolt"
## [10] "days.to.bolt" "days.to.flower" "rosette.leaf.num"
## [13] "cauline.leaf.num" "blade.length.mm" "total.leaf.length.mm"
## [16] "total.leaf.length.cm"
Nous pouvons aussi créer et modifier plus d’une colonne à la fois, en
les séparant par une virgule (,
) dans la fonction
mutate()
:
# Créez deux nouvelles colonnes
expt1.cm <- mutate(expt1,
blade.length.cm = blade.length.mm/10,
total.leaf.length.cm = total.leaf.length.mm/10)
# Vérifier que les nouvelles colonnes sont bien là
colnames(expt1.cm)
## [1] "plant_nb" "genotype" "background"
## [4] "temperature" "fluctuation" "day.length"
## [7] "vernalization" "bolt.survival" "bolt"
## [10] "days.to.bolt" "days.to.flower" "rosette.leaf.num"
## [13] "cauline.leaf.num" "blade.length.mm" "total.leaf.length.mm"
## [16] "blade.length.cm" "total.leaf.length.cm"
Attention!! Si vous utilisez le nom d’une colonne déjà existante, vous allez la modifier et non créer une nouvelle colonne.
Exercice 5:
Créez une nouvelle colonne “blade.ratio” avec le ratio de
blade.length.mm
ettotal.leaf.length.mm
BONUS:
Créez une nouvelle colonne “late.flowering” qui contientTRUE
si days.to.bolt est supérieur à 70, etFALSE
days.to.bolt est inférieur à 70.
Aide: Trouvez la solution en utilisant google