L’objectif est de passer en revue les différentes fonctions de la la librairie dplyr
library(dplyr)
permettant par exemple de
Ces différentes opérations sont appliquées sur le jeu de données flights de la librairie nycflights13
library(nycflights13)
flights
Le jeu de données flights est un tibble une variante de data frame optimisé pour l’usage des fonction de tidyverse.
library(tibble)
Nous allons nous focaliser sur les cinq fonctions clés de la librairie dplyr, à savoir
Ces fonctions s’utilisent en parallèle de la fonction group_by() permettant le traitement par groupe d’observations. Elles prennent toujours comme premier argument le data frame sur lequel on travaille.
# Sélection des vols du 1er Janvier.
filter(flights, month == 1 & day == 1)
# Sélection des vols de novembre et de décembre
filter(flights, month == 11 | month == 12)
# Autre alternative avec l'opérateur %in%
filter(flights, month %in% c(11, 12))
# Trier par année, mois jours
arrange(flights, year, month, day)
On utilise la fonction desc() pour trier par ordre décroissant.
# Trie en fonction du retard par ordre décroissant
arrange(flights, desc(dep_delay))
Les valeurs manquantes sont toujours placées à la fin.
# Conserve toutes les variables entre year et day (inclus)
select(flights, year:day)
# Sélectionne toute les variables exceptées celles entre year et day (inclus)
select(flights, -(year:day))
La sélection des variables est facilitée par l’utilisation des fonctions suivantes
# Table flights_sml contenant une sélection de variables.
flights_sml <- select(flights,
year:day,
ends_with("delay"),
distance,
air_time
)
# Calcul du rattrapage de retard et de la vitesse
mutate(flights_sml,
during_flight_delay = arr_delay - dep_delay,
speed = distance / air_time * 60
)
On peut aussi faire référence aux variables que l’on vinet de créer
mutate(flights_sml,
during_flight_delay = arr_delay - dep_delay,
hours = air_time / 60,
during_flight_delay = during_flight_delay / hours
)
En utilisant la fonction transmute, on ne conserve que les variables nouvellement créées
transmute(flights,
during_flight_delay = arr_delay - dep_delay,
hours = air_time / 60,
gain_per_hour = during_flight_delay / hours
)
Parmi les fonctions utiles pour la création de variable, on compte les fonctions décalages lag() et lead()
x <- 1:10
lag(x)
## [1] NA 1 2 3 4 5 6 7 8 9
lead(x)
## [1] 2 3 4 5 6 7 8 9 10 NA
Ces fonctions sont utiles pour calculer des variations successives avec x-lag(x) ou détecter un changement de valeur x != lag(x) et les fonctions cumulatives cumsum(), cumprod(), cummin(), cummax() et cummean()
# Sommes cumulées
cumsum(x)
## [1] 1 3 6 10 15 21 28 36 45 55
# Moyennes mobiles
cummean(x)
## [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5
La fonction summarize() réduit le data frame à une seule ligne
summarise(flights, delay = mean(dep_delay, na.rm = TRUE))
Elle n’est pas très utile à moins d’être combinée avec group_by(). On peut ainsi obtenir la moyenne des retards au départ des vols pour chaque jour
by_day <- group_by(flights, year, month, day)
summarise(by_day, delay = mean(dep_delay, na.rm = T))
Nous souhaitons étudier la relation entre la distance et le retard.
library(ggplot2)
# On regroupe les vols par destinations
by_dest <- group_by(flights, dest)
# On calcule une distance moyenne et un retard moyen par destination
# La variable count = n() permet de conserver le nombre d'observations placées dans chaque groupe.
delay <- summarise(by_dest,
count = n(),
dist = mean(distance, na.rm = TRUE),
delay = mean(arr_delay, na.rm = TRUE)
)
# Nuage de point pondéré par la variable count() sur lequel on ajoute une courbe de tendance polynomial
ggplot(data = delay, mapping = aes(x = dist, y = delay)) +
geom_point(aes(size = count)) +
geom_smooth(method = loess)
## Warning: Removed 1 rows containing non-finite values (stat_smooth).
## Warning: Removed 1 rows containing missing values (geom_point).
On observe une tendance décroissante qui tend à conjecturer qu’une longue distance donne au pilote plus de marge pour rattraper le retard du vol. Une dernière opération peut être effectuée afin par exemple d’enlever l’aeroport d’Honolulu et les aéroports avec très peu de vol qui semble être souvent des valeurs marginales.
#On enlève les vols vers Honolulu et les destination avec moins de 20 vols
delay <- filter(delay, count > 20, dest != "HNL")
# On refait le même graphique que précédemment
ggplot(data = delay, mapping = aes(x = dist, y = delay)) +
geom_point(aes(size = count)) +
geom_smooth(se = FALSE)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
Le pipe %>% permet de ne pas créer des data frames intermédiaires et améliore la lisibilité du code
delays <- flights %>%
group_by(dest) %>%
summarise(
count = n(),
dist = mean(distance, na.rm = TRUE),
delay = mean(arr_delay, na.rm = TRUE)
) %>%
filter(count > 20, dest != "HNL")
Une fusion de deux data frames permet la création d’un nouveau data frame contenant plus de variables. La combinaison des deux data frames initiaux est possible du fait de la présence d’une ou plusieurs variables en commun dans les deux data frames. La librairie nycflights13 contient plusieurs jeu de données.
data(flights)
data(airports)
data(airlines)
la variable carrier dans la table flights contient indique la compagnie ayant opéré le vol.
flights %>% select(carrier)
On souhaite récupérer à l’aide cette information le nom complet de la compagnie aérienne qui est renseigné dans le data frame airlines.
airlines
Il est naturel de vouloir associer les deux data frames pour par exemple ajouter l’information name dans le data frame flights, on utilise pour cela la fonction left_join.
left_join(flights, airlines) %>% select(month, day, carrier, name)
## Joining, by = "carrier"
Dans cet exemple aucun preprocessing n’est nécessaire. La table airports contient des informations relatives aux aéroports
data("airports")
airports
La variable faa contient le code de l’aéroport, cette information est aussi présente dans la table flights avec la variable origin correspondant à l’aéroport de départ et dest pour l’aéroport d’arrivée.
flights %>% select(day, month, origin, dest)
La fusion direct de ces deux tables renvoit un message d’erreur
# left_join(flights, airports)
En effet, il est nécessaire de préciser la variable qui fera le lien entre les deux tables via l’option by=. Pour simplifier l’affichage, nous effectuons les opérations sur des tables contenant moins de variables avec
flights_ex <- flights %>% select(origin, dest, day, month)
airports_ex <- airports %>% select(faa, name, tzone)
left_join(flights_ex, airports_ex, by = c(origin = 'faa'))
Il existe plusieurs type de jointure suivant la relation entre les tables. Considérons les deux tables suivantes
prof_exp <- data.frame(nom = c('Bienvenue', 'Goffard', 'Milhaud', 'Clot', 'Bienvenue'), expertise = c('proba', 'None', 'stat', 'CS', 'CS'))
prof_exp
et
prof_prenom <- data.frame(nom = c('Bienvenue', 'Salhi'), prenom = c('Alexis', 'Yahia'))
prof_prenom
L’ordre dans lequel les tables sont passés en argument de la fonction left_join() a son importance.
left_join(prof_exp, prof_prenom, by = 'nom')
## Warning: Column `nom` joining factors with different levels, coercing to
## character vector
Chaque ligne présente dans prof_exp se retrouve dans le résultat de la fusion. La ligne Yahia présente dans prof_prenom mais pas dans prof_exp ne se retrouve pas dans la fusion. Les ligne Milhaud, Goffard et Clot sont dans la table issue de la fusion mais l’information pour la variable prenom est manquante car non-renseignée dans la table prof_prenom. Si on change l’ordre d’apparition dans left_join, c’est l’inverse
left_join(prof_prenom, prof_exp, by = 'nom')
## Warning: Column `nom` joining factors with different levels, coercing to
## character vector
Afin d’éviter les valeur manquante, on peut utiliser inner_join pour ne conserver que les lignes présentes dans chacune des deux tables.
inner_join(prof_exp, prof_prenom)
## Joining, by = "nom"
## Warning: Column `nom` joining factors with different levels, coercing to
## character vector