class: center, middle, inverse, title-slide # Informatique : Données ## Licence 3 Economie-Gestion - Parcours Economie-Finance ### Ewen Gallic ### Aix-Marseille Université ### 2020-2021 (mise à jour: 2020-09-06) --- class: inverse, center, middle # 1. Type de données <br/><br/><br/> <div style='text-align: center;'> <img src = "images/donnees/dilbert_data_accuracy.gif" width = "700px" title = "https://dilbert.com/strip/2020-05-07" /> <br/> <span class = "lien_source">Source : <a href = "https://dilbert.com/strip/2020-05-07">https://dilbert.com/strip/2020-05-07</a></span> </div> --- ### Types de données - `R` gère des objets ; - Ces objets ont quatre caractéristiques : * un <b class = "coul_1">nom</b>, * un <b class = "coul_1">mode</b>, * une <b class = "coul_1">longueur</b>, * un <b class = "coul_1">contenu</b>. --- class: titre_2, center, middle ## 1.1. Mode --- #### Mode - Mode = nature, type des éléments qui composent l'objet ; - Accès par `mode()` ou `typeof()`. ```r a <- 2 mode(a) ``` ``` ## [1] "numeric" ``` -- Il existe quatre principaux modes : - `numeric` ; - `character` : - `logical` ; - `complex`. --- #### Mode : numeric - Deux types de `numeric` : * `integers` (entiers), * `double` ou `real` (réels). ```r a <- 2.0 typeof(a) ``` ``` ## [1] "double" ``` ```r is.integer(a) # a est un réel, pas un entier. ``` ``` ## [1] FALSE ``` ```r b <- 2 ``` --- #### Mode : numeric ```r typeof(b) ``` ``` ## [1] "double" ``` ```r c <- as.integer(b) typeof(c) ``` ``` ## [1] "integer" ``` ```r is.numeric(c) # c est bien un numérique. ``` ``` ## [1] TRUE ``` --- #### Mode : character - Placées entre guillemets simples `'` ou doubles `"`. ```r a <- "Hello world!" a ``` ``` ## [1] "Hello world!" ``` ```r typeof(a) ``` ``` ## [1] "character" ``` --- #### Mode : logical - Deux valeurs : `TRUE` ou `FALSE`. ```r a <- 1 ; b <- 2 a < b ``` ``` ## [1] TRUE ``` ```r a == 1 # Test d'égalité ``` ``` ## [1] TRUE ``` ```r a != 1 # Test d'inégalité ``` ``` ## [1] FALSE ``` --- #### Mode : logical ```r is.character(a) ``` ``` ## [1] FALSE ``` ```r (a <- TRUE) ``` ``` ## [1] TRUE ``` ```r (a <- T) ``` ``` ## [1] TRUE ``` --- #### Mode : logical ##### Remarque `TRUE` est converti en `1` et `FALSE` en `0` ```r TRUE + TRUE + FALSE + TRUE*TRUE ``` ``` ## [1] 3 ``` --- #### Mode : complex - Partie réelle : `Re()` ; - Partie imaginaire : `Im()` ; - Création à l'aide de la lettre `i`. ```r 1i ``` ``` ## [1] 0+1i ``` ```r z <- 2+3i ``` --- #### Mode : complex ```r Re(z) # Partie réelle de z ``` ``` ## [1] 2 ``` ```r Im(z) # Partie imaginaire de z ``` ``` ## [1] 3 ``` ```r Mod(z) # Module de z ``` ``` ## [1] 3.605551 ``` ```r Arg(z) # Argument de z ``` ``` ## [1] 0.9827937 ``` --- class: titre_2, center, middle ## 1.2. Longueur --- #### Longueur - Nombre d'éléments que contient un objet ; - `length()`. ```r a <- 1 length(a) ``` ``` ## [1] 1 ``` --- class: titre_2, center, middle ## 1.3. Données manquantes --- #### Données manquantes - `NA` : <em>not available</em> ; - type `logical`. ```r x <- NA typeof(x) ``` ``` ## [1] "logical" ``` ```r is.na(x) ``` ``` ## [1] TRUE ``` --- class: titre_2, center, middle ## 1.4. L'objet vide --- #### L'objet vide - `NULL` : représente le vide ; - Mode `NULL` ; - Longueur `0` ; - Différent de l'objet vide ! ```r x <- NULL typeof(x) ``` ``` ## [1] "NULL" ``` ```r length(x) ``` ``` ## [1] 0 ``` --- #### L'objet vide ```r is.null(x) ``` ``` ## [1] TRUE ``` ```r is.null(list()) # La liste vide n'est pas NULL ``` ``` ## [1] FALSE ``` --- class: inverse, center, middle # 2. Structure des données <br/><br/><br/> <div style='text-align: center;'> <img src = "images/donnees/xkcd_matrix.png" width = "500px" title = "http://dilbert.com/strips/comic/2010-04-02/" /> <br/> <span class = "lien_source">Source : <a href = "http://xkcd.com/184/">http://xkcd.com/184/</a></span> </div> --- #### Structure des données - Les structures servent à <b class = "coul_1">organiser</b> les données ; - Accès par la fonction `class()`; - Quelques structures principales : * vecteurs, * facteurs, * matrices, tableaux, * tableaux de données. --- class: titre_2, center, middle ## 2.1. Vecteurs --- #### Vecteurs - Objets les plus communs en R ; - Tous les éléments d'un vecteur doivent être <b class = "coul_1">de même type</b> ; - Création (par exemple) par la fonction `c()`. ```r c(1,2,3) ``` ``` ## [1] 1 2 3 ``` -- On peut attribuer un nom aux éléments d'un vecteur, soit <em>a priori</em>, soit <em>a posteriori</em>. --- #### Vecteurs ```r a <- c(nom = "Piketty", prenom = "Thomas", annee_naissance = "1971") a ``` ``` ## nom prenom annee_naissance ## "Piketty" "Thomas" "1971" ``` ```r b <- c("Piketty", "Thomas", "1971") b ``` ``` ## [1] "Piketty" "Thomas" "1971" ``` ```r names(b) <- c("nom", "prenom", "annee_naissance") b ``` ``` ## nom prenom annee_naissance ## "Piketty" "Thomas" "1971" ``` --- #### Vecteurs - En cas de mélange de types, `R` convertit automatiquement dans le type le plus général. ```r c("deux", 1, TRUE) ``` ``` ## [1] "deux" "1" "TRUE" ``` -- - L'objet est-il un vecteur ? Combien possède-t-il d'éléments ? ```r a <- c(2,1) is.vector(a) ``` ``` ## [1] TRUE ``` ```r length(a) ``` ``` ## [1] 2 ``` --- class: titre_2, center, middle ## 2.2. Facteurs --- #### Facteurs - Pour les variables <b class = "coul_1">qualitatives</b> ; - Construction avec `factor()` ```r pays <- factor(c("France", "France", "Chine", "Espagne", "Chine")) pays ``` ``` ## [1] France France Chine Espagne Chine ## Levels: Chine Espagne France ``` ```r class(pays) ``` ``` ## [1] "factor" ``` --- #### Facteurs - Les <b class = "coul_1">niveaux</b> s'obtiennent avec la fonction `levels()`. ```r levels(pays) ``` ``` ## [1] "Chine" "Espagne" "France" ``` -- - Le changement de la référence s'effectue avec `relevel()`. ```r pays <- relevel(pays, ref = "Espagne") pays ``` ``` ## [1] France France Chine Espagne Chine ## Levels: Espagne Chine France ``` --- #### Facteurs Avec des modalités <b class = "coul_1">ordonnées</b>. ```r revenus <- ordered(c("<1500", ">2000", ">2000", "1500-2000", ">2000", "<1500"), levels = c("<1500", "1500-2000", ">2000")) revenus ``` ``` ## [1] <1500 >2000 >2000 1500-2000 >2000 <1500 ## Levels: <1500 < 1500-2000 < >2000 ``` --- class: titre_2, center, middle ## 2.3. Dates --- #### Dates - Trois classes de dates : - `Date` : pour les dates sans informations sur les heures (`1977-05-27`), - `POSIXct` et `POSIXlt` : pour les dates avec des heures (`1977-05-27 20:00:00`). -- - Stockage en `R` : <b class = "coul_1">nombre de jours</b> depuis `1970-01-01`, en valeurs négatives pour les dates antérieures ; - On peut le voir avec la fonction `unclass()` ; - Le format standard est : `%Y-%m-%d` ou `%Y/%m/%d` (`%Y` : année sur 4 chiffres, `%m` : mois sur deux chiffres, `%d` : jour sur deux chiffres). ```r (d <- as.Date("2015-10-21")) ``` ``` ## [1] "2015-10-21" ``` ```r unclass(d) ``` ``` ## [1] 16729 ``` --- #### Les classes de dates : `date` - Le paramètre `format` permet de préciser des formats non standards ; - Le paramètre `origin` permet de préciser une date d'origine différente de `1970-01-01`. ```r (d <- as.Date("2015 21 10", format = ("%Y %d %m"))) ``` ``` ## [1] "2015-10-21" ``` ```r (d <- as.Date("21 Octobre, 2015", format = ("%d %B, %Y"))) ``` ``` ## [1] "2015-10-21" ``` --- #### Les classes de dates : `formats` - Les codes des formats sont accessibles sur `?strptime()` (cf poly) ; | Code | Description | Exemple | |------|-------------|---------| | %a | Abréviation du jour de la semaine (dépend du lieu) | Mer | | %A | Jour de la semaine complet (dépend du lieu) | Mercredi | | %b | Abréviation du mois (dépend du lieu) | oct | | %B | Nom du mois complet (dépend du lieu) | octobre | | %d | Jour du mois (01–31) | 21 | | %D | Date au format %m/%d/%y | 10/21/15 | | %H | Heure (00–24) | 00 | | %m | Mois (01–12) | 10 | | %M | Minute (00-59) | 00 | | %S | Seconde (00-61) | 00 | | %Y | Année (en input, uniquement de 0 à 9999) | 2015 | | %z | offset en heures et minutes par rapport au temps UTC | +0000 | | %Z | Abréviation du fuseau horraire (en output seulement) | UTC | --- #### Les classes de dates : `POSIXct` et `POSIXlt` - `POSIXct` : dates stockées en <b class = "coul_1">secondes</b> depuis `1970-01-01 01:00:00` ; ```r d <- as.POSIXct("2015-10-21 13:55:44") unclass(d) ``` ``` ## [1] 1445428544 ## attr(,"tzone") ## [1] "" ``` ```r unclass(as.POSIXct("1970-01-01 01:00:00")) ``` ``` ## [1] 0 ## attr(,"tzone") ## [1] "" ``` --- #### Les classes de dates : `POSIXct` et `POSIXlt` - La fonction `Sys.time()` retourne un objet `POSIXct` indiquant la date et l'heure actuelle. ```r Sys.time() ``` ``` ## [1] "2020-09-06 13:25:52 CEST" ``` --- #### Les classes de dates : `POSIXct` et `POSIXlt` - `POSIXlt` : dates sous formes de <b class = "coul_1">listes</b> dont les éléments sont (cf `?DateTimeClasses`) : | Code | Description | |------|-------------| | sec | secondes (0–61) | | min | minutes (0–59) | | hour | heures (0–23) | | mday | jour du mois (1–31) | | mon | mois après le premier de l'année (0–11) | | year | années depuis 1900 | | wday | jour de la semaine (0–6), début de semaine le dimanche | | yday | jour de l'année (0–365) | | isdst | indicateur d'heure d'été (positif si appliquable, zéro sinon; négatif si in- connu) | | zone | Abréviation du fuseau horraire local ("" si inconnu, ou UTC) | | gmtoff | décalage en minutes par rapport au temps GMT (NA ou 0 si inconnu) | --- #### Dates : {`lubridate`} - Le _package_ {`lubridate`} propose des fonctions pour gérer les dates. - Trois fonctions pour les dates sans heures, à appliquer pour convertir une chaîne de caractères en date : - `ymd()`, - `mdy()`, - `dmy()` ; - les lettres font référence à l'année (`y` – _year_), le mois (`m` – _month_) et le jour (`d` – _day_) ; - Position des lettres : ordre des éléments de la date dans la chaîne de caractètres - pas nécessaire de préciser les séparateurs, une analyse est faite automatiquement pour le deviner. --- #### Dates : {`lubridate`} ```r library(lubridate) ``` ``` ## ## Attaching package: 'lubridate' ``` ``` ## The following objects are masked from 'package:base': ## ## date, intersect, setdiff, union ``` ```r ymd("2015-10-21") ``` ``` ## [1] "2015-10-21" ``` ```r mdy("10.21-15") ``` ``` ## [1] "2015-10-21" ``` ```r dmy("21 oct 2015") ``` ``` ## [1] "2015-10-21" ``` --- #### Dates : {`lubridate`} et fuseau horaire - Précision du fuseau horaire (si nom du fuseau reconnu par le système d'exploitation) : argument `tz` ```r ymd("2015-10-21", tz = "Pacific/Auckland") ``` ``` ## [1] "2015-10-21 NZDT" ``` -- - La fonction `OlsonNames()` retourne un vecteur contenant tous les fuseaux horaires disponibles. --- #### Dates : {`lubridate`} : heures, minutes et secondes - Si heures, minutes et secondes dans les dates : ajout d'un suffixe à la fonction de date ; - `h` (heures), ou `hm` (heures et minutes) ou `hms` (heures, minutes et secondes) ; - même principe que pour y, m et d pour les positions de h, m et s. ```r ymd_hms("2015-10-21 10:00:50") ``` ``` ## [1] "2015-10-21 10:00:50 UTC" ``` --- class: titre_2, center, middle ## 2.4. Matrices et tableaux --- #### Matrices et tableaux - Vecteurs avec un attribut de dimension (`dim`) valant 2 ; - Création avec `matrix()` ou `array()` ; - Remplissage par <b class = "coul_1">colonnes</b> successives. - Les données doivent être de même type. ```r (X <- matrix(1:6, ncol = 2, nrow = 3)) ``` ``` ## [,1] [,2] ## [1,] 1 4 ## [2,] 2 5 ## [3,] 3 6 ``` --- #### Matrices Pour forcer le remplissage par <b class = "coul_1">lignes</b> successives : ```r (Y <- matrix(1:6, ncol = 2, nrow = 3, byrow = TRUE)) ``` ``` ## [,1] [,2] ## [1,] 1 2 ## [2,] 3 4 ## [3,] 5 6 ``` --- #### Tableaux ```r (Z <- array(1:24, dim = c(2, 4, 3))) ``` ``` ## , , 1 ## ## [,1] [,2] [,3] [,4] ## [1,] 1 3 5 7 ## [2,] 2 4 6 8 ## ## , , 2 ## ## [,1] [,2] [,3] [,4] ## [1,] 9 11 13 15 ## [2,] 10 12 14 16 ## ## , , 3 ## ## [,1] [,2] [,3] [,4] ## [1,] 17 19 21 23 ## [2,] 18 20 22 24 ``` --- class: titre_2, center, middle ## 2.5. Listes --- #### Listes - Structures moins rigide ; - Les <b class = "coul_1">modes</b> des éléments peuvent être <b class = "coul_1">différents</b>. ```r (personne <- list("Piketty", "Thomas", "1971")) ``` ``` ## [[1]] ## [1] "Piketty" ## ## [[2]] ## [1] "Thomas" ## ## [[3]] ## [1] "1971" ``` ```r class(personne) ``` ``` ## [1] "list" ``` --- #### Listes - Les éléments peuvent être <b class = "coul_1">nommés</b> ; - Si le nom contient une espace, il faut utiliser des guillemets. ```r personne <- list("nom de famille" = "Piketty", prenom = "Thomas", annee = 1971) personne ``` ``` ## $`nom de famille` ## [1] "Piketty" ## ## $prenom ## [1] "Thomas" ## ## $annee ## [1] 1971 ``` --- #### Listes - Pour <b class = "coul_1">aplatir</b> une liste, on utilise la fonction `unlist()` ; - L'objet retourné est un <b class = "coul_1">vecteur</b> : attention aux conversions ! ```r unlist(personne) ``` ``` ## nom de famille prenom annee ## "Piketty" "Thomas" "1971" ``` --- class: titre_2, center, middle ## 2.6. Tableaux de données --- #### Tableaux de données - Structure largement utilisée par de nombreuses fonctions ; - Il s'agit d'une liste composée de vecteurs ; - Le mode des vecteurs peut varier ; - Création avec `data.frame()`. ```r femmes <- data.frame(height = c(58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72), weight = c(115, 117, 120, 123, 126, 129, 132, 135, 139, 142, 146, 150, 154, 159, 164)) ``` --- #### Tableaux de données ```r head(femmes, 4) ``` ``` ## height weight ## 1 58 115 ## 2 59 117 ## 3 60 120 ## 4 61 123 ``` ```r is.data.frame(femmes) ``` ``` ## [1] TRUE ``` ```r class(femmes) ``` ``` ## [1] "data.frame" ``` --- #### Tableaux de données ```r dim(femmes) # Dimensions ``` ``` ## [1] 15 2 ``` ```r nrow(femmes) # Nombre de lignes ``` ``` ## [1] 15 ``` ```r ncol(femmes) # Nombre de colonnes ``` ``` ## [1] 2 ``` --- #### Tibbles - La structure des `data.frame` est ancienne, le comportement de R peut être parfois pénible avec les `data.frame`, lorsque les volumes de données sont importants ; - Les `tibble` (_package_ {`tibble`}) proposent une alternative plus récente, dans un environnement R appelé `tidyverse` ; - La création est similaire à celle des `data.frame`: ```r library(tidyverse) femmes_tibble <- tibble(height = c(58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72), weight = c(115, 117, 120, 123, 126, 129, 132, 135, 139, 142, 146, 150, 154, 159, 164)) femmes_tibble ``` ``` ## # A tibble: 15 x 2 ## height weight ## <dbl> <dbl> ## 1 58 115 ## 2 59 117 ## 3 60 120 ## 4 61 123 ## 5 62 126 ## 6 63 129 ## 7 64 132 ## 8 65 135 ## 9 66 139 ## 10 67 142 ## 11 68 146 ## 12 69 150 ## 13 70 154 ## 14 71 159 ## 15 72 164 ``` --- #### Tibbles - Lors de la création, <b class = "coul_2">le nom des colonnes</b> n'est pas modifié s'il ne respecte pas les anciennes règles de nommage (à condition d'utiliser les accents graves pour définir le nom) ; - Les lignes ne sont <b class = "coul_2">pas nommées</b> ; - Les vecteurs de longueur 1 seront <b class = "coul_2">recyclés</b> (la valeur sera répétée le nombre de lignes du tableau final) ; - Il est possible de faire appel au nom d'une colonne <b class = "coul_2">créée précédemment</b>. ```r tibble(`1essai!` = c(1, 2, 3, 4, 5), col_deux = c(6, 7, 8, 9, 10), col_trois = 0, test = `1essai!` + col_deux ) ``` ``` ## # A tibble: 5 x 4 ## `1essai!` col_deux col_trois test ## <dbl> <dbl> <dbl> <dbl> ## 1 1 6 0 7 ## 2 2 7 0 9 ## 3 3 8 0 11 ## 4 4 9 0 13 ## 5 5 10 0 15 ``` --- #### Conversion d'un `data.frame` en `tibble` - La fonction `as_tibble()` permet de <b class = "coul_2">convertir</b> un `data.frame` en `tibble` : ```r femmes_tibble_2 <- as_tibble(femmes) femmes_tibble_2 ``` ``` ## # A tibble: 15 x 2 ## height weight ## <dbl> <dbl> ## 1 58 115 ## 2 59 117 ## 3 60 120 ## 4 61 123 ## 5 62 126 ## 6 63 129 ## 7 64 132 ## 8 65 135 ## 9 66 139 ## 10 67 142 ## 11 68 146 ## 12 69 150 ## 13 70 154 ## 14 71 159 ## 15 72 164 ``` ```r class(femmes_tibble_2) ``` ``` ## [1] "tbl_df" "tbl" "data.frame" ``` --- #### Pourquoi utiliser des Tibbles plutôt que des `data.frame` ? La raison principale, à ce stade de l'apprentissage de R, réside dans l'<b class = "coul_1">affichage</b>. - Lorsque l'on affiche un `tibble` en évaluant son nom dans la console, R n'affichera que les <b class = "coul_2">10 premières lignes</b> et <b class = "coul_2">l'ensemble des colonnes</b> qui peuvent s'afficher sur l'écran ; - Le <b class = "coul_2">mode</b> des colonnes est décrit lors de l'affichage ; - Une <b class = "coul_2">coloration syntaxique</b> est proposée pour visualiser plus facilement les contenus. Pour afficher davantage de lignes, il est possible d'utiliser la fonction `options()` : - `options(tibble.print_max = n, tibble.print_min = m)` : s'il y a plus de `n` lignes, seules les `m` premières seront affichées ; - `options(tibble.width = Inf)` : toutes les colonnes seront affichées, indépendament de la largeur de l'écran. --- class: exo # Exercices 1. Que permet une liste par rapport à un vecteur ? 2. Quel sera le retour de `c("deux", 1, TRUE)` ? de `c(0, FALSE)` ? de `c(0, "FALSE")` ? 3. Créer un vecteur de facteurs, de taille 5, dont les modalités sont les suivantes : "Google", "Instagram", "Twitter". La modalité de référence doit être "Google". Toutes les modalités doivent être présentes au moins une fois ; 4. Créer la matrice suivante sous `R` : `$$\begin{bmatrix}39 & 66 & 13\\66 & 168 & 28\\13 & 28 & 5\end{bmatrix}$$` 5. En utilisant la matrice de la question 4, la transformer en <em>data frame</em> ; 6. Créer la matrice de la fonction 4 à l'aide de la fonction `data.frame()`. --- class: inverse, center, middle # 3. Importation, exportation et création de données <br/> <div style='text-align: center;'> <img src = "images/donnees/datactivist.png" width = "500px" title = "Stickers Hex Datactivist" /> <br/> <span class = "lien_source">Source : <a href = "https://twitter.com/joelgombin/status/1143509781098967040">https://twitter.com/joelgombin/status/1143509781098967040</a></span> </div> --- #### Un mot sur l'espace de travail - Travail dans un <b class = "coul_1">environnement de travail</b> ; - Lecture et écriture par défaut dans le répertoire courant ; - Le connaître avec `getwd()` ; - Le changer avec `setwd()` ; - Utilisateurs de Windows : attentions avec le caractère "`/`". ```r getwd() # Affichage de l'environnement de travail setwd("C:\\Mes Documents\R") # Changement de cet environnement ``` -- - Généralement, il vaut mieux ne pas utiliser la fonction `setwd()` ; - Il est préférable de créer un Projet R pour laisser le soin à l'environnement de développement (e.g., RStudio) la détermination du répertoire courant : - plus pratique en cas de partage de code avec d'autres utilisateurs, ou suite à un changement de machine. --- class: titre_2, center, middle ## 3.1. Importation de données --- #### Importation - Avec des fichiers textes (ASCII) : * `read.table()`, * `scan()` - Avec des formats propriétaires, d'autres <em>packages</em> doivent être chargés. --- #### La fonction read.table() - Pratique avec des données déjà organisées sous forme de tableau ; - Range les données dans un <em>data frame</em> ; - Quelques paramètres principaux de la fonction : | Paramètre | Description | | ----------|:-----------:| | `file` | Nom de fichier ou chemin complet vers le fichier (peut être une URL) | | `header` | Noms de variables en 1ère ligne ? (`FALSE` par défaut) | | `sep` | Champ de séparation (caractère blanc par défaut)| | `dec` | Caractère pour les décimales ("`.`" par défaut) | | `row.names` | Vecteur des noms de lignes (numéro des lignes par défaut) | | `na.strings` | Vecteur de chaînes de caractères indiquant les valeurs manquantes (`NA` par défaut) | | `colClasses` | Vecteur de caractères indiquant les modes des colonnes (`R` fait au mieux par défaut) | --- #### La fonction read.table() : exemple ```r url <- "http://data.princeton.edu/wws509/datasets/phbirths.dat" phbirths <- read.table(url) ``` ```r head(phbirths) ``` ``` ## black educ smoke gestate grams ## 1 FALSE 0 TRUE 40 2898 ## 2 TRUE 0 TRUE 26 994 ## 3 FALSE 2 FALSE 38 3977 ## 4 FALSE 2 TRUE 37 3040 ## 5 FALSE 2 FALSE 38 3523 ## 6 FALSE 5 TRUE 40 3100 ``` --- #### Le _package_ {`readr`} - Le _package_ {`readr`} (environnement `tidyvsere`) propose de nombreuses fonctions pour importer les données ; - Ces fonctions commencent par le préfixe `read_` ; - Leur utilisation est relativement similaire aux fonctions de type `read.` de {`utils`} ; - Les tableaux de données sont de structure `tibble` plutôt que `data.frame` avec {`readr`}. ```r url <- "http://data.princeton.edu/wws509/datasets/phbirths.dat" phbirths <- readr::read_table(url) ``` ```r phbirths ``` ``` ## # A tibble: 1,115 x 6 ## X1 black educ smoke gestate grams ## <dbl> <lgl> <dbl> <lgl> <dbl> <dbl> ## 1 1 FALSE 0 TRUE 40 2898 ## 2 2 TRUE 0 TRUE 26 994 ## 3 3 FALSE 2 FALSE 38 3977 ## 4 4 FALSE 2 TRUE 37 3040 ## 5 5 FALSE 2 FALSE 38 3523 ## 6 6 FALSE 5 TRUE 40 3100 ## 7 7 TRUE 6 FALSE 40 3670 ## 8 8 TRUE 7 FALSE 41 3097 ## 9 9 TRUE 7 TRUE 39 3040 ## 10 10 TRUE 7 TRUE 39 3239 ## # … with 1,105 more rows ``` --- class: exo # Exercices 1. Télécharger le fichier <a href="http://data.princeton.edu/wws509/datasets/phbirths.dat" title="Births in Philadelphia (Germán Rodríguez, Office of Population Research, Princeton University )">phbirths.dat</a>, et le placer dans le répertoire de travail ; 2. Lire le fichier téléchargé à l'aide de la fonction `read.table()`. 3. Idem avec la fonction `read_table()`. --- #### La fonction read.table() : variantes - Il existe des variantes de `read.table()` : | Fonction | Séparateur de champs | Séparateur décimal | | ---------|:--------------------:|:------------------:| | `read.csv()` | "`,`" | "`.`" | | `read.csv2()` | "`;`" | "`,`" | | `read.delim()` | "`\t`" | "`.`" | | `read.delim2()` | "`\t`" | "`,`" | -- - Idem avec `read_table()` : | Fonction | Séparateur de champs | Séparateur décimal | | ---------|:--------------------:|:------------------:| | `read_csv()` | "`,`" | "`.`" | | `read_csv2()` | "`;`" | "`,`" | | `read_delim()` | "`\t`" | "`.`" | | `read_delim2()` | "`\t`" | "`,`" | --- #### La fonction scan() - Plus souple que `read.table()` ; - Quand les données ne sont pas organisées en tableau ; - La nature des variables peut être spécifiée par `what`. - Quelques paramètres principaux de la fonction : | Paramètre | Description | | ----------|:-----------| | `file` | Nom de fichier ou chemin complet vers le fichier (peut être une URL) | | `what` | Type des données lues | | `nmax` | Nombre de données maximum à lire | | `n` | Nombre de données à lire (pas de limite par défaut) | | `sep` | Champ de séparation (caractère blanc par défaut)| | `dec` | Caractère pour les décimales ("`.`" par défaut) | | `skio` | Nombre de lignes à omettre avant de débuter l'importation | | `na.strings` | Vecteur de chaînes de caractères indiquant les valeurs manquantes (`NA` par défaut) | | `flush` | Si `TRUE`, commence l'importation de la ligne suivante après le dernier champs requis (permet d'avoir des commentaires après le dernier champ) | --- #### La fonction scan() : exemple ```r url <- "http://data.princeton.edu/wws509/datasets/phbirths.dat" phbirths <- read.scan(url, what = "character") ``` ```r head(phbirths) ``` ``` ## [1] "black" "educ" "smoke" "gestate" "grams" "1" ``` --- class: exo # Exercices 1. À partir du fichier `phbirths.dat` téléchargé précédemment, utiliser la fonction `scan()` pour l'importer dans R. --- #### La fonction scan() : remarque - Appel à `scan()` sans paramètre file : données à entrer au clavier ; - Touche `ENTREEE` pour valider chaque entrée ; - Touche `ENTREE` sans saisie, ou `ESC` pour terminer. - Fin de saisie en ```r tmp <- scan() ``` --- #### La fonction read.fwf() - Fichiers dans un format à largeur fixée (<em>fixed width format</em>) ; - Mêmes paramètres que `read.table()` ; - Paramètre supplémentaire : `widths` pour indiquer les largeur des colonnes. ```r url <- "http://egallic.fr/Enseignement/R/Data/data_fwf.txt" phbirths <- read.fwf(url, widths = c(6,2,4)) ``` ```r head(phbirths, 4) ``` ``` ## V1 V2 V3 ## 1 FRANCE FR 14.0 ## 2 FRANCE FR 23.0 ## 3 FRANCE FR 32.9 ## 4 ITALIE IT 15.9 ``` --- #### Importation depuis Excel - Fichiers `.xls` ou `.xlsx` ; - Une fonction parmi d'autres : `read.xls()` (<em>package</em> `gdata`) ; - Choix optionnel de la feuille avec le paramètre `sheet` : par numéro ou par nom. ```r library("gdata") # Récupérer le lien vers le fichier iris.xls xlsfile <- file.path(path.package('gdata'),'xls','iris.xls') iris <- read.xls(xlsfile) # Créé un fichier csv temporaire head(iris, 3) ``` ``` ## Sepal.Length Sepal.Width Petal.Length Petal.Width Species ## 1 5.1 3.5 1.4 0.2 setosa ## 2 4.9 3.0 1.4 0.2 setosa ## 3 4.7 3.2 1.3 0.2 setosa ``` --- #### Importation depuis d'autres formats - <em>Package</em> `foreign` pour fichiers `DBF`, `STATA`, `STATA`, `SPSS`, etc. ; - <em>Package</em> `sas7bdat`, fonction `read.sas7bdat()` pour fichiers `SAS`. --- class: titre_2, center, middle ## 3.2. Exportation de données --- #### Exportation - Fonction `write.table()` ; - De nombreux paramètres modifiables (cf `?write.table`) ; - Uniquement pour des `data.frame`, `vector` ou `matrix` : ```r write.table(donnees, file = "nom_fichier.txt", sep = ";") ``` - Sauvegarder n'importe quel type d'objets : `save()` ; - Les importer dans `R` : `load()` : ```r save(d1, d2, d3, file = "nom_fichier.RData") load(load("nom_fichier.RData")) ``` - Sauvegarder la session : `save.image()`. --- class: titre_2, center, middle ## 3.3. Génération de données --- #### Génération - Génération de données : * séquences régulières, * séquences pseudo-aléatoires. --- #### Séquences régulières : seq() - Nombres également espacés : `seq()` en fournissant une valeur initiale et finale ; - Incrément défini par `by` (1 par défaut); - Longueur souhaitée : `length.out` (définit automatiquement l'incrément) ; ```r seq(1,3) ``` ``` ## [1] 1 2 3 ``` ```r seq(1,3, by = 0.5) ``` ``` ## [1] 1.0 1.5 2.0 2.5 3.0 ``` ```r seq(1,3, length.out = 10) ``` ``` ## [1] 1.000000 1.222222 1.444444 1.666667 1.888889 2.111111 2.333333 2.555556 ## [9] 2.777778 3.000000 ``` --- #### Séquences régulières : ":" - Pour des séquences dont l'incrément vaut 1, on peut utiliser l'opérateur "`:`" : ```r 1:10 ``` ``` ## [1] 1 2 3 4 5 6 7 8 9 10 ``` ```r 1.5:10 ``` ``` ## [1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5 ``` --- #### Séquences régulières : rep() - Séquence de valeur avec duplication du premier paramètre : `rep()`. ```r rep(1, 3) # Répète trois fois la valeur 1 ``` ``` ## [1] 1 1 1 ``` ```r rep(1:2, 3) # Répète trois fois la séquence 1:2 ``` ``` ## [1] 1 2 1 2 1 2 ``` ```r rep(1:2, each = 3) # Répète chaque élément de la séquence 1:2 trois fois ``` ``` ## [1] 1 1 1 2 2 2 ``` --- #### Séquences régulières : rep() ```r # Répète deux fois la séquence dans laquelle # les éléments de la séquence 1:2 sont répétés trois fois rep(1:2, 2, each = 3) ``` ``` ## [1] 1 1 1 2 2 2 1 1 1 2 2 2 ``` ```r # Répète la séquence 1:2 jusqu'à ce que # la longueur du résultat soit égale à 3 (le résultat peut être tronqué) rep(1:2, length.out = 3) ``` ``` ## [1] 1 2 1 ``` --- #### Séquences régulières : seq_len() - Pour créer une séquence allant de 1 au nombre passé au paramètre : `seq_len()`. ```r seq_len(4) ``` ``` ## [1] 1 2 3 4 ``` --- #### Séquences régulières : sequence() - Suite de nombre un peu spéciale ; - Pour <b class = "coul_1">chaque élément</b> du vecteur passé au paramètre `nvec`, une <b class = "coul_1">séquence</b> allant de 1 à la valeur de l'élément est créée ; - Les séquences créées sont ensuite <b class = "coul_1">concaténées</b>. ```r sequence(2:4) ``` ``` ## [1] 1 2 1 2 3 1 2 3 4 ``` ```r sequence(c(3,5)) ``` ``` ## [1] 1 2 3 1 2 3 4 5 ``` --- #### Séquences régulières : gl() - Générer des séries de facteurs : `gl()` ; - Deux paramètres requis : * `n` : nombre de niveaux souhaités, * `k` : nombre de réplications voulu ; - Paramètres optionnels : * `labels` : étiquettes des modalités, * `ordered` : logique indiquant si le facteur est ordonné, * `length` : longueur du résultat souhaitée. --- #### Séquences régulières : gl() ```r gl(2, 4) ``` ``` ## [1] 1 1 1 1 2 2 2 2 ## Levels: 1 2 ``` ```r gl(2, 4, length = 10) ``` ``` ## [1] 1 1 1 1 2 2 2 2 1 1 ## Levels: 1 2 ``` ```r gl(2, 4, labels = c("Oui", "Non")) ``` ``` ## [1] Oui Oui Oui Oui Non Non Non Non ## Levels: Oui Non ``` --- #### Séquences régulières : expand.grid() - Pour générer toutes les combinaisons possibles des vecteurs donnés en paramètre. ```r expand.grid(age = seq(18, 20), sexe = c("Femme", "Homme"), fumeur = c("Oui", "Non")) ``` ``` ## age sexe fumeur ## 1 18 Femme Oui ## 2 19 Femme Oui ## 3 20 Femme Oui ## 4 18 Homme Oui ## 5 19 Homme Oui ## 6 20 Homme Oui ## 7 18 Femme Non ## 8 19 Femme Non ## 9 20 Femme Non ## 10 18 Homme Non ## 11 19 Homme Non ## 12 20 Homme Non ``` --- #### Séquences pseudo-aléatoires - Génération de données suivant une distribution de probabilité donnée ; - Quatre fonctions pour chaque distribution, qui commencent par la lettre : * `r` : génération aléatoire, * `d` : densité (ou fonction de masse), * `p` : densité cumulée (ou fonction de répartition), * `q` : valeur de quantiles. --- #### Séquences pseudo-aléatoires : exemple avec la loi Normale ```r rnorm(n = 1, mean = 0, sd = 1) ``` ``` ## [1] 1.062692 ``` ```r dnorm(1) == 1/sqrt(2*pi) * exp(-1/2) ``` ``` ## [1] TRUE ``` ```r pnorm(1.96) ``` ``` ## [1] 0.9750021 ``` ```r qnorm(0.025) ; qnorm(0.975) ``` ``` ## [1] -1.959964 ``` ``` ## [1] 1.959964 ``` --- #### Séquences pseudo-aléatoires : lois de probabilités discrètes - Quelques fonctions pour les lois de probabilité discrètes : | Loi | Fonction | |-----|:---------| | Binomiale | `rbinom(n, size, prob)` | | Poisson | `rpois(n, lambda)` | | Géométrique | `rgeom(n, prob)` | | Hyper-géométrique | `rhyper(nn, m, n, k)` | | Binomiale négative | `rnbinom(n, size, prob, mu)` | --- #### Séquences pseudo-aléatoires : lois de probabilités continues - Quelques fonctions pour les lois de probabilité continues : | Loi | Fonction | |-----|:---------| | Normale | `rnorm(n, mean = 0, sd = 1)` | | Student | `rt(n, df, ncp)` | | Khi-deux | `rchisq(n, df, ncp = 0)` | | Fisher | `rf(n, df1, df2, ncp)` | | Exponentielle | `rexp(n, rate = 1)` | | Uniforme | `runif(n, min = 0, max = 1)` | | Beta | `rbeta(n, shape1, shape2, ncp = 0)` | | Logistique | `rlogis(n, location = 0, scale = 1)` | | Log-Normale | `rlnorm(n, meanlog = 0, sdlog = 1)` | | Gamma | `rgamma(n, shape, rate = 1, scale = 1/rate)` | | Weibull | `rweibull(n, shape, scale = 1)` | --- class: exo # Exercices 1. Quelle fonction utiliser pour importer un fichier `.csv`, dont les champs sont séparés par une tabulation, et dont la première ligne contient les noms de variables ? 2. Quelle(s) fonction(s) utiliser pour sauvegarder un _tibble_ en `.csv`, en séparant les champs par un point-virgule ? 3. Que retourne l'expression suivante : `c(FALSE, rep(1, 4))` ? 4. Proposer une solution pour créer un vecteur de nombres pairs allant de 0 à 10 ; 5. Générer une séquence de 10 nombres issus d'une loi normale centrée réduite ; 6. Trouver la valeur du quantile d'ordre 0.95 de la loi de Fisher à (4,26) degrés de liberté, 7. Calculer la probabilité d'obtenir une valeur plus grande que 2 lors d'un tirage selon une loi de Fisher de paramètres (4,26). --- class: inverse, center, middle # Manipulation de données <br/> <div style='text-align: center;'> <img src = "images/donnees/lego_data_1.jpg" height = "400px" title = "http://www.hotbutterstudio.com/#/alps/" /> <br/> <span class = "lien_source">Source : <a href = "http://www.hotbutterstudio.com/#/alps/">http://www.hotbutterstudio.com/#/alps/</a></span> </div> --- class: titre_2, center, middle ## 4.1. Opérateurs --- #### Opérateurs - Il existe trois sortes d'opérateurs en `R` : * <b class = "coul_1">arithmétiques</b>, * <b class = "coul_1">de comparaison</b>, * <b class = "coul_1">logiques</b>. --- #### Opérateurs arithmétiques - Les opérateurs <b class = "coul_2">arithmétiques</b> agissent sur des <b class = "coul_1">vecteurs</b> ou des <b class = "coul_1">matrices</b> ; - Ils opèrent sur des objets de type <b class = "coul_1">numérique</b>, <b class = "coul_1">complèxe</b> ou <b class = "coul_1">logique</b> ; - Les voici : * `+` : addition, * `-` : soustraction, * `*` : multiplication, * `/` : division, * `^` ou `**` : puissance, * `%%` : modulo, * `%/%` : division entière. --- #### Opérateurs arithmétiques ```r x <- c(1, 2, 3, 4, 5) ; y <- c(2, 5, 2, 8, 1) x + y # Addition ``` ``` ## [1] 3 7 5 12 6 ``` ```r x - y # Soustraction ``` ``` ## [1] -1 -3 1 -4 4 ``` ```r x * y # Multiplication ``` ``` ## [1] 2 10 6 32 5 ``` --- #### Opérateurs arithmétiques ```r x / y # Division ``` ``` ## [1] 0.5 0.4 1.5 0.5 5.0 ``` ```r x^y # Puissance ``` ``` ## [1] 1 32 9 65536 5 ``` ```r x %% y # Modulo ``` ``` ## [1] 1 2 1 4 0 ``` ```r x %/% y # Division entière ``` ``` ## [1] 0 0 1 0 5 ``` --- #### Opérateurs de comparaison - Les opérateurs de <b class = "coul_2">comparaison</b> agissent sur des <b class = "coul_1">vecteurs</b>, des <b class = "coul_1">tableaux de données</b> et des <b class = "coul_1">listes</b> ; - Le type de données n'est pas restreint comme pour les opérateurs arithmétiques ; - Les voici : * `<` : inférieur à ; * `<=` : inféfieur ou égal à ; * `>` : supérieur à ; * `>=` : supérieur ou égal à ; * `==` : égal à; * `!=` : différent de ; --- #### Opérateurs de comparaison ```r x <- seq_len(5) x < 2 # Inférieur à ``` ``` ## [1] TRUE FALSE FALSE FALSE FALSE ``` ```r x <= 2 # Inférieur ou égal à ``` ``` ## [1] TRUE TRUE FALSE FALSE FALSE ``` ```r x > 2 # Supérieur à ``` ``` ## [1] FALSE FALSE TRUE TRUE TRUE ``` --- #### Opérateurs de comparaison ```r x >= 2 # Supérieur ou égal à ``` ``` ## [1] FALSE TRUE TRUE TRUE TRUE ``` ```r x == 2 # Égal à ``` ``` ## [1] FALSE TRUE FALSE FALSE FALSE ``` ```r x != 2 # Différent de ``` ``` ## [1] TRUE FALSE TRUE TRUE TRUE ``` --- #### Opérateurs de comparaison : attention ! Attention avec l'opérateur de comparaison `==` ! Deux objets égaux pour un humain ne le sont pas forcément pour l'ordinateur, à cause de la représentation des nombres et des approximations. Voici un exemple tiré de "R pour les débutants" d'Emmanuel Paradis (2002) ```r 0.9 == (1.1 - 0.2) ``` ``` ## [1] FALSE ``` ```r all.equal(0.9, 1.1-0.2) ``` ``` ## [1] TRUE ``` ```r identical(0.9, 1.1-0.2) ``` ``` ## [1] FALSE ``` --- #### Opérateurs logiques - Les opérateurs <b class = "coul_2">logiques</b> agissent sur un ou deux objets de type <b class = "coul_1">logique</b> ; - Les opérateurs <b class = "coul_1">"ET"</b> et <b class = "coul_1">"OU"</b> existent sous deux formes : * la forme simple (`&` et `|`) : opération sur chaque élément, résultat pour chaque élément, * la forme double (`&&` et `||`) : opération uniquement sur le premier élément des objets. --- #### Opérateurs logiques ```r x <- c(TRUE, TRUE, FALSE, FALSE) ; y <- c(TRUE, FALSE, TRUE, FALSE) !x # 'Non' logique ``` ``` ## [1] FALSE FALSE TRUE TRUE ``` ```r x&y # 'Et' logique ``` ``` ## [1] TRUE FALSE FALSE FALSE ``` ```r x&&y # 'Et' logique (revient à faire x[1] & y[1]) ``` ``` ## [1] TRUE ``` --- #### Opérateurs logiques ```r x|y # 'Ou' logique ``` ``` ## [1] TRUE TRUE TRUE FALSE ``` ```r x||y # 'Ou' logique (revient à faire x[1] | y[1]) ``` ``` ## [1] TRUE ``` ```r xor(x, y) # 'Ou' exlusif ``` ``` ## [1] FALSE TRUE TRUE FALSE ``` --- #### Opérateurs logiques : deux fonctions intéressantes - Pour les vecteurs de types logiques, voici deux fonctions très utiles : * `any()` : au moins un des éléments du vecteur vaut `TRUE`, * `all()` : tous les éléments du vecteur valent `TRUE`. ```r x <- c(TRUE, FALSE) any(x) ``` ``` ## [1] TRUE ``` ```r y <- c(FALSE, FALSE) all(!y) ``` ``` ## [1] TRUE ``` --- #### Attention au recyclage - Avec une opération entre deux vecteurs de <b class = "coul_1">tailles différentes</b>, `R` effectue un <b class = "coul_1">recyclage</b> : * le vecteur de plus petite taille est <b class = "coul_1">complété</b> par ses propres valeurs, * au final, les deux vecteurs ont la même taille. ```r x <- c(1, 2, 3) y <- c(1, 2, 3, 4, 5, 6, 7) x + y ``` ``` ## Warning in x + y: la taille d'un objet plus long n'est pas multiple de la taille ## d'un objet plus court ``` ``` ## [1] 2 4 6 5 7 9 8 ``` ```r # R a ajouté le vecteur c(1, 2, 3, 1, 2, 3, 1) à y ``` --- class: exo # Exercices Soient les observations `x <- c(2, 5, 6, 3, 2)`. 1. Multiplier `x` par 10 ; 2. Normaliser les données (utiliser les fonctions `min()` et `max()`) : `$$x_i = \frac{x_i - min(x)}{max(x)-min(x)};$$` 3. Convertir les valeurs de `x` pour obtenir leur proportions (utiliser la fonction `sum()`) ; 4. Tester si les valeurs présentes appartiennent à l'ensemble `$$\{2,3,4\};$$` 5. Tester si les valeurs sont supérieures ou égales à 2 ; 6. Tester si les valeurs sont inférieures ou égales à 5 ; 7. Tester si les valeurs sont comprises entre 2 et 5 inclus. --- class: titre_2, center, middle ## 4.2. Accès aux valeurs, modifications --- #### Accès aux valeurs, modifications - `R` propose deux types d'accès aux données des différentes structures : * par <b class = "coul_1">indices</b>, * par <b class = "coul_1">noms</b>. --- class: titre_3, center, middle ## 4.2.1. Accès par indices --- #### Accès par indices (vecteurs) - Utiliation de l'indexation : * <b class = "coul_1">numérique</b>, * <b class = "coul_1">logique</b> ; - Avec la fonction `"["()` ; - Les paramètres sont les suivants : * le vecteur sur lequel on souhaite réaliser l'extraction, * un vecteur d'indices d'éléments à extraire, ou ne pas extraire, ou bien un vecteur d'éléments de type logique. --- #### Accès par indices (vecteurs) ```r x <- c(4, 7, 3, 5, 0) "["(x, 2) # Extraire le second élément de x ``` ``` ## [1] 7 ``` ```r x[2] # Une écriture plus commode pour extraire le second élément de x ``` ``` ## [1] 7 ``` ```r x[-2] # Tous les éléments de x sauf le second ``` ``` ## [1] 4 3 5 0 ``` ```r x[3:4] # Les troisième et quatrième éléments de x ``` ``` ## [1] 3 5 ``` --- #### Accès par indices (vecteurs) ```r i <- 3:4 x[i] # On peut utiliser une variable contenant un vecteur d'indices ``` ``` ## [1] 3 5 ``` ```r x[c(F, T, F, F, F)] # Le second élément de x ``` ``` ## [1] 7 ``` ```r x[x<1] # Les éléments de x inférieurs à 1 ``` ``` ## [1] 0 ``` ```r x<1 # Il s'agit bien d'un vecteur de logiques ``` ``` ## [1] FALSE FALSE FALSE FALSE TRUE ``` --- #### Accès par indices (vecteurs) : remarque - Positions des éléments `TRUE` d'un vecteur logique : `which()` ; - Position du (premier) <b class = "coul_1">minimum</b> : `which.min()` d'un vecteur logique ou numérique ; - Position du (premier) <b class = "coul_1">maximum</b> : `which.max()` d'un vecteur logique ou numérique. ```r x <- c(2, 4, 5, 1, 7, 6) which(x < 7 & x > 2) ``` ``` ## [1] 2 3 6 ``` ```r which.min(x) ``` ``` ## [1] 4 ``` --- #### Accès par indices (vecteurs) : remarque ```r which.max(x) ``` ``` ## [1] 5 ``` ```r x[which.max(x)] ``` ``` ## [1] 7 ``` --- #### Accès par indices (vecteurs) : remplacement - Utilisation de la flèche d'assignation "`->`" ; - Plusieurs éléments peuvent être modifiés en une seule instruction. ```r x <- seq_len(5) x[2] <- 3 x ``` ``` ## [1] 1 3 3 4 5 ``` ```r x[2] <- x[3] <- 0 ``` --- #### Accès par indices (vecteurs) : remplacement ```r x ``` ``` ## [1] 1 0 0 4 5 ``` ```r x[which(x == 0)] <- 10 x ``` ``` ## [1] 1 10 10 4 5 ``` --- #### Accès par indices (matrices et tableaux de données) - Utilisation de la même fonction : `"["()`, deux paramètres : `i` (lignes) et `j` (colonnes) ; - Syntaxe : `x[i, j]` ; - Omettre `i` retourne toutes les lignes pour les colonnes indicées `j`; - L'omission de `j` retourne toutes les colonnes pour les lignes indicées `i`. ```r (x <- matrix(1:9, ncol = 3, nrow = 3)) ``` ``` ## [,1] [,2] [,3] ## [1,] 1 4 7 ## [2,] 2 5 8 ## [3,] 3 6 9 ``` ```r x[1, 2] # Élément de la ligne 1 et de la colonne 2 ``` ``` ## [1] 4 ``` --- #### Accès par indices (matrices et tableaux de données) ```r i <- c(1,3) ; j <- 3 x[i,j] # Éléments des lignes 1 et 3 de la troisième colonne ``` ``` ## [1] 7 9 ``` ```r x[, 2] # Éléments de la seconde colonne ``` ``` ## [1] 4 5 6 ``` ```r x[1 ,] # Éléments de la première ligne ``` ``` ## [1] 1 4 7 ``` --- #### Accès par indices (matrices et tableaux de données) ```r x[, -c(1,3)] # x sans les colonnes 1 et 3 ``` ``` ## [1] 4 5 6 ``` - Dans ce dernier exemple, un <b class = "coul_1">vecteur</b> est retourné ; - Si on souhaite conserver une structure de <b class = "coul_1">matrice</b> : `drop = FALSE`. ```r x[, -c(1,3), drop = FALSE] ``` ``` ## [,1] ## [1,] 4 ## [2,] 5 ## [3,] 6 ``` --- #### Accès par indices (matrices et tableaux de données) - Les matrices sont des vecteurs empliés : on peut utiliser un seul paramètre à `"["()`. ```r x[c(1,3,7)] ``` ``` ## [1] 1 3 7 ``` --- #### Accès par indices (matrices et tableaux de données) : remplacement - Utilisation de la flèche d'assignation : "`->`". ```r x <- matrix(1:9, ncol = 3, nrow = 3) x[1,2] <- 0 x ``` ``` ## [,1] [,2] [,3] ## [1,] 1 0 7 ## [2,] 2 5 8 ## [3,] 3 6 9 ``` --- #### Accès par indices (matrices et tableaux de données) : remarque - `which()` sur une matrice retourne les indices sous forme de <b class = "coul_1">couples</b>. ```r which(x > 5, arr.ind = TRUE) ``` ``` ## row col ## [1,] 3 2 ## [2,] 1 3 ## [3,] 2 3 ## [4,] 3 3 ``` --- #### Accès par indices (tibbles) - La fonction `[`() peut s'utiliser sur des `tibble`, d'une manière similaire aux matrices ; - La fonction `[`() appliquée à un `tibble` retourne toujours un autre `tibble` (appliquée à un `data.frame`, cette fonction retourne un `data.frame` ou un vecteur) ```r x_t <- tibble(x = 1:3, y = 4:6, z = 7:9) x_t[1,2] # Element de la ligne 1 et de la colonne 2 ``` ``` ## # A tibble: 1 x 1 ## y ## <int> ## 1 4 ``` ```r x_t[c(1,3), 3] # Éléments des lignes 1 et 3 de la troisième colonne ``` ``` ## # A tibble: 2 x 1 ## z ## <int> ## 1 7 ## 2 9 ``` --- #### Accès par indices (tibbles) ```r x_t[,2] # Éléments de la seconde colonne ``` ``` ## # A tibble: 3 x 1 ## y ## <int> ## 1 4 ## 2 5 ## 3 6 ``` ```r x_t[, -c(1,3)] # x_t sans les colonnes 1 et 3 ``` ``` ## # A tibble: 3 x 1 ## y ## <int> ## 1 4 ## 2 5 ## 3 6 ``` --- #### Accès par indices (tibbles) : remplacement Le remplacement de valeur peut s'effectuer comme avec un matrice, à l'aide de la flèche : ```r x_t[1,2] <- 0 x_t ``` ``` ## # A tibble: 3 x 3 ## x y z ## <int> <int> <int> ## 1 1 0 7 ## 2 2 5 8 ## 3 3 6 9 ``` --- #### Accès par indices (vecteurs logiques) - Au lieu des indices, on peut utiliser des <b class = "coul_1">vecteurs logiques</b>. ```r (x_logique <- matrix(c(TRUE, FALSE), ncol = 3, nrow = 3)) ``` ``` ## Warning in matrix(c(TRUE, FALSE), ncol = 3, nrow = 3): la longueur des données ## [2] n'est pas un diviseur ni un multiple du nombre de lignes [3] ``` ``` ## [,1] [,2] [,3] ## [1,] TRUE FALSE TRUE ## [2,] FALSE TRUE FALSE ## [3,] TRUE FALSE TRUE ``` ```r x[x_logique] ``` ``` ## [1] 1 3 5 7 9 ``` --- #### Accès par indices (tableaux) - Autant de paramètres à `"["()` que de dimensions dans le tableau. ```r z <-array(1:24, dim =c(2, 4, 3)) z[2,4,3] # Élément de la ligne 2, colonne 4 de la dimension 3 ``` ``` ## [1] 24 ``` --- #### Accès par indices (listes) - À nouveau la fonction `"["()` ; - Le résultat est une liste. ```r personne <- list("Piketty", "Thomas", "1971") personne[1] ``` ``` ## [[1]] ## [1] "Piketty" ``` ```r personne[c(1,3)] ``` ``` ## [[1]] ## [1] "Piketty" ## ## [[2]] ## [1] "1971" ``` --- #### Accès par indices (listes) - L'accès au <b class = "coul_1">contenu</b> d'un ou plusieurs éléments d'une liste se fait avec `"[["()`. ```r "[["(personne, 1) # Premier élément de la liste ``` ``` ## [1] "Piketty" ``` ```r personne[[1]] # idem ``` ``` ## [1] "Piketty" ``` ```r personne[[1,2]] # Ne fonctionne pas ``` ``` ## Error in personne[[1, 2]]: nombre d'indices incorrect ``` --- #### Accès par indices (listes) ```r personne[[c(1,2)]] # Ne fonctionne pas non plus ici ``` ``` ## Error in personne[[c(1, 2)]]: indice hors limites ``` ```r personne[1,2] # Ne fonctionne pas ``` ``` ## Error in personne[1, 2]: nombre de dimensions incorrect ``` --- #### Accès par indices (listes) ```r personne[c(1,2)] # Retourne une liste de dim 2 contenant : ``` ``` ## [[1]] ## [1] "Piketty" ## ## [[2]] ## [1] "Thomas" ``` ```r # - le premier élément de la liste # - le second élément de la liste ``` --- #### Accès par indices (listes) - Indexation récursive. ```r (l <- list("foo_1", "foo_2", c("foo_3", "foo_4"))) ``` ``` ## [[1]] ## [1] "foo_1" ## ## [[2]] ## [1] "foo_2" ## ## [[3]] ## [1] "foo_3" "foo_4" ``` ```r l[[3]] # Troisième élément de la liste ``` ``` ## [1] "foo_3" "foo_4" ``` --- #### Accès par indices (listes) ```r l[[c(3,1)]] # Premier élément du troisième élément ``` ``` ## [1] "foo_3" ``` ```r l[[3]][1] # Premier élément du troisième élément ``` ``` ## [1] "foo_3" ``` --- #### Accès par indices (listes) : remplacement - À nouveau avec la flèche d'assignation "`->`". ```r l <- list(1, TRUE, "foo", list(matrix(1:4, ncol = 2), "foo_2")) l[[4]] <- 2 l # La liste en position 4 a été remplacée par un vecteur de longueur 1 ``` ``` ## [[1]] ## [1] 1 ## ## [[2]] ## [1] TRUE ## ## [[3]] ## [1] "foo" ## ## [[4]] ## [1] 2 ``` --- class: titre_3, center, middle ## 4.2.2. Accès par noms --- #### Accès par noms (vecteurs) - Lorsque les éléments d'un vecteur sont nommés ; - Avec la fonction `"["`. ```r personne <- c(nom = "Piketty", prenom = "Thomas", "annee de naissance" = "1971") personne["nom"] ``` ``` ## nom ## "Piketty" ``` ```r names(personne) # Accès aux noms des éléments du vecteur ``` ``` ## [1] "nom" "prenom" "annee de naissance" ``` --- #### Accès par noms (vecteurs) ```r names(personne) <- c("nom", "prenom", "naissance") # Modification des noms personne personne ``` ``` ## nom prenom naissance ## "Piketty" "Thomas" "1971" ``` ```r names(personne) <- NULL # Suppression des noms personne ``` ``` ## [1] "Piketty" "Thomas" "1971" ``` --- #### Accès par noms (listes, tableaux de données) - Utilisation de `"["()` (et `"[["()` pour les listes) possible ; - Utilisation de "`$`" également. ```r personne_liste <- list('nom de famille' = "Piketty", prenom = "Thomas", annee = 1971) personne_liste[["nom de famille"]] ``` ``` ## [1] "Piketty" ``` --- #### Accès par noms (listes, tableaux de données) ```r personne_liste$"nom de famille" # Le nom contenant au moins une espace, ``` ``` ## [1] "Piketty" ``` ```r # Il est nécessaire d'employer des guillemets personne_liste$prenom ``` ``` ## [1] "Thomas" ``` ```r names(personne_liste) # Accès aux noms des éléments de la liste ``` ``` ## [1] "nom de famille" "prenom" "annee" ``` --- #### Accès par noms (matrices, tableaux de données) - <b class = "coul_1">Nommer</b> les lignes et les colonnes : `rownames()` et `colnames()` ; - La fonction `dimnames()` retourne une liste dont les éléments sont : * une liste contenant le vecteur des noms de lignes, * une liste contenant le vecteur des noms de colonnes. ```r femmes <-data.frame(height =c(58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,69, 70, 71, 72), weight =c(115, 117, 120, 123, 126, 129, 132, 135, 139,142, 146, 150, 154, 159, 164)) colnames(femmes) ``` ``` ## [1] "height" "weight" ``` --- #### Accès par noms (matrices, tableaux de données) ```r rownames(femmes) ``` ``` ## [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" ``` ```r dimnames(femmes) ``` ``` ## [[1]] ## [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" ## ## [[2]] ## [1] "height" "weight" ``` --- #### Accès par noms (matrices, tableaux de données) : remplacement - Encore une fois, on utilise la flèche d'assignation "`->`" ; - Un message d'erreur apparaît (et le remplacement n'a pas lieu) si l'objet de remplacement n'est pas de la bonne longueur (pour les tableaux de données). ```r df <- data.frame(x = seq_len(3), y = rep(2,3), z = c(1,4,3)) df$x <- rep(NA, 3) ; df ``` ``` ## x y z ## 1 NA 2 1 ## 2 NA 2 4 ## 3 NA 2 3 ``` ```r tb <- tibble(x = seq_len(3), y = rep(2,3), z = c(1,4,3)) tb$x <- rep(NA,3) ; tb ``` ``` ## # A tibble: 3 x 3 ## x y z ## <lgl> <dbl> <dbl> ## 1 NA 2 1 ## 2 NA 2 4 ## 3 NA 2 3 ``` --- #### Accès par noms (matrices, tableaux de données) : remplacement ```r df$x <- rep(1, 4) ; df # La modification n'a pas été faite ``` ``` ## Error in `$<-.data.frame`(`*tmp*`, x, value = c(1, 1, 1, 1)): replacement has 4 rows, data has 3 ``` ``` ## x y z ## 1 NA 2 1 ## 2 NA 2 4 ## 3 NA 2 3 ``` ```r tb$x <- rep(1,4) ; tb ``` ``` ## Error: Assigned data `rep(1, 4)` must be compatible with existing data. ## x Existing data has 3 rows. ## x Assigned data has 4 rows. ## ℹ Only vectors of size 1 are recycled. ``` ``` ## # A tibble: 3 x 3 ## x y z ## <lgl> <dbl> <dbl> ## 1 NA 2 1 ## 2 NA 2 4 ## 3 NA 2 3 ``` --- #### Accès par noms (matrices, tableaux de données) : remplacement ```r # Attention is.list(df$x) ``` ``` ## [1] FALSE ``` ```r df$x <- list(4,3,2) df$x # La colonne "x" a changé de structure ! ``` ``` ## [[1]] ## [1] 4 ## ## [[2]] ## [1] 3 ## ## [[3]] ## [1] 2 ``` --- class: exo # Exercices 1. Extraire le troisième élément du vecteur `x <-c(3, 5, 6, 9)` ; 2. Extraire les éléments supérieurs à 5 ; 3. Extraire les éléments qui ne sont pas dans l'intervalle \([1,3]\) ; 4. Déterminer le maximum du vecteur `x` et donner sa position ; 5. Remplacer ce maximum par le minimum ; 6. Remplacer par la valeur `NA` les éléments négatifs de la matrice suivante : `$$\begin{bmatrix}1 & -1 & 5 \\ 5 & 7 & -9 \end{bmatrix};$$` 7. Extraire la deuxième colonne de la matrice obtenue à l'issue de la question 6 ; 8. Extraire le 3e élément de la liste suivante : `L <- list(rnorm(10), LETTERS[1:26], month.abb)` ; 9. Extraire tous les éléments de la liste `L` sauf le second. --- class: exo # Exercices (suite) 10. Extraire le troisième élément de la liste `L`, en utilisant le nom de l'élément. `L <- list(nombre = rnorm(10), lettre = LETTERS[1:26], mois = month.abb)` ; 11. Toujours en accédant par le nom, ajouter la valeur `10` aux valeurs du premier élément de `L`. Le résultat doit altérer `L` ; 12. Afficher les valeurs de la variable `y` du tibble `tb` : `tb <- tibble(x = 1:10, y = letters[1:10], z = rev(letters[1:10]))` ; 13. Afficher uniquement les colonnes `x` et `z` du tibble `tb`. --- class: titre_2, center, middle ## 4.3. Manipulation des chaînes de caractères --- class: titre_3, center, middle ### 4.3.1. Concaténation --- #### La fonction `cat()` - Concaténer et afficher à l'écran : `cat()` ; - Les paramètres fournis sont convertis en vecteurs de chaînes de caractères ; - Ces vecteurs sont ensuite concaténés en un seul, avec une espace entre chaque ; - L'espace peut être remplacée par ce que l'utilisateur souhaite, en jouant avec `sep`. ```r cat("Hello", "World", "!") ``` ``` ## Hello World ! ``` --- #### La fonction `cat()` - En ajoutant un passage à la ligne entre chaque élément ```r cat("Hello", "World", "!", sep = "\n") ``` ``` ## Hello ## World ## ! ``` - Avec une matrice : ```r cat(matrix(1:6)) ``` ``` ## 1 2 3 4 5 6 ``` --- #### La fonction `cat()` : remarque - Le caractère `\` sert d'échappement en `R` ; - Il permet d'afficher certains caractères : | Caractère | Description | Caractère | Description | | ----------|-------------------------|-----------|-------------------| | `\n` | Nouvelle ligne | `\r` | Retour à la ligne | | `\t` | Tabulation |`\b` | Retour arrière | | `\\` | Barre olbique inversée | `\'` | Apostrophe | | `\"` | Apostrophe double |`\‘` | Accent grave | --- #### La fonction `str_c()` - Nécessité de charger le <em>package</em> `stringr` - La fonction `str_c()` convertit les éléments passés en caractères ; - Elle les concatène ; - Le résultat est une chaîne de caractères ; - Le résultat peut être sotcké avec la flèche d'assignation "`<-`" ; - Une chaîne de séparation peut être définie à l'aide du paramètre `sep`. ```r library(stringr) x <- str_c("Hello", "World", "!", sep = " ") x ``` ``` ## [1] "Hello World !" ``` --- #### La fonction `str_c()` - Le paramètre `collapse` permet de joindre les éléments d'un vecteur dans une même chaîne. ```r str_c(c("Rennes", "Bretagne")) ``` ``` ## [1] "Rennes" "Bretagne" ``` ```r # Il n'y a qu'un paramètre, donc le séparateur est inutile ! str_c(c("Rennes", "Bretagne"), sep = ", ") ``` ``` ## [1] "Rennes" "Bretagne" ``` ```r # En ajoutant le paramètre collapse str_c(c("Rennes", "Bretagne"), collapse = ", ") ``` ``` ## [1] "Rennes, Bretagne" ``` --- #### La fonction `str_c()` - Les règles de recyclage s'appliquent. ```r str_c("Hello", c("Julien-Yacine", "Sonia", "Victor")) ``` ``` ## [1] "HelloJulien-Yacine" "HelloSonia" "HelloVictor" ``` - Les valeurs `NA` sont converties en chaîne `"NA"`... ```r str_c("Hello", NA) ``` ``` ## [1] NA ``` --- #### La fonction `str_c()` : remarque - La fonction `get()` retourne le contenu d'une variable dont on lui indique le nom sous forme de chaîne de caractères. ```r variable_1 <- 5 # Affiche la chaîne "variable_1" str_c("variable_", 1) ``` ``` ## [1] "variable_1" ``` ```r # Affiche le contenu de la variable nommée "variable_1" get(str_c("variable_", 1)) ``` ``` ## [1] 5 ``` --- class: titre_3, center, middle ### 4.3.2. Conversion en majuscules ou minuscules --- #### Conversion en majuscules ou minuscules - Majuscule : `toupper()`; - Minuscule : `tolower()` ; ```r x <- "Bonjour !" toupper(x) ``` ``` ## [1] "BONJOUR !" ``` ```r tolower(x) ``` ``` ## [1] "bonjour !" ``` --- #### Conversion en majuscules ou minuscules - La fonction `casefold()` fait les deux : on lui indique un logique pour son paramètre `upper`. ```r casefold(x) ``` ``` ## [1] "bonjour !" ``` ```r casefold(x, upper = TRUE) ``` ``` ## [1] "BONJOUR !" ``` --- class: exo # Exercices 1. Créer le vecteur de chaînes commençant par `joueur_` et se terminant par un entier `i` allant de `1 à 10` ; 2. Créer la chaîne composée des deux sous-chaînes `Criquette Rockwell` et `Brett Montgomery`, séparées par un retour à la ligne. Afficher le résultat dans la console avec la fonction `cat()` ; 3. Créer la chaîne `J'aime les pommes - "Ryuk"`, et stocker le résultat dans l'objet `light` ; 4. Passer la chaîne de la question 3 (`light`) en majuscules ; 5. Afficher le contenu de `light` en faisant appel à la fonction `get()`. --- class: titre_3, center, middle ### 4.3.3. Compter le nombre de caractères d'une chaîne --- #### Compter le nombre de caractères d'une chaîne - La fonction `str_length()` retourne le nombre de caractères d'une chaîne. ```r str_length("Bonjour") ``` ``` ## [1] 7 ``` ```r str_length(c("Bonjour", "Hello")) ``` ``` ## [1] 7 5 ``` --- class: titre_3, center, middle ### 4.3.4. Extraction et remplacement de sous-chaines --- #### Extraction et remplacement de sous-chaines - <b class = "coul_1">Extraction</b> en précisant la position de début et de fin : `str_sub()` ; - Attention, le premier caractère d'une chaîne est en position 1 en `R`. ```r x <- "Debt is one person's liability, but another person's asset." str_sub(x, 1, 4) ``` ``` ## [1] "Debt" ``` - Le <b class = "coul_1">remplacement</b> se fait avec la flèche d'assignation "`<-`" ; - Le remplacement d'une chaîne par une autre plus longue ne pose pas de problème. ```r str_sub(x, 1, 4) <- "Remplacement" x ``` ``` ## [1] "Remplacement is one person's liability, but another person's asset." ``` --- #### Extraction et remplacement de sous-chaines : remarques - Le paramètre `x` de `str_sub()` peut être un vecteur ; - La fonction est alors appliquée à chaque élément du vecteur. ```r str_sub(c("Rouge", "Vert", "Bleu"), 2, 3) ``` ``` ## [1] "ou" "er" "le" ``` - Les règles de recyclage s'appliquent. ```r x <- c("Rouge", "Vert", "Bleu") str_sub(x, 2, 3) <- c("!!", "@@") ``` ``` ## Warning in `stri_sub<-`(`*tmp*`, from = start, to = end, omit_na = omit_na, : ## longer object length is not a multiple of shorter object length ``` ```r x ``` ``` ## [1] "R!!ge" "V@@t" "B!!u" ``` --- #### Extraction et remplacement de sous-chaines : remarques - Si le paramètre `start` (`end`) est négatif, le décompte des positions se fait à partir du dernier caractère de la liste. ```r texte <- "le train de tes injures roule sur le rail de mon indifférence" str_sub(string = texte, start = -12, end = -1) ``` ``` ## [1] "indifférence" ``` --- class: titre_3, center, middle ### 4.3.5. Recherche de chaînes de caractères --- #### Recherche de chaînes de caractères - Recherche d'un <b class = "coul_1">motif</b> (<em>pattern</em>) dans un vecteur de chaînes de caractères : `str_detect()` ; - Retourne une chaîne de booléens de la longueur du vecteur de chaînes fourni en paramètre. ```r str_detect(string = c("Pomme", "Poire", "Ananas"), pattern = "o") ``` ``` ## [1] TRUE TRUE FALSE ``` --- #### Recherche de chaînes de caractères - Le remplacement par une autre chaîne de la <b class = "coul_1">première</b> occurence du motif trouvé se fait avec `str_replace()` ; - La chaîne de remplacement n'est pas tenue d'avoir la même longueur que le motif. ```r str_replace(string = c("Pomme", "Poire", "Ananas"), pattern = "a", replacement = "@@") ``` ``` ## [1] "Pomme" "Poire" "An@@nas" ``` - Pour remplacer <b class = "coul_1">toutes</b> les occurences trouvées : `str_replace_all()`. ```r str_replace_all(string = c("Pomme", "Poire", "Ananas"), pattern = "a", replacement = "@@") ``` ``` ## [1] "Pomme" "Poire" "An@@n@@s" ``` --- #### Recherche de chaînes de caractères - Pour ignorer la casse, il faut utiliser la fonction `regex()` sur le motif en indiquant `TRUE` pour l'argument `ignore_case` : ```r str_detect(string = c("Obi-Wan Kenobi", "Darth Vader"), pattern = "w") ``` ``` ## [1] FALSE FALSE ``` ```r str_detect(string = c("Obi-Wan Kenobi", "Darth Vader"), pattern = regex("w", ignore_case = TRUE)) ``` ``` ## [1] TRUE FALSE ``` --- #### Recherche de chaînes de caractères - On peut utiliser le symbole `|` à l'intérieur de la chaîne de caractère passée au paramètre `pattern` pour détecter la présence d'un motif ou d'un autre dans la chaîne de caractères. ```r str_detect(string = c("Obi-Wan Kenobi", "Darth Vader"), pattern = "w|D") ``` ``` ## [1] FALSE TRUE ``` --- #### Recherche de chaînes de caractères - La <b class = "coul_1">découpe</b> d'une chaîne en fonction d'un motif se fait avec `str_split()`. ```r x = "Criquette ! Vous, ici ? Dans votre propre salle de bain ? Quelle surprise !" str_split(string = x, pattern = " ") ``` ``` ## [[1]] ## [1] "Criquette" "!" "Vous," "ici" "?" "Dans" ## [7] "votre" "propre" "salle" "de" "bain" "?" ## [13] "Quelle" "surprise" "!" ``` --- class: exo # Exercices 1. Quelle fonction utiliser pour connaître le nombre de caractères d'une chaîne ? 2. Extraire `c("LON-1.6794", "LAT48.1147")` les valeurs numériques de longitue et latitude ; 3. Dans la chaîne `LON-1.6794`, remplacer `LON` par `LONG` ; 4. Repérer les éléments du vecteur `c("Finistere:I. d'Ouessant", "Finistere:I. de Batz", "Gard")` qui contiennent la sous-chaîne `finistere`, en ne tenant pas compte de la casse ; 5. Remplacer toutes les occurences de tirets (`-`) par une espace dans les éléments du vecteur `c("02-23-23-35-35", "02-23-23-35-45")` ; 6. Découper les numéros de téléphone `c("02-23-23-35-35", "02/23/23/35/45")` en fonction du tiret ou de la barre oblique. --- #### La fonction : `str_dup()` - Duplication de texte : `str_dup()`. ```r texte <- c("bla", "ah", "eh") str_dup(texte, 2) ``` ``` ## [1] "blabla" "ahah" "eheh" ``` ```r str_dup(texte, 1:3) ``` ``` ## [1] "bla" "ahah" "eheheh" ``` --- #### La fonction : `str_pad()` - Complétion d'une chaîne de caractères pour obtenir une chaîne avec une longueur donnée ; - La longueur désirée se fixe avec le paramètre `width` ; - Choix du côté pour la complétion : avec le paramètre `side` qui prend les valeurs `left`, `right` ou `both` ; ```r coords <- c(lat = "48.11", long = "-1.6794") str_pad(string = coords, width = 7, side = "left", pad = " ") ``` ``` ## [1] " 48.11" "-1.6794" ``` - Les chaînes plus longues que la valeur fournie à width sont inchangées. ```r str_pad(c("Gauthier", "Pascaline"), 3) ``` ``` ## [1] "Gauthier" "Pascaline" ``` --- #### La fonction : `str_trim()` - Retrait des caractères blancs (espaces, sauts de ligne, retours à la ligne, quadratins, etc.) : `str_trim()` ; - On peut choisir le côté sur lequel faire le retrait, avec le paramètre `side` (`left`, `right` ou `both`). ```r texte <- c("\n\nPardon, du sucre ?", "Oui, seize \n ", "...\t\t...\t") str_trim(texte, side = "both") ``` ``` ## [1] "Pardon, du sucre ?" "Oui, seize" "...\t\t..." ``` --- #### La fonction : `word()` - Extraction de mots dans une phrase : `word()` ; - La séparation entre les mots est l'espace par défaut ; - Le paramètre `sep` permet de changer le caractère unissant les mots ; - Le paramètre `sart` attend un entier indiquant la position du premier mot à extraire (1 par défaut) ; - Leparamètre `end` attend un entier indiquant la position du dernier mot à extraire. ```r phrase <- c("Mademoiselle Deray, il est interdit de manger de la choucroute ici.", "Oh si si, prenez un chewing-gum, Émile.") ``` --- #### La fonction : `word()` ```r word(phrase) # Extraction du premier mot ``` ``` ## [1] "Mademoiselle" "Oh" ``` ```r word(phrase, 2, -1) # Extraction du second au dernier mot ``` ``` ## [1] "Deray, il est interdit de manger de la choucroute ici." ## [2] "si si, prenez un chewing-gum, Émile." ``` - Si `start` reçoit une valeur négative, le décompte s'effectue de la droite vers la gauche ; ```r word(phrase, -1) # Extraction du dernier mot ``` ``` ## [1] "ici." "Émile." ``` --- #### La fonction : `word()` ```r # Du premier au dernier mot, du second au dernier, et du troisième au dernier # pour le premier élément de phrase word(phrase[1], 1:3, -1) ``` ``` ## [1] "Mademoiselle Deray, il est interdit de manger de la choucroute ici." ## [2] "Deray, il est interdit de manger de la choucroute ici." ## [3] "il est interdit de manger de la choucroute ici." ``` ```r # Premier mot, Premier et second mot, Premier et troisième mot # pour le second élément de phrase word(phrase[2], 1, 1:3) ``` ``` ## [1] "Oh" "Oh si" "Oh si si," ``` --- class: titre_2, center, middle ## 4.4. Dates --- class: titre_3, center, middle ### 4.4.1. Extraction des éléments d'une date --- #### Extraction : fonctions de {`lubridate`} | Fonction | Extraction | |----------|------------| | `second()` | secondes (0–59) | | `minute()` | minutes (0–59) | | `hour()` | heures (0–23) | | `day()`, `mday()` | jour du mois (1–31) | | `wday()` | jour de la semaine (1–7), le dimanche étant le 1 | | `yday()` | jour de l'année (1–366) | | `week()` | numéro de la semaine dans l'année. Les semaines sont définies comme les pé- riodes complètes de 7 jours s'étant déroulées depuis le premier janvier, plus 1 | | `isoweek()` | Semaine de l'année (00-53). Si la semaine (qui commence un lundi) qui contient le 1er janvier a 4 jours ou plus dans la nouvelle année, alors elle est considérée comme la semaine 1. Sinon, elle est considérée comme la dernière de l'année précédente, et la suivante est considérée comme semaine 1 | | `month()` | mois (1–12) | | `year()` | année, uniquement celles après l'an 1 | | `tz()` | fuseau horraire | --- #### Extraction : fonctions de {`lubridate`} - Avec `wday()` et `month()`, il est possible de récupérer le <b class="coul_2>nom</b> du jour de la semaine ou du mois, en précisant `TRUE` à l'argument `label` : ```r wday(ymd("2020-03-17"), label = TRUE, abbr = FALSE) ``` ``` ## [1] Mardi ## 7 Levels: Dimanche < Lundi < Mardi < Mercredi < Jeudi < ... < Samedi ``` ```r month(ymd("2020-05-11"), label = TRUE, abbr=FALSE) ``` ``` ## [1] mai ## 12 Levels: janvier < février < mars < avril < mai < juin < juillet < ... < décembre ``` On peut noter que l'élément retourné est un facteur ordonné. --- #### Extraction : fonctions de {`lubridate`} et langues - Si on désire extraire ces noms dans une autre langue, on peut jouer avec l'argument `local` - Il suffit de préciser le nom du local... mais celui-ci est spécifique au système... - Sous Unix : ```r wday(ymd("2020-03-17"), label = TRUE, abbr = FALSE, locale = "en_US") ``` ``` ## [1] Tuesday ## 7 Levels: Sunday < Monday < Tuesday < Wednesday < Thursday < ... < Saturday ``` - Sous Windows: ```r wday(ymd("2020-03-17"), label = TRUE, abbr = FALSE, locale = "english_us") ``` --- #### Extraction : fonctions de {`lubridate`} et langues - Pour afficher les différents noms disponibles, <b class="coul_1">sous Unix</b>, on peut évaluer une commande système directement depuis R : ```r system("locale -a", intern = TRUE) ``` - <b class="coul_1">Sous Windows</b>, la liste des noms est disponible sur la documentation en ligne de Microsoft : il faut chercher dans un moteur de recherche l'expression : `"MSDN Language Strings"` (comme indiqué sur [cette réponse](https://stackoverflow.com/a/26604195) sur StakOverflow) --- #### Extraction : cas particuliers - Certaines dates ne correspondent à <b class="coul_2">aucune norme reconnue</b> par {`lubridate`} ; - Les fonctions de type `ymd_hms()` ne parviendront pas à reconnaître le format ; - Toutefois, il est possible de convertir ces dates avec `parse_date_time()` de {`lubridate`} - Exemple : on dispose de cette date : ```r x <- "Fri Dec 25 20:12:00 +0001 2020" ``` - L'<b class="coul_2">ordre</b> des éléments est le suivant : - `%b` : abréviation du jour de la semaine, - `%m` : abréviation du mois de l'année, - `%d` : jour du mois, - ... - Les abréviations sont en anglais --- #### Extraction : cas particuliers - On renseigne alors les arguments suivants dans la fonction `parse_date_time()` : - `orders` : une chaîne de caractères précisant l'ordre des éléments de la date - `locale` : le loal à utiliser (ici, un local anglais) - Cela donne : ```r parse_date_time(x, orders = "%a %b %d %H:%M:%S %z %Y", locale = "en_US") ``` ``` ## [1] "2020-12-25 20:11:24 UTC" ``` --- class: titre_3, center, middle ### 4.4.2. Opérations sur les dates --- #### Opérations - Pour les exemples, créons des objets de chaque type de dates. ```r d_date_1 <- ymd("2019-09-01") d_date_2 <- ymd("2020-10-21") class(d_date_1) ``` ``` ## [1] "Date" ``` ```r d_posix_ct_1 <- ymd_hms("2020-03-17 12:32:28") d_posix_ct_2 <- ymd_hms("2020-05-11 13:55:44") class(d_posix_ct_1) ``` ``` ## [1] "POSIXct" "POSIXt" ``` --- #### Opérations : ajout et retrait de temps - Rappel : les dates sont stockées de manières différentes selon leur mode : - `Date` : en <b class="coul_2">nombre de jours</b> depuis le premier janvier 1970, - `POSIXct` : en <b class="coul_2">nombre de secondes</b> depuis le premier janvier 1970 ; - Si on ajoute un nombre à une date, cela ajoutera ce nombre en jours ou en secondes selon le mode de l'objet qui contient la date ; - Avec des `Date` : ```r d_date_2 ``` ``` ## [1] "2020-10-21" ``` ```r d_date_2 + 10 ``` ``` ## [1] "2020-10-31" ``` ```r d_date_2 - 10 ``` ``` ## [1] "2020-10-11" ``` --- #### Opérations : ajout et retrait de temps - Avec des `POSIXct` : ```r d_posix_ct_2 ``` ``` ## [1] "2020-05-11 13:55:44 UTC" ``` ```r d_posix_ct_2 + 10 ``` ``` ## [1] "2020-05-11 13:55:54 UTC" ``` ```r d_posix_ct_2 - 10 ``` ``` ## [1] "2020-05-11 13:55:34 UTC" ``` --- #### Opérations : comparaison de dates - Comme les dates sont stockées en durées en secondes ou jours depuis le 1er janvier 1970, il est possible de les <b class="coul_2">comparer facilement</b>, à l'aide des <b class="coul_2">opérateurs logiques</b>. ```r d_date_1 > d_date_2 ``` ``` ## [1] FALSE ``` ```r d_posix_ct_2 > d_posix_ct_1 ``` ``` ## [1] TRUE ``` ```r d_posix_ct_2 == d_posix_ct_1 ``` ``` ## [1] FALSE ``` --- class: titre_3, center, middle ### 4.4.3. Intervalles de dates --- #### Intervalles de dates - <b class="coul_2">Intervalle de dates</b> avec `interval()` de {`lubridate`} ; - Possible d'utiliser l'opérateur `%--%`; ```r debut <- ymd_hms("2020-03-17 07:00:00", tz = "Australia/Perth") fin <- ymd_hms("2020-05-11 23:00:00", tz = "Australia/Perth") (intervalle_1 <- interval(debut, fin)) ``` ``` ## [1] 2020-03-17 07:00:00 AWST--2020-05-11 23:00:00 AWST ``` ```r debut %--% fin ``` ``` ## [1] 2020-03-17 07:00:00 AWST--2020-05-11 23:00:00 AWST ``` --- #### Intervalles de dates : durée - La fonction `int_length()` de {`lubridate`} donne un <b class="coul_2">intervalle exprimé en secondes</b> ```r int_length(intervalle_1) ``` ``` ## [1] 4809600 ``` -- - Comment exprimer cette durée dans un format plus compréhensible par un humain ? - Nous devons faire un détour pour expliquer la différence entre deux notions : - les <b class="coul_2">durées</b> (_durations_), - les <b class="coul_2">époques</b> (_periods_). --- #### Intervalles de dates : durée et époques - Les <b class="coul_1">_durations_</b> ne tiennent pas en compte des <b class="coul_2">fluctuations de la ligne du temps</b>, (e.g., les années bissextiles) ; - Les <b class="coul_1">_periods_</b> si ; - Syntaxe des fonctions : - _durations_ : préfixe `d` immédiatement suivi du nom de la durée - _periods_ : nom de la durée ```r minutes(10) ``` ``` ## [1] "10M 0S" ``` ```r dminutes(10) ``` ``` ## [1] "600s (~10 minutes)" ``` --- #### Intervalles de dates : durée et époques - Exemple de différence entre _durations_ et _periods_: ajout d'un an à l'anné 2000 (qui était bissextile) : ```r leap_year(2000) # 2000 était une année bissextile ``` ``` ## [1] TRUE ``` - Ajout d'une <b class="coul_2">durée</b> d'un an, soit 365 jours ```r ymd("2000-01-01") + dyears(1) ``` ``` ## [1] "2000-12-31 06:00:00 UTC" ``` - Ajout d'une <b class="coul_2">période</b> d'un an, soit 366 jours dans ce cas ```r ymd("2000-01-01") + years(1) ``` ``` ## [1] "2001-01-01" ``` --- #### Intervalles de dates - On peut répondre à notre questionnement initial : Comment exprimer la durée d'un intervalle de temps dans un format plus compréhensible par un humain ? - Il suffit de <b class="coul_2">diviser le résultat retourné par `interval` par une durée ou une époque</b> : ```r intervalle <- interval(ymd_hms("2020-03-17 10:00:00"), ymd_hms("2020-05-11 08:00:00")) # Nombre de jours de confinement durant la pandémie de Covid-19 intervalle / ddays(1) ``` ``` ## [1] 54.91667 ``` ```r # Nombre de durées de 2 jours intervalle / ddays(2) ``` ``` ## [1] 27.45833 ``` ```r # Nombre d'heures intervalle / dhours(1) ``` ``` ## [1] 1318 ``` --- #### Intervalles de dates : tableau des durées | Fonction | Description | | :---------- | :------------- | | dseconds() | Secondes | | dminutes() | Minutes | | dhours() | Heures | | ddays() | Jours | | dweeks() | Semaines | | dmonths() | Mois | | dyears() | Années | | dmilliseconds() | Milisecondes | | dmicroseconds() | Microsecondes | | dnanoseconds() | Nanosecondes | | dpicoseconds() | Picosecondes | --- class: titre_3, center, middle ### 4.4.4. Séquences de dates --- - La fonction `seq()` de {`base`} peut être utilisée pour <b class="coul_2">générer des séquences de dates</b> (ce qui est notamment utile lorsque l'on réalise des graphiques) ; - Cela fonctione avec des dates au formats `date`, `POSIXct` ou `POSIXlt`; - Avec des objets de class date : ```r seq(ymd("2020-09-01"), length = 4, by = "day") ``` ``` ## [1] "2020-09-01" "2020-09-02" "2020-09-03" "2020-09-04" ``` - Tous les deux jours ```r seq(ymd("2020-09-01"), length = 4, by = "2 days") ``` ``` ## [1] "2020-09-01" "2020-09-03" "2020-09-05" "2020-09-07" ``` - En spécifiant le début et la date maximum ```r seq(ymd("2020-09-01"), ymd("2020-09-08") , by = "2 days") ``` ``` ## [1] "2020-09-01" "2020-09-03" "2020-09-05" "2020-09-07" ``` - Avec des objets de classe POSIXct ```r seq(ymd_hms("2020-03-17 12:32:28 "), by = "9 months", length = 2) ``` ``` ## [1] "2020-03-17 12:32:28 UTC" "2020-12-17 12:32:28 UTC" ``` --- class: titre_3, center, middle ### 4.4.5. Fuseaux horaires --- #### Fuseaux horaires - Convertir des dates dans un autre <b class="coul_2">fuseau horaire</b> : `with_tz()` de {`lubridate`} ; - Exemple : une heure à Paris : ```r (d <- ymd_hms("2020-10-30 20:00:00", tz = "Europe/Paris")) ``` ``` ## [1] "2020-10-30 20:00:00 CET" ``` - L'heure équivalente à Abdijan : ```r with_tz(d, "Africa/Abidjan") ``` ``` ## [1] "2020-10-30 19:00:00 GMT" ``` --- #### Fuseaux horaires - La fonction `force_tz()` permet de <b class="coul_2">remplacer le fuseau horaire d'une date</b> ; - Cela ne change pas la _valeur_ de la date, uniquement le fuseau horaire : ```r (d <- ymd_hms("2020-10-30 20:00:00", tz = "Europe/Paris")) ``` ``` ## [1] "2020-10-30 20:00:00 CET" ``` ```r (d <- force_tz(d, "Africa/Abidjan")) ``` ``` ## [1] "2020-10-30 20:00:00 GMT" ``` - Pour rappel, l'ensemble des fuseaux horaires disponibles est donné à l'aide de la fonction `OlsonNames()` de {`base`}. --- class: exo # Exercices 1. Avec la fonction appropriée du _package_ {`lubridate`}, créer un objet contenant la date du jour (sans les heures, minutes et secondes) ; 2. Idem avec l'heure du jour et les minutes (mais pas les secondes) ; 3. Convertir la chaîne de caractères `x <- "17/05/2020"` en objet de type `Date` ; 4. Stocker sous forme de `POSIXct` la date initialement donnée dans la chaîne de caractères suivate : `"Thu Sep 18 23:40:54 +0000 2020"` ; 5. À partir de la date obtenue en question précédente, obtenir l'heure équivalente à New York City ; 6. Calculer le nombre de jours séparant votre date de naissance et aujourd'hui ; 7. Créer une séquence de dates allant de "1975-01-01" à "2021-01-01", par pas de 6 mois. 8. À partir de `dd`, trouver la date une semaine auparavant (en termes de durées, et en termes d'époques). ```r dd <- "2012-03-02 23:40:54 +0000 2020" ``` --- class: titre_2, center, middle ## 4.5. Calculs matriciels --- #### Calculs matriciels Considérons trois matrices \(A\), \(B\) et \(C\) de même type, ainsi qu'un scalaire \(a\). ```r (A <- matrix(c(1, 3, 2, 2, 2, 1, 3, 1, 3), ncol = 3)) ``` ``` ## [,1] [,2] [,3] ## [1,] 1 2 3 ## [2,] 3 2 1 ## [3,] 2 1 3 ``` ```r (B <- matrix(c(4, 6, 4, 5, 5, 6, 6, 4, 5), ncol = 3)) ``` ``` ## [,1] [,2] [,3] ## [1,] 4 5 6 ## [2,] 6 5 4 ## [3,] 4 6 5 ``` --- #### Calculs matriciels ```r (C <- matrix(c(0, 3, 1), ncol = 1)) ``` ``` ## [,1] ## [1,] 0 ## [2,] 3 ## [3,] 1 ``` ```r a <- 2 ``` --- #### Calculs matriciels : addition ```r A+a # Avec un scalaire ``` ``` ## [,1] [,2] [,3] ## [1,] 3 4 5 ## [2,] 5 4 3 ## [3,] 4 3 5 ``` ```r A+B # De deux matrices ``` ``` ## [,1] [,2] [,3] ## [1,] 5 7 9 ## [2,] 9 7 5 ## [3,] 6 7 8 ``` --- #### Calculs matriciels : soustraction ```r A-a # Avec un scalaire ``` ``` ## [,1] [,2] [,3] ## [1,] -1 0 1 ## [2,] 1 0 -1 ## [3,] 0 -1 1 ``` ```r A-B # De deux matrices ``` ``` ## [,1] [,2] [,3] ## [1,] -3 -3 -3 ## [2,] -3 -3 -3 ## [3,] -2 -5 -2 ``` --- #### Calculs matriciels : multiplication par un scalaire ```r a*A ``` ``` ## [,1] [,2] [,3] ## [1,] 2 4 6 ## [2,] 6 4 2 ## [3,] 4 2 6 ``` --- #### Calculs matriciels : division par un scalaire ```r A/a ``` ``` ## [,1] [,2] [,3] ## [1,] 0.5 1.0 1.5 ## [2,] 1.5 1.0 0.5 ## [3,] 1.0 0.5 1.5 ``` --- #### Calculs matriciels : transposée ```r t(A) ``` ``` ## [,1] [,2] [,3] ## [1,] 1 3 2 ## [2,] 2 2 1 ## [3,] 3 1 3 ``` --- #### Calculs matriciels : conjuguée ```r Conj(A) ``` ``` ## [,1] [,2] [,3] ## [1,] 1 2 3 ## [2,] 3 2 1 ## [3,] 2 1 3 ``` --- #### Calculs matriciels : multiplication de deux matrices ```r A%*%C ``` ``` ## [,1] ## [1,] 9 ## [2,] 7 ## [3,] 6 ``` Attention, `*` effectue une multiplication termes à termes, si les deux matrices sont de même dimension. ```r A*B ``` ``` ## [,1] [,2] [,3] ## [1,] 4 10 18 ## [2,] 18 10 4 ## [3,] 8 6 15 ``` --- #### Calculs matriciels : inversion ```r solve(A) ``` ``` ## [,1] [,2] [,3] ## [1,] -0.41666667 0.25 0.3333333 ## [2,] 0.58333333 0.25 -0.6666667 ## [3,] 0.08333333 -0.25 0.3333333 ``` --- #### Calculs matriciels : division matricielle ```r B %/% solve(A) ``` ``` ## [,1] [,2] [,3] ## [1,] -10 19 18 ## [2,] 10 20 -7 ## [3,] 48 -25 15 ``` --- #### Calculs matriciels : produit avec la transposition ```r crossprod(A,B) ``` ``` ## [,1] [,2] [,3] ## [1,] 30 32 28 ## [2,] 24 26 25 ## [3,] 30 38 37 ``` ```r t(A) %*% B # Moins rapide ``` ``` ## [,1] [,2] [,3] ## [1,] 30 32 28 ## [2,] 24 26 25 ## [3,] 30 38 37 ``` --- #### Calculs matriciels : déterminant, diagonale et trace ```r det(A) ``` ``` ## [1] -12 ``` ```r diag(A) ``` ``` ## [1] 1 2 3 ``` ```r sum(diag(A)) ``` ``` ## [1] 6 ``` --- class: exo # Exercices : données Considérons le modèle suivant : `$$\textrm{mpg} = \beta_0 + \beta_1 \textrm{hp} + \beta_2 \textrm{wt} + \varepsilon,$$` où `\(\textrm{mpg}\)` est un vecteur de valeurs de consommation de carburant (miles par gallons), `\(\textrm{hp}\)` et `\(\textrm{wt}\)` des vecteurs de puissance (nombre de chevaux) et de masse du véhicule (en millième de livres) respectivement. Le vecteur `\(\varepsilon\)` est un terme d'erreurs. <br/><br/> On cherche à estimer les paramètres `\(\beta_0\)`, `\(\beta_1\)` et `\(\beta_3\)` par la méthode des moindres carrés ordinaires. <br/><br/> Les données sont contenues dans le <em>data frame</em> `mtcars`. --- class: exo # Exercices : question 1. À partir de `mtcars`, créer le vecteur `y` contenant les valeurs de consommation (`mpg`) ; 2. Créer également la matrice `X` qui doit contenir 3 colonnes : une pour la constante, une autre pour la puissance (`ht`) et une dernière pour la masse (`wt`) ; 3. Calculer la transposée de `\(X\)` : `\(X^T\)` ; 4. Calculer le produit matriciel : `\(X^TX\)` (de deux façons); 5. Calculer l'inverse de ce produit matriciel : `\((X^TX)^{-1}\)` ; 6. Calculer le produit matriciel `\(X^Ty\)` ; 7. Donner les estimations des paramètres : `\((X^TX)^{-1} X^Ty\)`. --- class: titre_2, center, middle ## 4.6. Manipulation sur les tableaux de données --- #### Manipulation sur les tableaux de données - Cette partie montre comment <b class="coul_1">manipuler la structure de données</b> la plus fréquemment rencontrée en économétrie : les <b class="coul_2">tableaux de données</b> ; - Il sera considéré que ces tableaux de données sont sous la forme de tibbles plutôt que data frame ; - Les manipulations sont principalement effectuées à l'aide de fonctions issues de l'environnement `tidyverse` ; - Plus particulièrement, de nombreuses fonctions appartenant au _package_ {`dplyr`} sont présentées. --- class: titre_3, center, middle ### 4.6.1. L'opérateur Pipe --- #### L'opérateur Pipe - Avant de commencer à présenter les manipulations de données, il peut être intéressant d'introduire un opérateur : <b class="coul_1">Pipe</b> (` %>% `) ; - Cet opérateur provient de {`magrittr`} ; - Pour comprendre à quoi sert cet opérateur, et quelle peut être son utilité, regardons quelques exemples qui *ne l'utilisent pas*, en se basant sur les explications fournies dans Grolemund, G., & Wickham, H. (2018). -- - Admettons qu'il soit nécessaire d'effectuer <b class="coul_1">plusieurs opérations à la suite</b>, sur un tableau de données. - Par exemple, considérons un tableau dont chaque ligne contient les ventes mensuelles (en colonnes, une par mois) des bars du Cours Julien (en lignes) et que l'on souhaite réaliser les opérations suivantes : 1. Calculer la moyenne du chiffre d'affaires (CA) à l'année pour chaque bar ; 2. Ordonner les observations par valeurs croissante des moyennes ; 3. Afficher le top 5 des bars avec le plus gros CA. --- #### L'opérateur Pipe - Une manière de faire consiste à <b class="coul_2">sauvegarder un objet nouvel objet à chaque étape</b> (le code qui suit ne s'évalue pas, il s'agit d'un exemple) : ```r top_ca_bars_anuel_1 <- calcul(ca_bars_cours_ju, type = "moyenne") top_ca_bars_anuel_2 <- ordonner(top_ca_bars_anuel_2, type = "decroissantes", variable = "ca_annuel") top_ca_bars_anuel_3 <- head(top_ca_bars_anuel_2, 5) ``` - Cette manière de faire requière de créer de nombreux objets intermédiaires avant d'arriver au résultat : - le nom de ces objets intermédiaires peut ne pas être facile à trouver/comprendre (s'il est possible de trouver des noms sensés, cette méthode peut être adaptée), - <b class="coul_1">le code devient plus difficile à lire</b> du fait des nombreux noms de variables inintéressantes, - Remarque : si le tableau initial contient un volume de données importantes, la création des objets intermédiaire n'occupera pas un espace en mémoire important (R gère cela plutôt bien) --- #### L'opérateur Pipe - Une autre manière de faire l'opération en chaîne consiste à <b class="coul_2">écraser l'objet d'origine</b> à chaque étape : ```r top_ca_bars_anuel_1 <- calcul(ca_bars_cours_ju, type = "moyenne") top_ca_bars_anuel_1 <- ordonner(top_ca_bars_anuel_1, type = "decroissantes", variable = "ca_annuel") top_ca_bars_anuel_1 <- head(top_ca_bars_anuel_1, 5) ``` - Cette solution est moins pénible à rédiger que la précédente ; - Mais elle rend le débugage difficile ; - Le nom de l'objet modifié a été écrit 5 fois et il est difficile de rapidement comprendre ce qui a été modifié à chaque ligne. --- #### L'opérateur Pipe - Une dernière alternative avant de présenter l'opérateur pipe est la <b class="coul_2">composition de fonction</b> : ```r top_ca_bars_anuel_1 <- head( ordonner( calcul( ca_bars_cours_ju, type = "moyenne"), type = "decroissantes", variable = "ca_annuel" ), 5 ) ``` - Le temps de rédaction peut être allongé ; - Pour comprendre ce que fait le code, il faut lire de l'intérieur vers l'extérieur, ce qui est d'autant plus difficile que les arguments de chaque fonction sont éloignés. --- #### L'opérateur Pipe - L'opérateur Pipe permet de réaliser l'opération chaînée de la manière suivante : ```r top_ca_bars_anuel_1 <- ca_bars_cours_ju %>% calcul(type = "moyenne") %>% ordonner(type = "decroissantes", variable = "ca_annuel") %>% head(5) ``` - La lecture est rapide pour une personne humaine ! - Le deboguage est plus facile à réaliser ; - Attention toutefois à ne pas enchaîner de trop nombreuses opérations : il faut trouver un juste milieux (sinon, le déboguage redevient difficile et la compréhension de ce que l'on veut faire devient plus ardue). --- class: titre_3, center, middle ### 4.6.2. Sélection --- #### Sélection de colonnes - Pour sélectionner une colonne d'un tibble : `select()` ; - Le résultat est également un tibble ; - Le nom des colonnes ne doit pas être entre guillemets : ```r tb <- tibble(x = seq(1,4), y = x^2, z = LETTERS[1:4], t = letters[1:4]) select(tb, x) ``` ``` ## # A tibble: 4 x 1 ## x ## <int> ## 1 1 ## 2 2 ## 3 3 ## 4 4 ``` - Pour extraire le <b class="coul_1">contenu</b> d'une seule colonne, il est toujours possible d'utiliser le symbole dollar `$`. ```r tb$x ``` ``` ## [1] 1 2 3 4 ``` --- #### Sélection de colonnes - Sélection de <b class="coul_2">plusieurs colonnes</b> en inscrivant le nom des colonnes séparés d'une virgule. ```r select(tb, x, z) ``` ``` ## # A tibble: 4 x 2 ## x z ## <int> <chr> ## 1 1 A ## 2 2 B ## 3 3 C ## 4 4 D ``` -- - Sélection d'une <b class="coul_2">plage de données contigues</b> avec les deux points `:`. ```r select(tb, y:t) ``` ``` ## # A tibble: 4 x 3 ## y z t ## <dbl> <chr> <chr> ## 1 1 A a ## 2 4 B b ## 3 9 C c ## 4 16 D d ``` --- #### Sélection de colonnes : sélection d'une variable dont le nom ne respecte pas les standards de nommage - Pour sélectionner à l'aide de la fonction `select()` une variable dont le nom ne respecte pas les standards de nommage, il n'est pas possible d'utiliser les guillemets doubles ; - Il faut utiliser les accents graves. ```r tb_2 <- tibble(`Un nom` = 1:3, `Un autre` = LETTERS[1:3]) select(tb_2, `Un nom`) ``` ``` ## # A tibble: 3 x 1 ## `Un nom` ## <int> ## 1 1 ## 2 2 ## 3 3 ``` --- #### Sélection de colonnes : cas particulier - Il arrive de vouloir extraire une variable par son nom, ce dernier étant le contenu d'une variable externe (dans une boucle par exemple) ; - La pratique suivante n'est pas recommandée car ambigüe : ```r nom_variable <- "x" select(tb, nom_variable) ``` ``` ## Note: Using an external vector in selections is ambiguous. ## ℹ Use `all_of(nom_variable)` instead of `nom_variable` to silence this message. ## ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>. ## This message is displayed once per session. ``` ``` ## # A tibble: 4 x 1 ## x ## <int> ## 1 1 ## 2 2 ## 3 3 ## 4 4 ``` --- #### Sélection de colonnes : cas particulier Le résultat obtenu n'est de fait pas nécessairement celui attendu : ```r nom_variable <- "x" tb_2 <- tibble(nom_variable = c("A","B", "C"), x = 1:3) select(tb_2, nom_variable) ``` ``` ## # A tibble: 3 x 1 ## nom_variable ## <chr> ## 1 A ## 2 B ## 3 C ``` --- #### Sélection de colonnes : cas particulier - Une solution consiste à faire précéder le nom de la variable qui contient le nom de la (ou les) colonne(s) que l'on souhaite sélectionner : ```r select(tb_2, !!nom_variable) ``` ``` ## # A tibble: 3 x 1 ## x ## <int> ## 1 1 ## 2 2 ## 3 3 ``` --- #### Retirer une colonne - Le <b class="coul_2">retrait</b> d'une colonne se fait en faisant précéder le nom de cette colonne du signe moins : ```r tb <- tibble(x = seq(1,4), y = x^2, z = LETTERS[1:4], t = letters[1:4]) select(tb, -x) ``` ``` ## # A tibble: 4 x 3 ## y z t ## <dbl> <chr> <chr> ## 1 1 A a ## 2 4 B b ## 3 9 C c ## 4 16 D d ``` --- #### Retirer plusieurs colonnes - Pour <b class="coul_2">retirer plusieurs colonnes</b>, il suffit de placer les noms de colonnes dans un vecteur à l'aide de la fonction `c()` et de faire précéder l'appel de cette fonction du signe moins : ```r select(tb, -c(x, z)) ``` ``` ## # A tibble: 4 x 2 ## y t ## <dbl> <chr> ## 1 1 a ## 2 4 b ## 3 9 c ## 4 16 d ``` - De manière équivalente : ```r select(tb, -x, -z) ``` ``` ## # A tibble: 4 x 2 ## y t ## <dbl> <chr> ## 1 1 a ## 2 4 b ## 3 9 c ## 4 16 d ``` --- #### Sélection de lignes - Pour <b class="coul_2">sélectionner les lignes</b> par leur numéro de ligne : la fonction `slice()` ```r tb <- tibble(x = seq(1,4), z = LETTERS[1:4], t = letters[1:4]) slice(tb, c(1,3,4)) ``` ``` ## # A tibble: 3 x 3 ## x z t ## <int> <chr> <chr> ## 1 1 A a ## 2 3 C c ## 3 4 D d ``` - Note : la numérotation des lignes a été changée. --- class: titre_3, center, middle ### 4.6.3. Filtrage --- #### Filtrage - La fonction `filter()` permet de conserver des lignes d'un tableau de données en fonction du respect de <b class="coul_2">conditions logiques</b> appliquées aux valeurs ; - Le premier argument de la fonction est le nom du tableau, les suivants les expressions à évaluer à l'intérieur du tableau. Redéfinissions le tableau des tailles et masses : ```r femmes <- tibble(height = c(58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72), weight = c(115, 117, 120, 123, 126, 129, 132, 135, 139, 142, 146, 150, 154, 159, 164)) ``` --- #### Filtrage - Pour <b class="coul_2">filter sur une seule condition logique</b>, il suffit de la donner en 2e argument de la fonction `filter` ; - Par exemple, pour ne conserver que les lignes pour lesquelles la valeur prise par la caractéristique `height` vaut exactement 60 : ```r filter(femmes, height == 60) ``` ``` ## # A tibble: 1 x 2 ## height weight ## <dbl> <dbl> ## 1 60 120 ``` -- - Pour <b class="coul_2">ajouter des conditions supplémentaires</b> : soit utiliser la virgule pour ajouter les conditions, soit composer l'expression logique à l'aide de l'esperluette (`&`) ; - Les femmes dont la masse vaut plus de 120 livres et dont la taille est inférieure ou égale à 62 pouces : ```r filter(femmes, weight > 120, height <= 62) ``` ``` ## # A tibble: 2 x 2 ## height weight ## <dbl> <dbl> ## 1 61 123 ## 2 62 126 ``` --- #### Filtrage : expressions logiques - En construisant une expression logique, par exemple avec une condition de type OU : ```r filter(femmes, weight %in%c(150,159) | height == 62) ``` ``` ## # A tibble: 3 x 2 ## height weight ## <dbl> <dbl> ## 1 62 126 ## 2 69 150 ## 3 71 159 ``` --- class: titre_3, center, middle ### 4.6.4. Retrait des valeurs dupliquées --- #### Retrait des valeurs dupliquées - Lorsqu'une ou plusieurs lignes d'un tableau de données sont <b class="coul_2">dupliquées</b> et qu'il est nécessaire de se restreindre aux lignes aux <b class="coul_2">valeurs uniques</b>, R propose la fonction `unique()` : ```r tb <- tibble(x = letters[c(1,2,3,1,4,3,1)], y = letters[c(1,5,2,4,3,2,1)]) unique(tb) ``` ``` ## # A tibble: 5 x 2 ## x y ## <chr> <chr> ## 1 a a ## 2 b e ## 3 c b ## 4 a d ## 5 d c ``` --- class: titre_3, center, middle ### 4.6.5. Modification des colonnes --- #### Modification des colonnes : renommer - Pour <b class="coul_2">renommer des colonnes</b>, la fonction `rename()` de {`dplyr`} peut être utilisée ; - Le premier argument est le tableau de données, les suivants les modifications de nom à apporter, en adoptant la syntaxe suivante : `nouveau_nom = ancien_nom` ; ```r rename(femmes, masse = weight) %>% head() ``` ``` ## # A tibble: 6 x 2 ## height masse ## <dbl> <dbl> ## 1 58 115 ## 2 59 117 ## 3 60 120 ## 4 61 123 ## 5 62 126 ## 6 63 129 ``` --- #### Modification des colonnes : renommer plusieurs colonnes - Pour <b class="coul_2">renommer plusieurs colonnes</b> avec la fonction `rename()`, il suffit d'ajouter des arguments : ```r rename(femmes, masse = weight, taille = height) %>% head() ``` ``` ## # A tibble: 6 x 2 ## taille masse ## <dbl> <dbl> ## 1 58 115 ## 2 59 117 ## 3 60 120 ## 4 61 123 ## 5 62 126 ## 6 63 129 ``` -- - Il est également possible d'extraire le nom des colonnes avec la fonction `colnames()` puis d'effectuer un remplacement à l'aide de la flèche d'assignation --- #### Modification des colonnes : remarque - Avec la fonction `select()`, une variable peut être sélectionnée et renommée d'une seule ligne de code : ```r femmes %>% select(masse = weight, hauteur = height) %>% head() ``` ``` ## # A tibble: 6 x 2 ## masse hauteur ## <dbl> <dbl> ## 1 115 58 ## 2 117 59 ## 3 120 60 ## 4 123 61 ## 5 126 62 ## 6 129 63 ``` --- #### Modification des colonnes : ajout et modification de colonnes - L'<b class="coul_2">ajout d'une colonne</b> dans un tableau de données peut être aisément réalisé à l'aide de l'opérateur `$` ; ```r chomeurs <- tibble(annee = 2012:2008, nb_chomeurs =c(2.811, 2.604, 2.635, 2.573, 2.064), pop_active =c(28.328, 28.147, 28.157, 28.074, 27.813)) ``` ```r chomeurs$taux_chomage_0 <- chomeurs$nb_chomeurs / chomeurs$pop_active * 100 chomeurs ``` ``` ## # A tibble: 5 x 4 ## annee nb_chomeurs pop_active taux_chomage_0 ## <int> <dbl> <dbl> <dbl> ## 1 2012 2.81 28.3 9.92 ## 2 2011 2.60 28.1 9.25 ## 3 2010 2.64 28.2 9.36 ## 4 2009 2.57 28.1 9.17 ## 5 2008 2.06 27.8 7.42 ``` --- #### Modification des colonnes : ajout et modification de colonnes - Pour éviter d'avoir à écrire de nombreuses fois le nom du tibble, la fonction `mutate()` de {`dplyr`} s'avère pratique et améliore la lisibilité du code ; - Il est de plus possible de réaliser <b class="coul_2">plusieurs modifications / ajouts</b> en une seule instruction : ```r chomeurs <-chomeurs %>% mutate(tx_chomage_1 = nb_chomeurs/pop_active*100, log_nb_chomeurs =log(nb_chomeurs)) chomeurs ``` ``` ## # A tibble: 5 x 6 ## annee nb_chomeurs pop_active taux_chomage_0 tx_chomage_1 log_nb_chomeurs ## <int> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 2012 2.81 28.3 9.92 9.92 1.03 ## 2 2011 2.60 28.1 9.25 9.25 0.957 ## 3 2010 2.64 28.2 9.36 9.36 0.969 ## 4 2009 2.57 28.1 9.17 9.17 0.945 ## 5 2008 2.06 27.8 7.42 7.42 0.725 ``` --- #### Modification des colonnes : ajout et modification de colonnes - La création ou la modification d'une variable avec `mutate()` peut s'appuyer sur une autre variable créée lors de la même évaluation : ```r chomeurs <-chomeurs %>% mutate(tx_chomage_2 = nb_chomeurs/pop_active*100, log_tx_chomage = log(tx_chomage_2)) chomeurs ``` ``` ## # A tibble: 5 x 8 ## annee nb_chomeurs pop_active taux_chomage_0 tx_chomage_1 log_nb_chomeurs ## <int> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 2012 2.81 28.3 9.92 9.92 1.03 ## 2 2011 2.60 28.1 9.25 9.25 0.957 ## 3 2010 2.64 28.2 9.36 9.36 0.969 ## 4 2009 2.57 28.1 9.17 9.17 0.945 ## 5 2008 2.06 27.8 7.42 7.42 0.725 ## # … with 2 more variables: tx_chomage_2 <dbl>, log_tx_chomage <dbl> ``` --- #### Modification des colonnes : ajout et modification de colonnes - La modification du contenu d'une colonne peut être effectuée en se référant au nom de cette colonne au sein de la fonction `mutate()` : ```r chomeurs %>% mutate(annee = annee / 1000) ``` ``` ## # A tibble: 5 x 8 ## annee nb_chomeurs pop_active taux_chomage_0 tx_chomage_1 log_nb_chomeurs ## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 2.01 2.81 28.3 9.92 9.92 1.03 ## 2 2.01 2.60 28.1 9.25 9.25 0.957 ## 3 2.01 2.64 28.2 9.36 9.36 0.969 ## 4 2.01 2.57 28.1 9.17 9.17 0.945 ## 5 2.01 2.06 27.8 7.42 7.42 0.725 ## # … with 2 more variables: tx_chomage_2 <dbl>, log_tx_chomage <dbl> ``` --- class: titre_3, center, middle ### 4.6.6. Tri --- ### Tri : à l'ancienne - Plusieurs manières de trier un tableau de données : - à l'ancienne, avec `order()`, - en utilisant `arrange()` de {`dplyr`} ; - Tri par odre de valeurs croissantes ou décroissantes : `order()` ; - Le résultat est un vecteur de rangs. --- ### Tri : à l'ancienne - Tri selon l'ordre alphanumérique: ```r df <- tibble(nom = c("Durand", "Martin", "Martin", "Martin", "Durand"), prenom = c("Sonia", "Serge", "Julien-Yacine", "Victor", "Emma"), note = c(23, 18, 17, 17, 19)) df ``` ``` ## # A tibble: 5 x 3 ## nom prenom note ## <chr> <chr> <dbl> ## 1 Durand Sonia 23 ## 2 Martin Serge 18 ## 3 Martin Julien-Yacine 17 ## 4 Martin Victor 17 ## 5 Durand Emma 19 ``` --- ### Tri : à l'ancienne - Ordonner par notes décroissantes : ```r order(df$note, decreasing = TRUE) ``` ``` ## [1] 1 5 2 3 4 ``` ```r df[order(df$note), ] ``` ``` ## # A tibble: 5 x 3 ## nom prenom note ## <chr> <chr> <dbl> ## 1 Martin Julien-Yacine 17 ## 2 Martin Victor 17 ## 3 Martin Serge 18 ## 4 Durand Emma 19 ## 5 Durand Sonia 23 ``` -- - Remarques : - `sort()` retourne un vecteur trié par valeurs croissantes ou décroissantes ; - `order()` retourne les rangs du classement. --- ### Tri : avec `arrange()` - La fonction `arrange()` permet également de trier les tableaux de données (et sur plusieurs colonnes !) ; - La fonction prend en premier argument le tableau de données ; les arguments suivants définissent les colonnes à utiliser pour réaliser le tri ; - Il n'y a pas d'argument pour indiquer si le tri doit se faire par valeurs croissantes ou décroissantes : - par défaut, le tri se fait par valeurs croissantes, - si on veut un tri par valeurs décroissantes pour une colonne, il faut faire précéder son nom du signe `-` ou bien appeler la fonction `desc()` sur la variable. Par exemple, pour trier par valeurs décroissantes des noms : ```r df %>%arrange(-note) ``` ``` ## # A tibble: 5 x 3 ## nom prenom note ## <chr> <chr> <dbl> ## 1 Durand Sonia 23 ## 2 Durand Emma 19 ## 3 Martin Serge 18 ## 4 Martin Julien-Yacine 17 ## 5 Martin Victor 17 ``` --- ### Tri : avec `arrange()` Pour un tri par ordre alphabétique des noms puis inverse des prénoms : ```r df %>% arrange(nom, desc(prenom)) ``` ``` ## # A tibble: 5 x 3 ## nom prenom note ## <chr> <chr> <dbl> ## 1 Durand Sonia 23 ## 2 Durand Emma 19 ## 3 Martin Victor 17 ## 4 Martin Serge 18 ## 5 Martin Julien-Yacine 17 ``` --- class: titre_3, center, middle ### 4.6.7. Jointure --- #### Jointures - Deux fonctions sont utiles pour <b class="coul_2">juxtaposer des tableaux de données</b> (ou des matrices) entre-eux : - `cbind()` : pour placer côte-à-côte des tableaux, - `rbind()` : pour empiler des tableaux ; - Voici trois tableaux de données : ```r (A <-tibble(x1 =c(1, -1), x2 =c(0, 3))) ``` ``` ## # A tibble: 2 x 2 ## x1 x2 ## <dbl> <dbl> ## 1 1 0 ## 2 -1 3 ``` ```r (B <-tibble(x1 =c(3,2), x2 =c(1, 1))) ``` ``` ## # A tibble: 2 x 2 ## x1 x2 ## <dbl> <dbl> ## 1 3 1 ## 2 2 1 ``` ```r (C <-tibble(x3 =c(0, 3))) ``` ``` ## # A tibble: 2 x 1 ## x3 ## <dbl> ## 1 0 ## 2 3 ``` --- #### Jointures - Coller A et B côte-à-côte : ```r cbind(A,B) ``` ``` ## x1 x2 x1 x2 ## 1 1 0 3 1 ## 2 -1 3 2 1 ``` -- - Empiler A et B : ```r rbind(A,B) ``` ``` ## # A tibble: 4 x 2 ## x1 x2 ## <dbl> <dbl> ## 1 1 0 ## 2 -1 3 ## 3 3 1 ## 4 2 1 ``` --- #### Jointures - Coller côte-à-côte A, B et C : ```r cbind(A,B, C) ``` ``` ## x1 x2 x1 x2 x3 ## 1 1 0 3 1 0 ## 2 -1 3 2 1 3 ``` - Toutefois, il est nécessaire que les tableaux soient de dimensions compatibles : - même nombre de lignes lorsque l'on veut utiliser `cbind()`, - même nombre de colonnes lorsque l'on veut utiliser `rbind()` ; - Les opérations sont surtout utiles en économie lorsque l'on désire apparier différents jeux de données de sources multiples : de nombreuses précautions doivent alors être prises au préalable pour effectuer des jointures, ce qui n'est pas très pratique. --- #### Jointures avec {`dplyr`} - Une fois encore, le _package_ {`dplyr`} vient à la rescousse ! - Tout d'abord, pour empiler des tableaux les uns sur les autres, la fonction `bind_rows()` propose une équivalence à `rbind()`: ```r bind_rows(A,B) ``` ``` ## # A tibble: 4 x 2 ## x1 x2 ## <dbl> <dbl> ## 1 1 0 ## 2 -1 3 ## 3 3 1 ## 4 2 1 ``` --- #### Jointures avec {`dplyr`} - Une multitude de fonctions de jointure sont disponibles ; - Elles partagent une syntaxe commune : - `xx_join(x, y, by = NULL, copy = FALSE, ...)`, où `x` et `y` sont les tableaux à joindre, `by` est un vecteur de chaînes de caractères contenant les noms des variables permettant la jointure (si la valeur est `NULL` – par défaut – la jointure se fera à l'aide des variables portant le même nom dans les deux tables) --- #### Jointures avec {`dplyr`} Les différentes <b class="coul_2">fonctions de jointure</b> sont les suivantes : —`inner_join()` : toutes les lignes de `x` pour lesquelles il y a des valeurs correspondantes dans `y`, et toutes les colonnes de `x` et `y`. S’il y a plusieurs correspondances dans les noms entre `x` et `y`, toutes les combinaisons possibles sont retournées ; —`left_join()`: toutes les lignes de `x`, et toutes les colonnes de `x` et `y`. Les lignes dans `x` pour lesquelles il n’y a pas de correspondance dans `y` auront des valeurs `NA` dans les nouvelles colonnes. S’il y a plusieurs correspondances dans les noms entre `x` et `y`, toutesles combinaisons sont retournées ; —`right_join()`: toutes les lignes de `y`, et toutes les colonnes de `x` et `y`. Les lignes dans `y` pour lesquelles il n’y a pas de correspondance dansxauront des valeurs `NA` dans les nouvelles colonnes. S’il y a plusieurs correspondances dans les noms entre `x` et `y`, toutesles combinaisons sont retournées ; —`semi_join()`: toutes les lignes de `x` pour lesquelles il y a des valeurs correspondantes dans `y`, en ne conservant uniquement les colonnes de `x`; —`anti_join()`: toutes les lignes dexpour lesquelles il n’y a pas de correspondances dans `y`, en ne conservant que les colonnes de `x`. --- #### Jointures avec {`dplyr`} - Illustrons tout celà à l'aide de quelques données : ```r exportations <- tibble(year = 2011:2013, exportations =c(572.6, 587.3,597.8)) importations <- tibble(annee = 2010:2012, importations =c(558.1, 625.3,628.5)) exportations ``` ``` ## # A tibble: 3 x 2 ## year exportations ## <int> <dbl> ## 1 2011 573. ## 2 2012 587. ## 3 2013 598. ``` ```r importations ``` ``` ## # A tibble: 3 x 2 ## annee importations ## <int> <dbl> ## 1 2010 558. ## 2 2011 625. ## 3 2012 628. ``` --- #### Jointures avec {`dplyr`} —`inner_join()` : toutes les lignes de `x` pour lesquelles il y a des valeurs correspondantes dans `y`, et toutes les colonnes de `x` et `y`. S’il y a plusieurs correspondances dans les noms entre `x` et `y`, toutes les combinaisons possibles sont retournées. ```r exportations %>% inner_join(importations, by = c(year = "annee")) ``` ``` ## # A tibble: 2 x 3 ## year exportations importations ## <int> <dbl> <dbl> ## 1 2011 573. 625. ## 2 2012 587. 628. ``` --- #### Jointures avec {`dplyr`} —`left_join()`: toutes les lignes de `x`, et toutes les colonnes de `x` et `y`. Les lignes dans `x` pour lesquelles il n’y a pas de correspondance dans `y` auront des valeurs `NA` dans les nouvelles colonnes. S’il y a plusieurs correspondances dans les noms entre `x` et `y`, toutesles combinaisons sont retournées. ```r exportations %>% left_join(importations, by =c(year = "annee")) ``` ``` ## # A tibble: 3 x 3 ## year exportations importations ## <int> <dbl> <dbl> ## 1 2011 573. 625. ## 2 2012 587. 628. ## 3 2013 598. NA ``` --- #### Jointures avec {`dplyr`} —`right_join()`: toutes les lignes de `y`, et toutes les colonnes de `x` et `y`. Les lignes dans `y` pour lesquelles il n’y a pas de correspondance dansxauront des valeurs `NA` dans les nouvelles colonnes. S’il y a plusieurs correspondances dans les noms entre `x` et `y`, toutesles combinaisons sont retournées. ```r exportations %>% right_join(importations, by =c(year = "annee")) ``` ``` ## # A tibble: 3 x 3 ## year exportations importations ## <int> <dbl> <dbl> ## 1 2011 573. 625. ## 2 2012 587. 628. ## 3 2010 NA 558. ``` --- #### Jointures avec {`dplyr`} —`semi_join()`: toutes les lignes de `x` pour lesquelles il y a des valeurs correspondantes dans `y`, en ne conservant uniquement les colonnes de `x`. ```r exportations %>% semi_join(importations, by =c(year = "annee")) ``` ``` ## # A tibble: 2 x 2 ## year exportations ## <int> <dbl> ## 1 2011 573. ## 2 2012 587. ``` --- #### Jointures avec {`dplyr`} —`anti_join()`: toutes les lignes dexpour lesquelles il n’y a pas de correspondances dans `y`, en ne conservant que les colonnes de `x`. ```r exportations %>% anti_join(importations, by =c(year = "annee")) ``` ``` ## # A tibble: 1 x 2 ## year exportations ## <int> <dbl> ## 1 2013 598. ``` --- class: exo # Exercices : données ```r (X <- tibble(mois = month.name[c(1,6,1,6)], annee = c(2014, 2014, 2015, 2015), val_1 = 1:4, val_2 = 5:8)) ``` ``` ## # A tibble: 4 x 4 ## mois annee val_1 val_2 ## <chr> <dbl> <int> <int> ## 1 January 2014 1 5 ## 2 June 2014 2 6 ## 3 January 2015 3 7 ## 4 June 2015 4 8 ``` ```r (Y <- tibble(mois = rev(month.name[c(1,6,1,6)]), annee = c(2014, 2014, 2015, 2015), val_3 = 9:12, val_2 = 13:16)) ``` ``` ## # A tibble: 4 x 4 ## mois annee val_3 val_2 ## <chr> <dbl> <int> <int> ## 1 June 2014 9 13 ## 2 January 2014 10 14 ## 3 June 2015 11 15 ## 4 January 2015 12 16 ``` --- class: exo # Exercices : questions 1. Créer un tableau `Z` qui contient `X` et `Y` côte-à-côte ; 2. Que se passe-t-il si on évalue l'instruction suivante : `rbind(X,Y)` ; 3. En utilisant une fonction appropriée, fusionner les tibbles `X` et `Y` par année et par mois ; 4. À l'aide de la fonction appropriée, ajouter à `X` les valeurs de la colonne `val_5` du tibble `Z`, en effectuant l'appariement sur la colonne des années : ```r (Z <- tibble(year = c(2013, 2014), val_5 = c("A", "B"))) ``` ``` ## # A tibble: 2 x 2 ## year val_5 ## <dbl> <chr> ## 1 2013 A ## 2 2014 B ``` --- class: titre_3, center, middle ### 4.6.8. Agrégation --- #### Agrégation - Il n'est pas rare de devoir effectuer des <b class="coul_2">calculs d'agrégation</b> : - pour passer d'une dimension trimestrielle à annuelle par exemple, - pour calculer des quantités à l'échelle d'un pays lorsqu'on dispose de données à l'échelle des régions - ... - Ce genre d'opérations est facilement exécutable à l'aide de la fonction `summarise()` du _package_ {`dplyr`} ; - Cette fonction réduit une colonne d'un tableau de données à une seule observation ; - Son premier argument est un tableau de données, les arguments suivants sont les opérations d'agrégation à effectuer (e.g., une moyenne, une somme, un cumul, etc.) --- #### Agrégation À titre illustratif, voici un tableau indiquant les nombre de chômeurs en 2010 et 2011 dans 6 département de deux régions françaises, pour les ouvriers et pour les ingénieurs. ```r chomage <- tibble( region =rep(c(rep("Bretagne", 4),rep("Corse", 2)), 2), departement =rep(c("Cotes-d'Armor", "Finistere", "Ille-et-Vilaine", "Morbihan", "Corse-du-Sud", "Haute-Corse"), 2), annee =rep(c(2011, 2010), each = 6), ouvriers =c(8738, 12701, 11390, 10228, 975, 1297,8113, 12258, 10897, 9617, 936, 1220), ingenieurs =c(1420, 2530, 3986, 2025, 259, 254,1334, 2401, 3776, 1979, 253, 241)) head(chomage) ``` ``` ## # A tibble: 6 x 5 ## region departement annee ouvriers ingenieurs ## <chr> <chr> <dbl> <dbl> <dbl> ## 1 Bretagne Cotes-d'Armor 2011 8738 1420 ## 2 Bretagne Finistere 2011 12701 2530 ## 3 Bretagne Ille-et-Vilaine 2011 11390 3986 ## 4 Bretagne Morbihan 2011 10228 2025 ## 5 Corse Corse-du-Sud 2011 975 259 ## 6 Corse Haute-Corse 2011 1297 254 ``` --- #### Agrégation - Pour obtenir la moyenne et l'écart-type des colonnes `ouvriers` et `ingenieurs` : ```r chomage %>% summarise(moy_ouvriers = mean(ouvriers), sd_ouvriers = sd(ouvriers), moy_ingenieurs = mean(ingenieurs), sd_ingenieurs = sd(ingenieurs)) ``` ``` ## # A tibble: 1 x 4 ## moy_ouvriers sd_ouvriers moy_ingenieurs sd_ingenieurs ## <dbl> <dbl> <dbl> <dbl> ## 1 7364. 4801. 1705. 1331. ``` --- #### Agrégation - Il serait peut-être plus intéressant de s'intéresser à la moyenne et l'écart-type sur des <b class="coul_2">sous-groupes de données</b>, par année par exemple ; - Pour ce faire, il suffit de faire appel à la fonction `group_by()` de {`dplyr`} en amont du calcul, en précisant au second argument sur quelle colonne effectuer les regroupements : ```r chomage %>% group_by(annee) %>% summarise(ouvriers = sum(ouvriers), ingenieurs = sum(ingenieurs)) ``` ``` ## `summarise()` ungrouping output (override with `.groups` argument) ``` ``` ## # A tibble: 2 x 3 ## annee ouvriers ingenieurs ## <dbl> <dbl> <dbl> ## 1 2010 43041 9984 ## 2 2011 45329 10474 ``` --- #### Agrégation - Les regroupements peuvent être effectués sur <b class="coul_2">plusieurs variables</b> ; - Par exemple, en groupant les données par année et par région avant de calculer dans chaque sous-groupe la moyenne et l'écart-type des deux colonnes d'intérêt : ```r chomage %>% group_by(annee, region) %>% summarise(ouvriers = sum(ouvriers), ingenieurs =sum(ingenieurs)) ``` ``` ## `summarise()` regrouping output by 'annee' (override with `.groups` argument) ``` ``` ## # A tibble: 4 x 4 ## # Groups: annee [2] ## annee region ouvriers ingenieurs ## <dbl> <chr> <dbl> <dbl> ## 1 2010 Bretagne 40885 9490 ## 2 2010 Corse 2156 494 ## 3 2011 Bretagne 43057 9961 ## 4 2011 Corse 2272 513 ``` --- #### Agrégation : remarque - Attention, si des calculs sur les résultats obtenus sur des sous-groupes doivent être effectués, il faut penser à <b class="coul_2">dégrouper</b>, à l'aide de la fonction `ungroup()` ```r chomage %>% group_by(annee, region) %>% summarise(ouvriers = sum(ouvriers), ingenieurs =sum(ingenieurs)) %>% ungroup() ``` ``` ## `summarise()` regrouping output by 'annee' (override with `.groups` argument) ``` ``` ## # A tibble: 4 x 4 ## annee region ouvriers ingenieurs ## <dbl> <chr> <dbl> <dbl> ## 1 2010 Bretagne 40885 9490 ## 2 2010 Corse 2156 494 ## 3 2011 Bretagne 43057 9961 ## 4 2011 Corse 2272 513 ``` --- class: exo # Exercice 1. À partir du tibble `chomage`, calculer la moyenne du nombre de chômeurs par région et par année ; 2. Même question en effectuant le calcul uniquement pour l'année 2020 ; 3. Ajouter une colonne indiquant le carré du nombre de chomeurs pour les ouvriers, puis calculer la moyenne de cette colonne par année et par région. --- class: titre_3, center, middle ### 4.6.9. Faire pivoter un tableau --- #### Faire pivoter un tableau - Devoir faire <b class="coul_2">pivoter un tableau</b> arrive fréquemment en R, principalement pour préparer les données avant de les fournir aux fonctions permettant de réaliser des graphiques ; - Deux fonctions du _package_ {`tidyr`} sont en cours de maturation à la rédaction de ces diapositives : - `pivot_longer()` : pivoter des données d'un tableau large vers un tableau long, - `pivot_wider()` : pivoter des données d'un tableau long vers un tableau en largeur. --- #### Faire pivoter un tableau : `pivot_longer()` Voici un tableau large : ```r pop <- tibble(ville =c ("Paris", "Paris", "Lyon", "Lyon"), arrondissement = c(1, 2, 1, 2), pop_municipale =c (17443, 22927, 28932, 30575), pop_totale =c(17620, 23102, 29874, 31131)) pop ``` ``` ## # A tibble: 4 x 4 ## ville arrondissement pop_municipale pop_totale ## <chr> <dbl> <dbl> <dbl> ## 1 Paris 1 17443 17620 ## 2 Paris 2 22927 23102 ## 3 Lyon 1 28932 29874 ## 4 Lyon 2 30575 31131 ``` - Comment faire pour obtenir un tableau dans lequel chaque ligne donne la population, pour une ville, un arrondissement et indique si la valeur de la population concerne la population municipale ou totale ? --- #### Faire pivoter un tableau : `pivot_longer()` Il suffit d'utiliser `pivot_longer()` en précisant : - pour l'argument `cols`, les variables contenant les valeurs que l'on veut avoir dans la colonne unique ; - éventuellement, il est possible de préciser : - le nom de la colonne qui indiquera le nom des colonnes d'où viennent initialement les données, en le passant à l'argument `names_to` (par defaut : `name`) ; - le nom de la colonne dans lesquelles les valeurs se trouveront en le passant à l'argument `values_to` (par defaut : `value`) ```r pop_long <- pop %>% pivot_longer(cols = c(pop_municipale, pop_totale), values_to = "population", names_to = "type_pop") pop_long ``` ``` ## # A tibble: 8 x 4 ## ville arrondissement type_pop population ## <chr> <dbl> <chr> <dbl> ## 1 Paris 1 pop_municipale 17443 ## 2 Paris 1 pop_totale 17620 ## 3 Paris 2 pop_municipale 22927 ## 4 Paris 2 pop_totale 23102 ## 5 Lyon 1 pop_municipale 28932 ## 6 Lyon 1 pop_totale 29874 ## 7 Lyon 2 pop_municipale 30575 ## 8 Lyon 2 pop_totale 31131 ``` --- #### Faire pivoter un tableau : `pivot_wider()` - La fonction `pivot_wider()` permet d'effectuer l'opération dans l'autre sens ; - Les arguments `names_from` et `values_from` permettent de désigner où sont les noms qui définiront les colonnes du tableau large et les valeurs associées, respectivement. ```r pop_long %>% pivot_wider(names_from = type_pop, values_from = population) ``` ``` ## # A tibble: 4 x 4 ## ville arrondissement pop_municipale pop_totale ## <chr> <dbl> <dbl> <dbl> ## 1 Paris 1 17443 17620 ## 2 Paris 2 22927 23102 ## 3 Lyon 1 28932 29874 ## 4 Lyon 2 30575 31131 ``` --- class: exo # Exercices : données ```r tb <- tibble(region = rep(c(rep("Bretage",4), rep("Corse", 2)), 2), dep = rep(c("Cotes-d'Armor", "Finistere", "Ille-et-Vilaine", "Morbihan", "Corse-du-Sud", "Haute-Corse"), 2), annee = rep(2012:2013, each = 6), ensoleillement = c(1586, 1545, 1762, 1792, 2933, 2735, 1639, 1661, 1729, 1770, 2715, 2606), precipitations = c(733, 1311, 788, 920, 876, 676, 679, 1166, 736, 788, 871, 729)) ``` --- class: exo # Exercices : questions 1. Creer les variables `ensoleillement_c` et `precipitations_c` dans le tibble `tb`, en utilisant la fonction `mutate()`. Ces deux variables doivent représenter l'écart à la moyenne de la variable `ensoleillement` et `precipitations` respectivement ; 2. Calculer la moyenne de précipitations pour chaque département et chaque année ; 3. Trier le résultat de la question précédente par année décroissante et ordre alphabétique des régions ; 4. À partir de `tb`, créer un tibble en long, où chaque ligne correspond à la durée d'ensoleillement ou les précipitations par région, département et année. Chaque ligne doit indiquer si la valeur concerne l'ensoleillement ou les précipitations.