---
title: "Tutorial:Jointures avec dplyr & tidylog"
output:
learnr::tutorial:
progressive: true
allow_skip: true
runtime: shiny_prerendered
Description: Tuto jointures avec dplyr et tidylog
---
```{r setup, include=FALSE}
library(learnr)
knitr::opts_chunk$set(echo = FALSE)
library(tidyverse)
library(tidylog)
tutorial_options(exercise.timelimit = 60)
# Data
## Partie Concaténation
students<-c("Margot","Thibault","Kylian","Jon","Nathan","victor","Jeremy","Al")
class<-c("1A","2A","3A")
matiere<-c("Statistiques infer","Stat avec R","Anglais","SEM")
nom<-c("MARTIN","BERNARD","DURAND","DUBOIS","PETIT","LEMAIRE")
tel<-c("01","02","03","04","05","06","07","08")
table_classe<-cbind(prenom=sample(students,length(students)),classes=sample(class,length(students),replace=T))
class_b<-c("1A","2A","3A","1Abis","2Abis","3Abis")
table_edt_8h<-cbind(classes=class_b,edt_8h=sample(matiere,length(class_b),replace=T))
table_edt_9h<-cbind(classes=class_b,edt_9h=sample(matiere,length(class_b),replace=T))
n<-length(students)
table_eleves<-cbind(id=1:n,prenom=sample(students,n,replace=F),nom=sample(nom,n,replace=T),tel)
table_classe<-as.tibble(table_classe)
table_edt_8h<-as.tibble(table_edt_8h)
table_edt_9h<-as.tibble(table_edt_9h)
table_eleves<-as.tibble(table_eleves)
table_edt_p1_8h<-table_edt_8h[1:3,]
table_edt_p2_8h<-table_edt_8h[4:6,]
colnames(table_edt_p1_8h)<-c("classes","edt_classes_p1_8h")
colnames(table_edt_p2_8h)<-c("classes","edt_classes_p2_8h")
table_tel<-table_eleves[,-2:-3]
table_nom_prenom<-table_eleves[,1:3]
table_edt_p1_9h<-table_edt_9h[1:3,]
table_edt_p2_9h<-table_edt_9h[4:6,]
colnames(table_edt_p1_9h)<-c("classes","edt_classes_p1_9h")
colnames(table_edt_p2_9h)<-c("classes","edt_classes_p2_9h")
###Exemple concatenetation
m1<-matrix(sample(0:20,20),ncol=4,nrow=5)
m2<-matrix(sample(0:20,20),ncol=4,nrow=5)
m3<-matrix(sample(0:20,20),ncol=4,nrow=5)
m1<-as.tibble(m1)
m2<-as.tibble(m2)
m3<-as.tibble(m3)
##Partie Jointures
###Semi et anti
cartes<-c("Tortank","Roucoups","Rattata","Nidoran","Mysterbe","Nosferapti","Dracaufeu","Alakazam")
pv_cartes<-c("100PV","80 PV","40 PV","60 PV","40 PV","50 PV","120 PV","80 PV")
enfants<-as.tibble(cbind(élèves=students,cartes))
cartes_bis<-cartes[-4]
pv_cartes_bis<-pv_cartes[-4]
info_cartes<-as.tibble(cbind(cartes=cartes_bis,PV=pv_cartes_bis))
```
## Bienvenue
Bienvenue dans notre tutoriel sur l'utilisation des packages 'tidylog' et 'dplyr' afin de fusionner, concaténer et joindre des tables, des jeux de données.
Dans ce tutoriel on s'interessera aux différentes facons de joindre des tables à l'aide du package `dplyr`et `tidylog`
Pour ce faire on divisera ce tutoriel en 2 parties: La première concernera la concaténation qui est une manière de joindre 2 tables ,puis l'on s'interessera aux jointures à proprement parler.
Ainsi on commencera par charger les packages suivant: `tidylog`et `tidyverse`
## Présentation de `tidylog`et `dplyr`
`dplyr` est un package appartenant au coeur du `tidyverse`. Le `tidyverse` est quant a lui un ensemble d'extensions ayant de large fonctionnalités:
Elles abordent un très grand nombre d’opérations courantes dans R . C'est notament un package de premier choix pour la manipulation de tables de données.
C'est `dplyr` qui est l'extension contenant les opérations de manipulation de données.
`tidylog`est quant à lui une aide lors des jointures avec `dplyr`: Il permet lors des opérations de jointures de tables de voir les opérations faites lors de la jointure.
Cependant `tidylog` ne fonctionne que avec les fonction de type "join".
## Concatenation avec `bind_cols` et `bind_rows`
Permettent d’ajouter des lignes (respectivement des colonnes) à une table à partir d’une ou plusieurs autres tables.
### Présentation `bind_cols` et `bind_rows`
Les fonctions `bind_rows` et `bind_cols` permettent d’ajouter des lignes (respectivement des colonnes) à une table à partir d’une ou plusieurs autres tables.
Voici un petit exemple pour comprendre leur fonctionnement:
On dispose de 3 tableaux auxquelles on donne des noms de colonnes différents:
1.1,...1.4 pour le première,
2.1,....2.4 pour le deuxième,
3.1,....3.4 pour le troisième
```{r}
colnames(m1)<-c("1.1","1.2","1.3","1.4")
colnames(m2)<-c("2.1","2.2","2.3","2.4")
colnames(m3)<-c("3.1","3.2","3.3","3.4")
m1
m2
m3
```
Maintenant faisons bind_rows(m1,m2,m3):
```{r exemple}
bind_rows(m1,m2,m3)
```
et bind_cols(m1,m2,m3):
```{r exemple2}
bind_cols(m1,m2,m3)
```
Désormais changeons le noms des colonnes des tableaux tel qu'ils aient les mêmes noms :
colnames(m1)<-c("1.1","1.2","1.3","1.4")
colnames(m2)<-c("1.1","1.2","1.3","1.4")
colnames(m3)<-c("1.1","1.2","1.3","1.4")
```{r exemple3}
colnames(m1)<-c("1.1","1.2","1.3","1.4")
colnames(m2)<-c("1.1","1.2","1.3","1.4")
colnames(m3)<-c("1.1","1.2","1.3","1.4")
bind_rows(m1,m2,m3)
```
et bind_cols(m1,m2,m3):
```{r exemple4}
colnames(m1)<-c("1.1","1.2","1.3","1.4")
colnames(m2)<-c("1.1","1.2","1.3","1.4")
colnames(m3)<-c("1.1","1.2","1.3","1.4")
bind_cols(m1,m2,m3)
```
On en conclut que pour `bind_rows`: Il concatene les lignes pour chaque variables: Si deux colonnes ont des noms similaires les parties des lignes ajoutées appartennant à ses colonnes communes seront considérer comme une seule colonne. Sinon la fonction considère de nouvelles colonnes.
Pour `bind_cols`:Si 2 colonnes ont le même nom, il modifiera le nom des colonnes similaires et les placeras dans des colonnes différentes
A travers cet exemple on peut aussi observer un exemple de l'aide de `tidylog`: EN effet dans la dernière sortie , tidylog nous affiche dans la console les opérations faites:
New Names :
* `1.1` -> `1.1...1`
* `1.2` -> `1.2...2`
* `1.3` -> `1.3...3`
* `1.4` -> `1.4...4`
* `1.1` -> `1.1...5`
* ..."
### Exercices:
#### Présentation du jeu de données
On utilisera dans cette partie d'exercices un jeu de données simples :
Il existe 6 classes:"1A","2A","3A","1Abis","2Abis","3Abis"
et 8 élèves:
-> table_classe contient la classe pour chaque étudiant.
Colonnes de table_classe :
prenom,classes
->table_edt_p1_8h et table_edt_p2_8h,
Ces tables contiennent: La matière du lundi de 8h à 9h de chaque classes. Cependant, il a eu une erreur et la table principale à été séparé en 2. Chaque tables contient 3 classes et leur emploi du temps.
Colonnes des tables table_edt_p1_8h et table_edt_p2_8h:
classes,edt_classes_p1_8h
classes,edt_classes_p2_8h
->table_edt_p1_9h et table_edt_p2_9h
Ces tables contiennent: La matière du lundi de 9h à 10h de chaque classes. Cependant, il a eu une erreur et la table principale à été séparé en 2. Chaque tables contient 3 classes et leur emploi du temps.
Colonnes des tables table_edt_p1_9h et table_edt_p2_9h:
classes,edt_classes_p1_9h
classes,edt_classes_p2_9h
->table_tel et table_nom_prenom,
contienennent les informations personnelles de chaque étudiants
Colonnes des tables table_tel et table_nom_prenom:
id,prenom,nom
id,tel
#### Exercice 1
1)Concatener dans un premier temps les tables (table_edt_p1_8h,table_edt_p2_8h) dans la table table_edt_8h dans laquelle on peut retrouver l'edt de chaqu'une des classes sans modifier les deux tables!
```{r bind_rows, exercise=TRUE}
table_edt_8h<-
table_edt_8h
```
2)On observe alors l'apparition de NA du au fait que par exemple la classe 1A n'existe pas dans la table table_edt_p2_8h: Modifier et concatener les deux tables pour que aucun NA apparaissent
```{r bind_rows2, exercise=TRUE}
[2]<-"edt_8h"
[2]<-"edt_8h"
table_edt_8h<-
table_edt_8h
```
3)Refaite la même opération en utilisant l'option `.id` ="Source" et constatez son utilité: bind_rows(x,y,.id="source")
```{r bind_rows3, exercise=TRUE}
[2]<-"edt_8h"
[2]<-"edt_8h"
table_edt_8h<-bind_rows()
table_edt_8h
```
#### Exercice 2
1)Réunissez les informations prenom,nom,tel des tables table_nom_prenom et table_tel : Sans modifier les tables.
```{r bind_rows4, exercise=TRUE}
```
#### Exercice 3
1)Concatener dans un premier temps les tables (table_edt_p1_9h,table_edt_p2_9h) dans la table table_edt_9h sans NA, comme precedemment
```{r bind_rows6, exercise=TRUE}
[2]<-"edt_9h"
[2]<-"edt_9h"
table_edt_9h<-
table_edt_9h
```
2)Concatenener les tables table_edt_8h et table_edt_9h tel que la table table_edt contiennt l'emploi du temps de toute les classes pour les 2 crenaux
```{r bind_rows7, exercise=TRUE}
table_edt<-bind_cols()
table_edt<-table_edt[,]
table_edt
```
## Les jointures
### Présentation
Les fonctions join fonctionnent globalement de la même manière.
Nous allons dans un premier temps développer left_join, sachant que right_join
fonctionne pratiquement pareil. En effet, left_join(x,y)=right_join(y,x).
Cette fonction permet de rajouter, d'adjoindre à un jeu de données (un tibble) des
informations d'un autre jeu de données (un tibble également)
Comment cela fonctionne?
L'appel de la fonction doit être : left_join(x,y) où x et y sont deux tibble.
Si vos données ne sont pas en tibble, vous pouvez convertir des matrices, des
data frame en tibble grâce à la fonction x=tibble::as_tibble(x).
L'option by de la fonction permet de sélectionner les colonnes
des 2 tableaux (par exemple C1 et C3) où l'on va regarder l'information.
Si l'information est la même dans les 2 tables ,i.e Cx[i,1]=Cy[i,1] et Cx[i,3]=Cy[i,3]
alors le reste de la ligne i de Y est ajouté à la ligne i de X.
Si l'option BY n'est pas précisé, la fonction détecte les colonnes similaires.
De plus, si il n'y a pas d'information pour l'individu i en Y, la fonction
rajoute automatique des NA"
"L'option suffix permet de différencier les colonnes identiques des deux tables
non utilisées dans l'option by. L'option suffix est un vecteur caractère de
longueur 2 où la première valeur attribue le suffixe à la colonne présente dans les 2
tableaux au premier tableau et la seconde valeur de vecteur attribue le suffixe à la
colonne du second tableau".
"Dans l'utilisation des fonctions join, deux packages sont utilisés : le package dpylr
et le package tidylog. Le premier est le package où se trouvent les fonctions et
est donc nécessaire pour faire des jointures. Le package tidylog n'est pas
nécessaire en lui-même mais est très utile car il permet de voir explicitement dans
la console les options prise par les fonctions de dplyr".
### `left_join`et `right_join`
#### Exemple
Nous créons deux jeux de données simples concernant des étudiants fictifs de l'ENSAI.
```{r presentation left, include= FALSE}
etudiants <- tibble(
nom = c("Arnaud","Julien","Maxime","Juliette","Sarah","Paul","Nina","Anaïs"),
provenance=c("MP","STID","MP","MIASHS","MP","MP","INSEE","MP"),
age = c(19,22,26,18,19,20,22,21)
)
parcours <- tibble(
nom = c("Arnaud","Julien","Maxime","Juliette","Sarah","Paul","Nina","Jules"),
option = c("Dvlp durable","Musique","Physique","Théâtre","Physique","Littérature","Anglais","Sport"),
age = c(19,22,26,18,19,20,22,26)
)
```
```{r presentationleft2}
etudiants
parcours
```
Voici donc quelques exemples pour comprendre le fonctionnement de left_join.
```{r exempleleft}
left_join(etudiants,parcours, by=NULL)
```
Le package tidylog nous fournit l'explication de cette fonction. On apprend donc que
by a pris en option deux colonnes : Joining, by = c("nom", "age").
Anaïs n'a pas d'information dans parcours donc la fonction rajoute NA
à sa ligne associée pour parcours après la jointure.
Maintenant si nous donnons à by uniquement la colonne nom, que se passe-t-il?
```{r exemple2left}
left_join(etudiants,parcours, by="nom", suffix = c(".x", ".y"))
```
Il existe donc une colonne age dans chaque tableau qui ne sert pas dans by.
L'option suffixe permet donc de différencier ces colonnes age en age.x et age.y
Enfin, nous renommons la colonne nom de parcours par prenom.
```{r exemple 3 left}
parcours <- tibble(
prenom = c("Arnaud","Julien","Maxime","Juliette","Sarah","Paul","Nina","Jules"),
option = c("Dvlp durable","Musique","Physique","Théâtre","Physique","Littérature","Anglais","Sport"),
age = c(19,22,26,18,19,20,22,26)
)
left_join(etudiants,parcours, by=c("nom"="prenom"), suffix=c(".etudiant",".parcours"))
```
Ainsi, l'option by permet de joindre des tableaux en utilisant des variables
de nom différents. On remarque qu'on obtient le même resultat qu'auparauvant. Or, si l'option by n'avait pas été précisée, cela aurait donné un résultat totalement différent.
```{r exemple 4 left}
left_join(etudiants,parcours)
```
Passons maintenant à la partie exercices.
#### Exercices
##### Exercice 1 : La fonction left_join
```{r exo 4 left}
library(tidyverse)
library(nycflights13)
data(flights)
data(airports)
data(airlines)
```
Voici trois tables sur des vols entre aéroports et villes avec plein
de variables et d'informations.
On aimerait donc associer à chaque vol le nom de la compagnie possédant l'avion."
###### 1) Regardez à quoi ressemblent les jeux de données avec des fonctions comme dim, summary, rownames, head, etc. Prêtez particulièrement attention aux noms des colonnes.
```{r exo_4left1, exercise=TRUE}
```
<div id="exo4left1-hint">
**Indice:** Remarquez les colonnes présentes dans plusieurs jeux de données.
</div>
###### 2) Faites maintenant une jointure avec left_join afin d'ajouter le nom des compagnies aériennes à la table des vols. On nommera la nouvelle table vols_noms. L'option by doit être précisée.
```{r exo4left2, exercise=TRUE}
vols_noms <-
```
```{r exo4left2-solution}
vols_noms <- left_join(flights, airlines, by="carrier")
```
<div id="exo4left2-solution">
**Indice:** vols_noms <- left_join(flights, airlines, by="carrier").
</div>
###### 3) Regardez maintenant votre nouvelle table avec les mêmes fonctions que la question 1.
```{r exo4left3, exercise=TRUE}
```
<div id="exo4left3-hint">
**Indice:** Regardez la dimension de vols_noms par rapport à flights.
</div>
##### Exercice 2 : un petit peu plus compliqué
La table flights nous donne les aéroports de départ et d'arrivée tandis que la table airports nous donne les informations sur ces aéroports. Essayons donc de n'en faire qu'une seule table."
Pour cause de simplification des données, nous supprimons quelques colonnes de flights peu pertinentes dans cet exercice et nous renommons le nom des compagnies aériennes en nom company".
```{r exo5leftprepa}
vols_noms <- left_join(flights, airlines, by="carrier")
```
```{r exo5left}
colnames(vols_noms)
vols_noms_reduit=vols_noms[,c(1,2,3,10,11,13,14,16,20)]
colnames(vols_noms_reduit)=c("year","month","day","carrier","flight","origin","dest","distance","name company")
```
###### 1) Grâce au left_join et à une utilisation correcte de by, ajouter les informations sur les aéroports de départs à la table flights2. On nommera cette nouvelle table vols_noms_complet.
```{r exo5left1, exercise=TRUE}
vols_noms_complets <-
```
```{r exo5left1-solution}
vols_noms_complets <- left_join(vols_noms_reduit,airports, by=c("origin"="faa"))
```
###### 2) Ajoutez maintenant les informations sur les aéroports d'arrivée. Les noms des aéroports d'origine et leurs informations seront de la forme ".aéroport origine" et ceux des aéroports d'arrivée seront ".aéroport arrivée".
```{r exo5left2, exercise=TRUE}
vols_noms_complets <-
```
```{r exo5left2-solution}
vols_noms_complet <- left_join(vols_noms_complet, airports, by=c("dest"="faa"), suffix=c(".aéroport origine",".aéroport arrivée")
)
```
<div id="exo5left2-hint">
**Indice:** Attention à bien utiliser l'option BY et pensez à différencier les aéroports d'origine des aéroports de départ avec l'option suffix.
</div>
#### Quizz
```{r prepaquizz, echo = FALSE, include = FALSE}
x <- tibble(
C1=c(2,3,8,18,29,0),
C2=c('a','b','c','d','e','f'),
C3=c(0.5,2.6,4.3,8.0,1.1,4.2)
)
y <- tibble(
C1=c(2,3,8,18,29,0),
C2=c('a','b','j','d','x','f'),
C4=c(6.7, 7.1, 0.9, 3.0, 2.2, 8.1)
)
A = left_join(x,y)
B = left_join(y,x)
C = full_join(x,y)
D = inner_join(x,y)
```
Voici deux jeux de données simple et quatre jeux de données créés en utilisant différents types de join.
```{r quizz}
x
y
A
B
C
D
```
```{r logicals, echo = FALSE}
question(" Quel est le jeu de données correspondant au code suivant ? `full_join(x,y)`",
answer("A", message = "left_join(x,y) "),
answer("B", message = "left_join(y,x) "),
answer("C", correct = TRUE),
answer("D", message = "inner_join(x,y)"),
allow_retry = TRUE
)
```
### `inner_join`et `full_join`
```{r presentationtotale, include= FALSE}
etudiants <- tibble(
nom = c("Arnaud","Julien","Maxime","Juliette","Sarah","Paul","Nina","Anaïs"),
provenance=c("MP","STID","MP","MIASHS","MP","MP","INSEE","MP"),
age = c(19,22,26,18,19,20,22,21)
)
parcours <- tibble(
nom = c("Arnaud","Julien","Maxime","Juliette","Sarah","Paul","Nina","Jules"),
option = c("Dvlp durable","Musique","Physique","Théâtre","Physique","Littérature","Anglais","Sport"),
age = c(19,22,26,18,19,20,22,26)
)
```
Dans un deuxieme temps, on va donc s'intéresser à 'inner_join' ainsi qu'à 'full_join'.
L'appel de ces deux fonctions sont sensiblement les mêmes que left_join et right_join développées plus haut. Cependant, le types de jointure est différent.
#### 'inner_join'
Ainsi, supposons que l'on souhaite faire une jointure interne grâce à 'inner_join'. Ce type de jointure permet de garder uniquement les individus qui seront dans les deux tables de données.
Pour comprendre la manière dont fonctionnent ces deux fonctions nous allons utiliser l'exemple de l'explication de la partie précédente sur les élèves de l'ENSAI.
Les deux tables présentent deux variables communes : age et nom. Ce sont des relations de clé étrangère qui permettent d'avoir une jointure interne entre ces deux tables.
Nous en avons deux dans notre exemple, mais il est possible de faire une jointure interne avec une tables ayant une ou plus de 2 relations de clé étrangère.
Pour cela, utilisons la commande suivante:
inner_join(etudiants,parcours,by=NULL)
```{r exempleinner1}
inner_join(etudiants,parcours,by=NULL)
```
Avec le package tidylog, cela nous permet donc de savoir que by a pris comme clés étrangères le nom et l'âge. En effet lorsque l'on prend le paramètre by par défault, cela fait en sorte que l'on ait une jointure interne faites avec les 2 clés étrangères.
On obtient alors un jeu de données sans Anaïs et Jules, deux individus étant uniquement respectivement dans la première table et la deuxième table. De plus,chaque individu est représenté par une ligne qui lui est propre à laquelle on a rajouté simplement l'option en dernière colonne.
Désormais, étudions le cas où l'on ferai une jointure interne en ne prenant uniquement que l'âge:
inner_join(etudiants,parcours,by="age")
```{r exempleinner2}
inner_join(etudiants,parcours,by="age")
```
Anaïs a ici disparu de la nouvelle table. Cependant, Jules, quant à lui, y apparait car Maxime à le même âge que lui.
Si l'on fait de même avec un by="nom", on obtiendra alors une table sans Jules ni Anaïs car ils sont tout seul à porter leur prénom parmi les étudiants et.
Cependant il semble important de noter que lorsque l'on restreint la jointure à une seule colonne, les tables qui en résultent ne sont pas très intéressantes.
Pour pouvoir illustrer une jointure interne qui irait dans ce sens et qui serait plus intéressante, ajoutons le tibble suivant à nos données :
```{r presentationinner, include= FALSE}
association <- tibble(
nom= c("Arnaud","Arnaud", "Julien", "Julien", "Karim"),
asso=c("EJC","BDE","EJC","EJR","Ludik"),
anciennete = c(1, 2, 3, 1,2),
)
```
```{r presentationinner2}
association
```
inner_join(etudiants,association,by="age")
```{r exempleinner3}
inner_join(etudiants,association,by="nom")
```
La requète nous montre alors bien une jointure interne entre les deux tables. On remarque que la clé étrangère est ici le nom et que donc, tout les étudiants n'était ni Julien, ni Arnaud disparaissent. De plus, on remarque aussi qu'il y a 2 lignes par étudiants, cela étant lié aux associations.
#### 'full_join'
La jointure complète peut être considérée comme l'antagoniste de la jointure interne. En effet, dans une jointure complète on va garder tout les individus présents dans l'une ou l'autre table.
Pour illustrer cela, reprenons l'exemple des étudiants de l'ENSAI avec la commande suivante:
full_join(etudiants,parcours,by=NULL)
```{r exemplefull1}
full_join(etudiants,parcours,by=NULL)
```
La jointure se fait bien par les deux clés étrangères que sont l'âge et le nom.
On retrouve alors les 9 élèves présents dans les deux tables, c'est à dire l'ensemble des individus.
On observe 2 NA dans notre table finale. Ils sont la conséquence du manque de données de la provenance de Jules ainsi que celle de l'option d'Anaïs.
En conséquence, lors d'une jointure complète, lorsqu'une information est manquante pour l'un des individus ( qu'il n'y a pas de correspondance avec l'autre table) la fonction lui attribut automatiquement la valeur NA.
Observons ce qui se passe si l'on fait une jointure entre deux tables si l'on prend uniquement une colonne sur laquelle regarder l'information:
full_join(etudiants,parcours,by="nom")
```{r exemplefull234}
full_join(parcours,etudiants, by="nom")
```
On retrouve donc nos 9 étudiants avec une concaténation des tables simple et donc 2 colonnes age. On retrouve alors 2 NA pour Jules qui n'est pas présent dans la première table et 2 NA pour Anïs qui n'est pas présente dans la deuxième.
Passons aux exercices:
#### Exercices
##### Exercice 5 : L'usine agroalimentaire
Dans cet exercice, nous allons étudier les 2 tables de données suivantes provenant d'une usine agroalimentaire confectionnant des gateaux aux pommes.
```{r exo5inner prepa, echo = FALSE}
library(tidyverse)
library(tidylog)
ingredients <- tibble(
numero=c(1,2,3,4,5),
ingredient= c("pommes","oeuf","sucre","vanille","farine"),
approvisionneur=c("Royal Pommes","Loué","Daddy","Vahiné","Chabrior"),
id_rangement=c(1,2,4,5,4)
)
rangement <- tibble(
id_rangement = c(1,2,3,4),
nom_rangement = c("Bacs à légumes","Zone Réfrégirée","Entrepôt","Tank à lait"),
remplissage = c(100,56,21,32),
)
```
```{r presentationexercice2345}
ingredients
rangement
```
###### 1) Si je décide de faire une jointure interne entre la table ingrédients et la table rangement, quel ingrédient n'apparaitrera pas dans la table finale ?
```{r exo5leftKS, exercise=TRUE}
"-----"
```
```{r exo5leftKS-solution}
"vanille"
```
##### 2) Donnez à présent la commande permettant de faire cette jointure interne. L'option by doit être précisée et la nouvelle table sera appelée usine.
```{r exo5leftLMM, exercise=TRUE}
usine<-
```
```{r exo5leftLMM-solution}
usine<-inner_join(rangement,ingredients,by="id_rangement")
```
##### Exercice 2 : Le carnet de commande
Dans cet exercice, nous allons étudier les 3 tables de données suivantes provenant du carnet de commande d'une entreprise vendant des produits de coiffure.
```{r exo2full prepa, echo = FALSE}
library(tidyverse)
library(tidylog)
table1<-tibble(
id_client=c(1:6),
Etat=c(rep("Alabama",2), rep("Ohio",4)),
)
table2<-tibble(
id_client=c(2,4,6),
produit=c(rep("Fer à lisser", 2), rep("Shampoing", 1)),
)
table3<-tibble(
Etat=c("Kansas","Ohio","Alabama"),
prix_envoi=c("10$","3.5$","7$"),
jours_livraisons=c("3","1","2"),
)
```
```{r presentationexo6}
table1
table2
table3
```
On retrouve donc 5 variables ici, le numéro de client, l'état où réside le client, le produit acheté par le client, le prix d'envoi du colis et le temps de livraison
```{r quizinner1, echo=FALSE}
question("1- Quelles sont les deux clés étrangères de ce jeu de données ",
answer("Etat & id_client", correct = TRUE),
answer("id_client & produit"),
answer("Etat & produit"),
answer("prix_envoi & produit")
)
```
```{r quizinner2, echo=FALSE}
question("2- Quelle est la jointure à répéter k fois permet d'obtenir tout les individus de toutes les tables de notre jeu de données ? De combien de lignes disposera-t-ton dans la table finale ? ",
answer("jointure interne & k=2 & 7 lignes"),
answer("jointure interne & k=1 & 6 lignes"),
answer("jointure interne & k=1 & 7 lignes"),
answer("jointure complète & k=1 & 7 lignes"),
answer("jointure complète & k=1 & 6 lignes"),
answer("jointure complète & k=2 & 7 lignes", correct = TRUE)
)
```
client<-inner_join(table2,table3,by=NULL)
full_join(table1,client,by=NULL)
```{r quizinner3, echo=FALSE}
question("3- Que va nous donner la commande ci-dessus ? ",
answer("Cela va renvoyer une table de 4 individus"),
answer("Cela va renvoyer une table de 5 individus"),
answer("Cela va renvoyer une table de 6 individus"),
answer("Cela va renvoyer une table de 7 individus"),
answer("Cela va nous renvoyer une erreur", correct = TRUE)
)
```
###### Je souhaite obtenir une table finale notée carnet_de_commande me donnant, pour tout les clients, leur adresse, leur produit s'il en ont acheté, le prix d'envoi d'un colis à leur domicile ainsi que le temps de livraison de ce colis. Si table intermédiaire il y a besoin, vous l'appelerez "client". N'oubliez pas de spécifier la variable dans l'option by.
```{r exo2left234, exercise=TRUE}
```
```{r exo2left234-solution}
client<-full_join(df1,df2,by="id_client")
carnet_de_commande<-inner_join(client,df3,by="Etat")
```
### semi_join et anti_join
`semi_join` et `anti_join` constituent des outils de jointure bien particulières.
En effet leur objectif n'est pas de joindre 2 tables mais de filtrer des tables:
#### Présentation de `semi_join` et `anti_join`
Soit le jeu de données suivantconstitué de 2 tables:
La table enfant:
Recense la carte pokémon favorite de 8 enfants :
```{r semietantiprésent1}
enfants
```
La table`info_cartes`:
Contient les points de vie de quelques cartes pokémons:
```{r semietantiprésent2}
info_cartes
```
##### Exemple
Utilisons la commande suivante:
semi_join(enfants,info_cartes)
```{r semietantiexemple1}
semi_join(enfants,info_cartes)
```
Ici `semi_join` enlève la ligne de Jon car la carte Nidoran n'apparait pas dans la table info_cartes.
De manière générale `semi_join(x,y)`renvoie un tableau contenant les lignes de x qui apparaissent aussi dans y .
Désormais utilisons la commande `anti_join`:
anti_join(enfants,info_cartes)
```{r semietantiexemple2}
anti_join(enfants,info_cartes)
```
Ici `anti_join`renvoie un tableau contenant les lignes de x qui ne paraissent pas dans y :Dans notre cas c'est la ligne de la carte Nidoran.
A l'inverse
anti_join(info_cartes,enfants)
Retourne:
```{r semietantiexemple3}
anti_join(info_cartes,enfants)
```
Aucune ligne n'est renvoyée car toute les lignes de `info_carte`apparaissent dans la table `enfants`
#### Exercices
##### Exercice 1:
```{r semietantiexo1quizz}
quiz(
question("Predisez la sortie de semi_join(info_cartes,enfants)",
answer("Une table avec toutes les lignes de info_cartes avec les colonnes élèves,cartes"),
answer("La table enfants"),
answer("La table info_cartes",correct = TRUE),
answer("Une table avec toutes les lignes de enfants avec les colonnes cartes,PV")
)
)
```
##### Exercice 2:
Ecrivez une simple fonction `info_jointure` qui renvoie si une jointure left_join, ou right_join donnera des NA
```{r semietantiexo2, exercise=TRUE}
info_jointures<-function(tbl1,tbl2,type_join){
test_left<-....(tbl1,tbl2)
test_right<-....(tbl2,tbl1)
type_join<-as.character(type_join)
if(type_join=="left"){
if(dim(test_left)==dim(tbl1)){
rslt<-"SANS NA"
}
else{
rslt<-"..."
}
}
else{
if(dim(test_right)==dim(...)){
rslt<-"..."
}
else{
rslt<-"..."
}
}
paste0(type_join,"_join(tbl1,tbl2)",rslt)
}
```
Testez votre fonction:
```{r semietantiexo2-2,exercise=TRUE}
info_jointures()
```
##### Correction exercice 2:
info_jointures<-function(tbl1,tbl2,type_join){
test_left<-semi_join(tbl1,tbl2)
test_right<-semi_join(tbl2,tbl1)
type_join<-as.character(type_join)
if(type_join=="left"){
if(dim(test_left)==dim(tbl1)){
rslt<-"SANS NA"
}
else{
rslt<-"AVEC NA"
}
}
else{
if(dim(test_right)==dim(tbl2)){
rslt<-"SANS NA"
}
else{
rslt<-"AVEC NA"
}
}
paste0(type_join,"_join(tbl1,tbl2)",rslt)
}
##### Exercice 3 :
Soit:
tbl1<-semi_join(enfants,info_cartes)
tbl2<-anti_join(enfants,info_cartes)
```{r semietantiexo3p1quizz}
quiz(
question("Quelle table contient les lignes de enfants présentent dans la table info_cartes",
answer("tbl2"),
answer("tbl1",correct=TRUE),
answer("Aucune"),
answer("Les 2")
)
)
```
Rajoutons :
tbl3<-semi_join(info_cartes,enfants)
```{r semietantiexo3p2quizz}
quiz(
question("full_join(tbl1,tbl3)fera appraitre des NA",
answer("vrai"),
answer("Faux",correct=TRUE)
),
question("Et inner_join(tbl1,tbl3)",
answer("vrai"),
answer("Faux",correct=TRUE)
)
)
```
## Fin