Tout savoir sur tidyverse

C’est ici : www.tidyverse.org avec en complément le livre R for Data Science de Hadley Wickham, disponible gratuitement en ligne ici : r4ds.had.co.nz.

Installation et chargement

La commande suivante installe plusieurs packages.

install.packages("tidyverse")

Et on peut même charger tous ces packages en même temps.

library(tidyverse)
## ── Attaching packages ─────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.1     ✓ purrr   0.3.4
## ✓ tibble  3.0.1     ✓ dplyr   1.0.0
## ✓ tidyr   1.1.0     ✓ stringr 1.4.0
## ✓ readr   1.3.1     ✓ forcats 0.5.0
## ── Conflicts ────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

Mais on pourrait les charger un par un.

library(dplyr)
library(tidyr)

On va donc survoler ces packages (sauf ggplot2 vu par ailleurs) pour voir ce qu’ils ont à nous proposer.

tibble

iris.tib <- as_tibble(iris)
iris.tib
## # A tibble: 150 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
##           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
##  1          5.1         3.5          1.4         0.2 setosa 
##  2          4.9         3            1.4         0.2 setosa 
##  3          4.7         3.2          1.3         0.2 setosa 
##  4          4.6         3.1          1.5         0.2 setosa 
##  5          5           3.6          1.4         0.2 setosa 
##  6          5.4         3.9          1.7         0.4 setosa 
##  7          4.6         3.4          1.4         0.3 setosa 
##  8          5           3.4          1.5         0.2 setosa 
##  9          4.4         2.9          1.4         0.2 setosa 
## 10          4.9         3.1          1.5         0.1 setosa 
## # … with 140 more rows
has_rownames(iris)
## [1] FALSE
has_rownames(mtcars)
## [1] TRUE
remove_rownames(mtcars)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
rownames_to_column(mtcars)
##                rowname  mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1            Mazda RX4 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2        Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3           Datsun 710 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4       Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 5    Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 6              Valiant 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 7           Duster 360 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 8            Merc 240D 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9             Merc 230 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 10            Merc 280 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 11           Merc 280C 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 12          Merc 450SE 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 13          Merc 450SL 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 14         Merc 450SLC 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 15  Cadillac Fleetwood 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## 16 Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## 17   Chrysler Imperial 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## 18            Fiat 128 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 19         Honda Civic 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 20      Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 21       Toyota Corona 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 22    Dodge Challenger 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## 23         AMC Javelin 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## 24          Camaro Z28 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## 25    Pontiac Firebird 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## 26           Fiat X1-9 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 27       Porsche 914-2 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28        Lotus Europa 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 29      Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 30        Ferrari Dino 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 31       Maserati Bora 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 32          Volvo 142E 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
mtcars_tbl <- as_tibble(rownames_to_column(mtcars))
mtcars_tbl
## # A tibble: 32 x 12
##    rowname       mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <chr>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1 Mazda RX4    21       6  160    110  3.9   2.62  16.5     0     1     4     4
##  2 Mazda RX4 …  21       6  160    110  3.9   2.88  17.0     0     1     4     4
##  3 Datsun 710   22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
##  4 Hornet 4 D…  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
##  5 Hornet Spo…  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
##  6 Valiant      18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
##  7 Duster 360   14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
##  8 Merc 240D    24.4     4  147.    62  3.69  3.19  20       1     0     4     2
##  9 Merc 230     22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
## 10 Merc 280     19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
## # … with 22 more rows
head(column_to_rownames(mtcars_tbl))
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
head(column_to_rownames(mtcars_tbl, "rowname"))
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
glimpse(iris)
## Rows: 150
## Columns: 5
## $ Sepal.Length <dbl> 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4…
## $ Sepal.Width  <dbl> 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3…
## $ Petal.Length <dbl> 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1…
## $ Petal.Width  <dbl> 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0…
## $ Species      <fct> setosa, setosa, setosa, setosa, setosa, setosa, setosa, …

Une des différences majeures avec les data.frame réside dans l’affichage qui est limité aux 10 premières lignes.

A noter également que l’affichage tient compte du nombre de colonnes à afficher. Réduisez la largeur de la fenêtre Console dans RStudio et observez le résultat de mtcars_tbl par exemple… Impressionnant non ?

dplyr

mutate() / transmute()

Pour ajouter des variables à un data.frame (ou à un tibble bien sûr) soit en conservant les autres (mutate) soit en les supprimant (transmute).

mutate(mtcars, cyl2 = cyl*2)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb cyl2
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4   12
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4   12
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1    8
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1   12
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2   16
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1   12
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4   16
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2    8
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2    8
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4   12
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4   12
## 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3   16
## 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3   16
## 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3   16
## 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4   16
## 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4   16
## 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4   16
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1    8
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2    8
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1    8
## 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1    8
## 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2   16
## 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2   16
## 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4   16
## 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2   16
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1    8
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2    8
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2    8
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4   16
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6   12
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8   16
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2    8
mtcars.mute <- mutate(mtcars, cyl2 = cyl*2)
head(mtcars.mute)
##    mpg cyl disp  hp drat    wt  qsec vs am gear carb cyl2
## 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4   12
## 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4   12
## 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1    8
## 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1   12
## 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2   16
## 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1   12
class(mtcars.mute)
## [1] "data.frame"
mtcars.transmute <- transmute(mtcars, cyl2 = cyl*2)
head(mtcars.transmute)
##   cyl2
## 1   12
## 2   12
## 3    8
## 4   12
## 5   16
## 6   12
mtcars %>% mutate(cyl3 = cyl^3)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb cyl3
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4  216
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4  216
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1   64
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1  216
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2  512
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1  216
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4  512
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2   64
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2   64
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4  216
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4  216
## 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3  512
## 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3  512
## 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3  512
## 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4  512
## 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4  512
## 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4  512
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1   64
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2   64
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1   64
## 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1   64
## 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2  512
## 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2  512
## 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4  512
## 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2  512
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1   64
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2   64
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2   64
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4  512
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6  216
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8  512
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2   64
mtcars
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
mtcars.mute3 <- mtcars %>% mutate(cyl3 = cyl^3)

Euh, c’est quoi le truc %>% ?

select()

La fonction select offre des possibilités pour sélectionner simplement des variables dans un data.frame (ou un tibble).

select(iris, starts_with("Petal"))
##     Petal.Length Petal.Width
## 1            1.4         0.2
## 2            1.4         0.2
## 3            1.3         0.2
## 4            1.5         0.2
## 5            1.4         0.2
## 6            1.7         0.4
## 7            1.4         0.3
## 8            1.5         0.2
## 9            1.4         0.2
## 10           1.5         0.1
## 11           1.5         0.2
## 12           1.6         0.2
## 13           1.4         0.1
## 14           1.1         0.1
## 15           1.2         0.2
## 16           1.5         0.4
## 17           1.3         0.4
## 18           1.4         0.3
## 19           1.7         0.3
## 20           1.5         0.3
## 21           1.7         0.2
## 22           1.5         0.4
## 23           1.0         0.2
## 24           1.7         0.5
## 25           1.9         0.2
## 26           1.6         0.2
## 27           1.6         0.4
## 28           1.5         0.2
## 29           1.4         0.2
## 30           1.6         0.2
## 31           1.6         0.2
## 32           1.5         0.4
## 33           1.5         0.1
## 34           1.4         0.2
## 35           1.5         0.2
## 36           1.2         0.2
## 37           1.3         0.2
## 38           1.4         0.1
## 39           1.3         0.2
## 40           1.5         0.2
## 41           1.3         0.3
## 42           1.3         0.3
## 43           1.3         0.2
## 44           1.6         0.6
## 45           1.9         0.4
## 46           1.4         0.3
## 47           1.6         0.2
## 48           1.4         0.2
## 49           1.5         0.2
## 50           1.4         0.2
## 51           4.7         1.4
## 52           4.5         1.5
## 53           4.9         1.5
## 54           4.0         1.3
## 55           4.6         1.5
## 56           4.5         1.3
## 57           4.7         1.6
## 58           3.3         1.0
## 59           4.6         1.3
## 60           3.9         1.4
## 61           3.5         1.0
## 62           4.2         1.5
## 63           4.0         1.0
## 64           4.7         1.4
## 65           3.6         1.3
## 66           4.4         1.4
## 67           4.5         1.5
## 68           4.1         1.0
## 69           4.5         1.5
## 70           3.9         1.1
## 71           4.8         1.8
## 72           4.0         1.3
## 73           4.9         1.5
## 74           4.7         1.2
## 75           4.3         1.3
## 76           4.4         1.4
## 77           4.8         1.4
## 78           5.0         1.7
## 79           4.5         1.5
## 80           3.5         1.0
## 81           3.8         1.1
## 82           3.7         1.0
## 83           3.9         1.2
## 84           5.1         1.6
## 85           4.5         1.5
## 86           4.5         1.6
## 87           4.7         1.5
## 88           4.4         1.3
## 89           4.1         1.3
## 90           4.0         1.3
## 91           4.4         1.2
## 92           4.6         1.4
## 93           4.0         1.2
## 94           3.3         1.0
## 95           4.2         1.3
## 96           4.2         1.2
## 97           4.2         1.3
## 98           4.3         1.3
## 99           3.0         1.1
## 100          4.1         1.3
## 101          6.0         2.5
## 102          5.1         1.9
## 103          5.9         2.1
## 104          5.6         1.8
## 105          5.8         2.2
## 106          6.6         2.1
## 107          4.5         1.7
## 108          6.3         1.8
## 109          5.8         1.8
## 110          6.1         2.5
## 111          5.1         2.0
## 112          5.3         1.9
## 113          5.5         2.1
## 114          5.0         2.0
## 115          5.1         2.4
## 116          5.3         2.3
## 117          5.5         1.8
## 118          6.7         2.2
## 119          6.9         2.3
## 120          5.0         1.5
## 121          5.7         2.3
## 122          4.9         2.0
## 123          6.7         2.0
## 124          4.9         1.8
## 125          5.7         2.1
## 126          6.0         1.8
## 127          4.8         1.8
## 128          4.9         1.8
## 129          5.6         2.1
## 130          5.8         1.6
## 131          6.1         1.9
## 132          6.4         2.0
## 133          5.6         2.2
## 134          5.1         1.5
## 135          5.6         1.4
## 136          6.1         2.3
## 137          5.6         2.4
## 138          5.5         1.8
## 139          4.8         1.8
## 140          5.4         2.1
## 141          5.6         2.4
## 142          5.1         2.3
## 143          5.1         1.9
## 144          5.9         2.3
## 145          5.7         2.5
## 146          5.2         2.3
## 147          5.0         1.9
## 148          5.2         2.0
## 149          5.4         2.3
## 150          5.1         1.8
select(iris.tib, starts_with("Petal"))
## # A tibble: 150 x 2
##    Petal.Length Petal.Width
##           <dbl>       <dbl>
##  1          1.4         0.2
##  2          1.4         0.2
##  3          1.3         0.2
##  4          1.5         0.2
##  5          1.4         0.2
##  6          1.7         0.4
##  7          1.4         0.3
##  8          1.5         0.2
##  9          1.4         0.2
## 10          1.5         0.1
## # … with 140 more rows
select(iris, contains("Width"))
##     Sepal.Width Petal.Width
## 1           3.5         0.2
## 2           3.0         0.2
## 3           3.2         0.2
## 4           3.1         0.2
## 5           3.6         0.2
## 6           3.9         0.4
## 7           3.4         0.3
## 8           3.4         0.2
## 9           2.9         0.2
## 10          3.1         0.1
## 11          3.7         0.2
## 12          3.4         0.2
## 13          3.0         0.1
## 14          3.0         0.1
## 15          4.0         0.2
## 16          4.4         0.4
## 17          3.9         0.4
## 18          3.5         0.3
## 19          3.8         0.3
## 20          3.8         0.3
## 21          3.4         0.2
## 22          3.7         0.4
## 23          3.6         0.2
## 24          3.3         0.5
## 25          3.4         0.2
## 26          3.0         0.2
## 27          3.4         0.4
## 28          3.5         0.2
## 29          3.4         0.2
## 30          3.2         0.2
## 31          3.1         0.2
## 32          3.4         0.4
## 33          4.1         0.1
## 34          4.2         0.2
## 35          3.1         0.2
## 36          3.2         0.2
## 37          3.5         0.2
## 38          3.6         0.1
## 39          3.0         0.2
## 40          3.4         0.2
## 41          3.5         0.3
## 42          2.3         0.3
## 43          3.2         0.2
## 44          3.5         0.6
## 45          3.8         0.4
## 46          3.0         0.3
## 47          3.8         0.2
## 48          3.2         0.2
## 49          3.7         0.2
## 50          3.3         0.2
## 51          3.2         1.4
## 52          3.2         1.5
## 53          3.1         1.5
## 54          2.3         1.3
## 55          2.8         1.5
## 56          2.8         1.3
## 57          3.3         1.6
## 58          2.4         1.0
## 59          2.9         1.3
## 60          2.7         1.4
## 61          2.0         1.0
## 62          3.0         1.5
## 63          2.2         1.0
## 64          2.9         1.4
## 65          2.9         1.3
## 66          3.1         1.4
## 67          3.0         1.5
## 68          2.7         1.0
## 69          2.2         1.5
## 70          2.5         1.1
## 71          3.2         1.8
## 72          2.8         1.3
## 73          2.5         1.5
## 74          2.8         1.2
## 75          2.9         1.3
## 76          3.0         1.4
## 77          2.8         1.4
## 78          3.0         1.7
## 79          2.9         1.5
## 80          2.6         1.0
## 81          2.4         1.1
## 82          2.4         1.0
## 83          2.7         1.2
## 84          2.7         1.6
## 85          3.0         1.5
## 86          3.4         1.6
## 87          3.1         1.5
## 88          2.3         1.3
## 89          3.0         1.3
## 90          2.5         1.3
## 91          2.6         1.2
## 92          3.0         1.4
## 93          2.6         1.2
## 94          2.3         1.0
## 95          2.7         1.3
## 96          3.0         1.2
## 97          2.9         1.3
## 98          2.9         1.3
## 99          2.5         1.1
## 100         2.8         1.3
## 101         3.3         2.5
## 102         2.7         1.9
## 103         3.0         2.1
## 104         2.9         1.8
## 105         3.0         2.2
## 106         3.0         2.1
## 107         2.5         1.7
## 108         2.9         1.8
## 109         2.5         1.8
## 110         3.6         2.5
## 111         3.2         2.0
## 112         2.7         1.9
## 113         3.0         2.1
## 114         2.5         2.0
## 115         2.8         2.4
## 116         3.2         2.3
## 117         3.0         1.8
## 118         3.8         2.2
## 119         2.6         2.3
## 120         2.2         1.5
## 121         3.2         2.3
## 122         2.8         2.0
## 123         2.8         2.0
## 124         2.7         1.8
## 125         3.3         2.1
## 126         3.2         1.8
## 127         2.8         1.8
## 128         3.0         1.8
## 129         2.8         2.1
## 130         3.0         1.6
## 131         2.8         1.9
## 132         3.8         2.0
## 133         2.8         2.2
## 134         2.8         1.5
## 135         2.6         1.4
## 136         3.0         2.3
## 137         3.4         2.4
## 138         3.1         1.8
## 139         3.0         1.8
## 140         3.1         2.1
## 141         3.1         2.4
## 142         3.1         2.3
## 143         2.7         1.9
## 144         3.2         2.3
## 145         3.3         2.5
## 146         3.0         2.3
## 147         2.5         1.9
## 148         3.0         2.0
## 149         3.4         2.3
## 150         3.0         1.8
iris.tib %>% select(contains("Width"))
## # A tibble: 150 x 2
##    Sepal.Width Petal.Width
##          <dbl>       <dbl>
##  1         3.5         0.2
##  2         3           0.2
##  3         3.2         0.2
##  4         3.1         0.2
##  5         3.6         0.2
##  6         3.9         0.4
##  7         3.4         0.3
##  8         3.4         0.2
##  9         2.9         0.2
## 10         3.1         0.1
## # … with 140 more rows

Noter au passage qu’on commence à prendre goût au fait que le tibble s’affiche plus proprement, non ?

Euh oui, et sinon, c’est quoi le %>% ?

filter()

La fonction filter agit dans le même esprit que select mais cette fois-ci sur les observations d’un data.frame (ou d’un vous savez quoi).

filter(mtcars, cyl==6)
##                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Merc 280       19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C      17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
filter(mtcars, between(qsec,16,18))
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
mtcars %>% filter(between(qsec,16,18)) %>%
  arrange(qsec)
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3

Et… %>% ? On en reparle plus loin… regardez bien, il y a une section qui s’appelle comme ça.

summarise()

Pour calculer quelques indicateurs statistiques sur une ou plusieurs variables.

summarise(mtcars_tbl, mean=mean(disp))
## # A tibble: 1 x 1
##    mean
##   <dbl>
## 1  231.
summarise(mtcars_tbl, mean=mean(disp), median= median(disp))
## # A tibble: 1 x 2
##    mean median
##   <dbl>  <dbl>
## 1  231.   196.

Pour calculer ces mêmes indicateurs sur des sous-groupes dépendant d’une variable catégorielle, on peut utiliser au préalable la fonction group_by.

mtcar_by_cyl <- group_by(mtcars_tbl, cyl)
mtcar_by_cyl <- group_by(mtcars, cyl)
summarise(mtcar_by_cyl, mean=mean(disp), median=median(disp))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 3 x 3
##     cyl  mean median
##   <dbl> <dbl>  <dbl>
## 1     4  105.   108 
## 2     6  183.   168.
## 3     8  353.   350.

Notons au passage que même si group_by prend un data.frame en paramètres, le résultat est un grouped tbl (qui peut être “dégrouper” avec la fonction… ungroup.

ungroup(mtcar_by_cyl)
## # A tibble: 32 x 11
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
##  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
##  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
##  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
##  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
##  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
##  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
##  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
##  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
## 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
## # … with 22 more rows

Et même si on ne doit pas encore en parler

mtcars_tbl %>% group_by(cyl) %>% summarise(mean=mean(disp))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 3 x 2
##     cyl  mean
##   <dbl> <dbl>
## 1     4  105.
## 2     6  183.
## 3     8  353.

arrange()

Pour ranger les lignes d’un data.frame (ou …) dans l’ordre croissant ou décroissant d’une variable.

arrange(mtcars, disp)
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
arrange(mtcars_tbl, disp)
## # A tibble: 32 x 12
##    rowname       mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <chr>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1 Toyota Cor…  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
##  2 Honda Civic  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
##  3 Fiat 128     32.4     4  78.7    66  4.08  2.2   19.5     1     1     4     1
##  4 Fiat X1-9    27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
##  5 Lotus Euro…  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
##  6 Datsun 710   22.8     4 108      93  3.85  2.32  18.6     1     1     4     1
##  7 Toyota Cor…  21.5     4 120.     97  3.7   2.46  20.0     1     0     3     1
##  8 Porsche 91…  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
##  9 Volvo 142E   21.4     4 121     109  4.11  2.78  18.6     1     1     4     2
## 10 Merc 230     22.8     4 141.     95  3.92  3.15  22.9     1     0     4     2
## # … with 22 more rows
arrange(mtcars, hp)
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
arrange(mtcars, desc(mpg))
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
mtcars_tbl %>% arrange(disp)
## # A tibble: 32 x 12
##    rowname       mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <chr>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1 Toyota Cor…  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
##  2 Honda Civic  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
##  3 Fiat 128     32.4     4  78.7    66  4.08  2.2   19.5     1     1     4     1
##  4 Fiat X1-9    27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
##  5 Lotus Euro…  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
##  6 Datsun 710   22.8     4 108      93  3.85  2.32  18.6     1     1     4     1
##  7 Toyota Cor…  21.5     4 120.     97  3.7   2.46  20.0     1     0     3     1
##  8 Porsche 91…  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
##  9 Volvo 142E   21.4     4 121     109  4.11  2.78  18.6     1     1     4     2
## 10 Merc 230     22.8     4 141.     95  3.92  3.15  22.9     1     0     4     2
## # … with 22 more rows

%>% ???? On en reparle plus loin…

readr

A voir avec ses propres fichiers. Notez que la sortie des fonctions read_delim, read_csv et autres sera un… tibble bien sûr.

Ces 3 exemples issus de l’aide de la fonction read_delim illustrent le fait que cette fonction décompresse automatiquement des fichiers zip et bz2 avant de les importer.

read_csv(readr_example("mtcars.csv"))
## Parsed with column specification:
## cols(
##   mpg = col_double(),
##   cyl = col_double(),
##   disp = col_double(),
##   hp = col_double(),
##   drat = col_double(),
##   wt = col_double(),
##   qsec = col_double(),
##   vs = col_double(),
##   am = col_double(),
##   gear = col_double(),
##   carb = col_double()
## )
## # A tibble: 32 x 11
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
##  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
##  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
##  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
##  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
##  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
##  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
##  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
##  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
## 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
## # … with 22 more rows
read_csv(readr_example("mtcars.csv.zip"))
## Parsed with column specification:
## cols(
##   mpg = col_double(),
##   cyl = col_double(),
##   disp = col_double(),
##   hp = col_double(),
##   drat = col_double(),
##   wt = col_double(),
##   qsec = col_double(),
##   vs = col_double(),
##   am = col_double(),
##   gear = col_double(),
##   carb = col_double()
## )
## # A tibble: 32 x 11
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
##  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
##  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
##  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
##  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
##  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
##  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
##  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
##  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
## 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
## # … with 22 more rows
read_csv(readr_example("mtcars.csv.bz2"))
## Parsed with column specification:
## cols(
##   mpg = col_double(),
##   cyl = col_double(),
##   disp = col_double(),
##   hp = col_double(),
##   drat = col_double(),
##   wt = col_double(),
##   qsec = col_double(),
##   vs = col_double(),
##   am = col_double(),
##   gear = col_double(),
##   carb = col_double()
## )
## # A tibble: 32 x 11
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
##  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
##  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
##  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
##  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
##  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
##  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
##  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
##  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
## 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
## # … with 22 more rows

stringr

Le package contient tout un tas de fonctions pour faciliter la manipulation des chaînes de caractères. En voici une illustration

La longueur d’une chaîne

DesCaracteres <- "Oh les beaux caracteres !"
str_length(DesCaracteres)
## [1] 25

Concaténer des chaînes

str_c(DesCaracteres, "C'est bien vrai.")
## [1] "Oh les beaux caracteres !C'est bien vrai."
str_c(DesCaracteres, "C'est bien vrai.", sep=" ")
## [1] "Oh les beaux caracteres ! C'est bien vrai."
str_c("Oh, le joli ", c("a","b","c"), ". C'est vrai qu'il est beau.")
## [1] "Oh, le joli a. C'est vrai qu'il est beau."
## [2] "Oh, le joli b. C'est vrai qu'il est beau."
## [3] "Oh, le joli c. C'est vrai qu'il est beau."

Sélectionner des parties

str_sub(DesCaracteres, start = 8, end = 12)
## [1] "beaux"
str_sub(DesCaracteres, start = 1, end = 6)
## [1] "Oh les"
str_sub(DesCaracteres, end = 6)
## [1] "Oh les"
str_sub(DesCaracteres, start = 8)
## [1] "beaux caracteres !"

Et vous pensez que l’on peut… oui.

DesCaracteres %>% str_sub(start=10)
## [1] "aux caracteres !"

Détecter des chaînes…

… qui contiennent une caractère donné

DesFruits <- c("Pomme", "Poire", "Peche", "Abricot", "Melon")
str_detect(DesFruits,"o")
## [1]  TRUE  TRUE FALSE  TRUE  TRUE

… qui commencent ou finissent par un caractère donné

str_detect(DesFruits,"^P")
## [1]  TRUE  TRUE  TRUE FALSE FALSE
str_detect(DesFruits,"e$")
## [1]  TRUE  TRUE  TRUE FALSE FALSE

Pas futé sur cette exemple, le résultat est le même pour les deux ! Trop beau, je le laisse quand même.

str_detect(DesFruits,"t$")
## [1] FALSE FALSE FALSE  TRUE FALSE

Et pour revenir un peu en arrière avec str_sub et un peu en avant avec %>%.

DesFruits %>% str_sub(1, 4)
## [1] "Pomm" "Poir" "Pech" "Abri" "Melo"

Passer de minuscules à majuscules ou inversement

str_to_upper(DesCaracteres)
## [1] "OH LES BEAUX CARACTERES !"
str_to_lower(DesCaracteres)
## [1] "oh les beaux caracteres !"

Il y a encore tout plein de fonctions à explorer dans le package stringr. Commencez à taper str_ dans la console RStudio et regardez…

Un petit dernier quand même

str_view(DesCaracteres, "eau")
str_view(DesFruits, "^P")

forcats

Le package forcats propose de nombreuses fonctions pour faciliter la manipulation des factors (factors <-> forcats, vous saisissez ?).

Ré-ordonner les niveaux d’un facteur

Pour illustrer l’intérêt de la fonction fct_reorder, le plus simple est de passer par un graphique comme cela est suggéré dans l’aide de la fonction.

Regardons des boxplots pour chaque modalité du facteur Species du fameux jeu de données iris

ggplot(iris, aes(x=Species, y = Sepal.Width)) + geom_boxplot()

Ce serait sympa (même si pas forcément très utile ici) de ré-ordonner les boxplots par médiane croissante par exemple.

ggplot(iris,
       aes(x=fct_reorder(Species, Sepal.Width), y = Sepal.Width)) +
  geom_boxplot()

Et voilà, trop facile. On n’a précisé la médiane nulle part car c’est la fonction utilisée par défaut. Mais si on veut modifier le critère de tri, c’est dans l’argument .fun que ça se passe.

Pour trier selon l’écart-type croissant, par exemple, on fait :

ggplot(iris,
       aes(x=fct_reorder(Species, Sepal.Width, .fun=sd),
           y = Sepal.Width)) +
  geom_boxplot()

Le changement n’est pas flagrant vu que l’ordre est le même que par médiane croissante. Et si on veut selon un critère décroissant, on complète avec .desc.

ggplot(iris,
       aes(x=fct_reorder(Species, Sepal.Width, .fun=sd, .desc=TRUE),
           y = Sepal.Width)) +
  geom_boxplot()

Manipuler des facteurs ordonnés

Les facteurs ordonnées sont utiles pour gérer des variables qualitatives ordonnées comme par exemple “Un peu” qui est une modalité inférieure à “Beaucoup” elle même inférieure à “Passionnément”.

f <- factor(c("b", "b", "a", "c", "c", "c"))
fct_infreq(f, ordered = TRUE)
## [1] b b a c c c
## Levels: c < b < a
fct_inorder(f, ordered = TRUE) #  # match the order of the first appearance in the data.
## [1] b b a c c c
## Levels: b < a < c
f <- factor(c(7,4,1,8,10,10,3,7,8,4,3,4))
fct_inseq(f, ordered = TRUE)
##  [1] 7  4  1  8  10 10 3  7  8  4  3  4 
## Levels: 1 < 3 < 4 < 7 < 8 < 10
fct_inorder(f, ordered = TRUE)
##  [1] 7  4  1  8  10 10 3  7  8  4  3  4 
## Levels: 7 < 4 < 1 < 8 < 10 < 3
fct_infreq(f, ordered = TRUE)
##  [1] 7  4  1  8  10 10 3  7  8  4  3  4 
## Levels: 4 < 3 < 7 < 8 < 10 < 1

Dans les exemple ci-dessus, on voit que la fonction

  • fct_inseq réordonne les niveaux d’un facteur en fonction de l’ordre numérique

  • fct_inorder réordonne les niveaux d’un facteur en fonction de leur ordre d’apparition dans les données

  • fct_infreq les niveaux d’un facteur en fonction de leur effectif

Et bien entendu :

f %>% fct_infreq(ordered=TRUE)
##  [1] 7  4  1  8  10 10 3  7  8  4  3  4 
## Levels: 4 < 3 < 7 < 8 < 10 < 1

Calculer les effectifs par modalité d’un facteur

[Exemples tirés de l’aide de la fonction fct_count]

Pour calculer les effectifs par modalité d’un facteur, on connaît la fonction table, pas de souci particulier de ce côté-là.

f <- factor(sample(letters)[rpois(1000, 10)])
table(f)
## f
##   a   b   c   d   g   h   i   j   k   l   m   n   o   s   t   w   x   y   z 
## 101  57  61  62 129   7 123   3 121  36  35   1  21  18  88 114   3  14   6

Mais regardons quand même ce que nous propose la fonction fct_count.

fct_count(f)
## # A tibble: 19 x 2
##    f         n
##    <fct> <int>
##  1 a       101
##  2 b        57
##  3 c        61
##  4 d        62
##  5 g       129
##  6 h         7
##  7 i       123
##  8 j         3
##  9 k       121
## 10 l        36
## 11 m        35
## 12 n         1
## 13 o        21
## 14 s        18
## 15 t        88
## 16 w       114
## 17 x         3
## 18 y        14
## 19 z         6

OK, on reconnaît un tibble, pourquoi pas, mais rien de révolutionnaire.

Explorons un peu plus :

fct_count(f, sort = TRUE)
## # A tibble: 19 x 2
##    f         n
##    <fct> <int>
##  1 g       129
##  2 i       123
##  3 k       121
##  4 w       114
##  5 a       101
##  6 t        88
##  7 d        62
##  8 c        61
##  9 b        57
## 10 l        36
## 11 m        35
## 12 o        21
## 13 s        18
## 14 y        14
## 15 h         7
## 16 z         6
## 17 j         3
## 18 x         3
## 19 n         1

Pourquoi pas, mais on peut aussi s’en sortir avec

sort(table(f), decreasing = TRUE)
## f
##   g   i   k   w   a   t   d   c   b   l   m   o   s   y   h   z   j   x   n 
## 129 123 121 114 101  88  62  61  57  36  35  21  18  14   7   6   3   3   1

Un petit dernier peut-être :

fct_count(f, sort = TRUE, prop = TRUE)
## # A tibble: 19 x 3
##    f         n     p
##    <fct> <int> <dbl>
##  1 g       129 0.129
##  2 i       123 0.123
##  3 k       121 0.121
##  4 w       114 0.114
##  5 a       101 0.101
##  6 t        88 0.088
##  7 d        62 0.062
##  8 c        61 0.061
##  9 b        57 0.057
## 10 l        36 0.036
## 11 m        35 0.035
## 12 o        21 0.021
## 13 s        18 0.018
## 14 y        14 0.014
## 15 h         7 0.007
## 16 z         6 0.006
## 17 j         3 0.003
## 18 x         3 0.003
## 19 n         1 0.001

OK, on pourrait aussi s’en sortir sans la fonction fct_count, mais c’est quand même pas mal.

Combiner les niveaux de facteurs pour créer un nouveau facteur

Pour certaines analyses statistiques, il peut être utile de croiser différents facteurs pour en faire un seul. Cela est quasiment immédiat avec la fonction fct_cross.

Genotype <- factor(c("WT","Mut","WT","Mut","WT","Mut"))
Condition <- factor(c("CTRL","CTRL", "CTRL", "Trait", "Trait", "Trait"))
Temperature <- c("Low","High","High", "High", "High", "Low")
fct_cross(Genotype, Condition)
## [1] WT:CTRL   Mut:CTRL  WT:CTRL   Mut:Trait WT:Trait  Mut:Trait
## Levels: Mut:CTRL WT:CTRL Mut:Trait WT:Trait
fct_cross(Genotype, Condition, sep="_")
## [1] WT_CTRL   Mut_CTRL  WT_CTRL   Mut_Trait WT_Trait  Mut_Trait
## Levels: Mut_CTRL WT_CTRL Mut_Trait WT_Trait
fct_cross(Genotype, Condition, Temperature, sep="_")
## [1] WT_CTRL_Low    Mut_CTRL_High  WT_CTRL_High   Mut_Trait_High WT_Trait_High 
## [6] Mut_Trait_Low 
## 6 Levels: Mut_CTRL_High WT_CTRL_High Mut_Trait_High ... Mut_Trait_Low
fct_cross(Genotype, Condition, Temperature, sep="_", keep_empty = TRUE)
## [1] WT_CTRL_Low    Mut_CTRL_High  WT_CTRL_High   Mut_Trait_High WT_Trait_High 
## [6] Mut_Trait_Low 
## 8 Levels: Mut_CTRL_High WT_CTRL_High Mut_Trait_High ... WT_Trait_Low

Ajouter des niveaux à un facteur

Pour ajouter un ou des niveaux à un facteur existant, on peut utiliser la fonction fct_expand.

fct_expand(Condition, "Trait2")
## [1] CTRL  CTRL  CTRL  Trait Trait Trait
## Levels: CTRL Trait Trait2
fct_expand(Condition, "Trait2", "Trait3")
## [1] CTRL  CTRL  CTRL  Trait Trait Trait
## Levels: CTRL Trait Trait2 Trait3

On arriverait à des résultat similaire en jouant avec la fonction levels, mais bon, on a mis les pieds dans le tidyverse, alors on essaie de jouer le jeu.

Regrouper certains niveaux d’un facteur

Où l’on apprend que to lump signifie mettre en bloc, en masse, en tas et que to lump things together signifie réunir des choses ensemble.

Donc, on va commencer par créer un facteur avec des modalités plus ou moins fréquentes. L’aide en ligne de la fonction fct_lump nous propose par exemple :

f <- factor(rep(LETTERS[1:9], times = c(40, 10, 5, 27, 1, 1, 1, 1, 1)))
f %>% fct_count()
## # A tibble: 9 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 B        10
## 3 C         5
## 4 D        27
## 5 E         1
## 6 F         1
## 7 G         1
## 8 H         1
## 9 I         1
f %>% fct_count(sort=TRUE)
## # A tibble: 9 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 D        27
## 3 B        10
## 4 C         5
## 5 E         1
## 6 F         1
## 7 G         1
## 8 H         1
## 9 I         1

On a ainsi 40 fois la modalité A, 10 fois B, 5 fois C, 27 fois D et une fois chaque lettre suivante jusqu’à I (merci fct_count quand même).

Voyons ce que nous propose cette fonction fct_lump

fct_lump(f)
##  [1] A     A     A     A     A     A     A     A     A     A     A     A    
## [13] A     A     A     A     A     A     A     A     A     A     A     A    
## [25] A     A     A     A     A     A     A     A     A     A     A     A    
## [37] A     A     A     A     Other Other Other Other Other Other Other Other
## [49] Other Other Other Other Other Other Other D     D     D     D     D    
## [61] D     D     D     D     D     D     D     D     D     D     D     D    
## [73] D     D     D     D     D     D     D     D     D     D     Other Other
## [85] Other Other Other
## Levels: A D Other
f %>% fct_lump()
##  [1] A     A     A     A     A     A     A     A     A     A     A     A    
## [13] A     A     A     A     A     A     A     A     A     A     A     A    
## [25] A     A     A     A     A     A     A     A     A     A     A     A    
## [37] A     A     A     A     Other Other Other Other Other Other Other Other
## [49] Other Other Other Other Other Other Other D     D     D     D     D    
## [61] D     D     D     D     D     D     D     D     D     D     D     D    
## [73] D     D     D     D     D     D     D     D     D     D     Other Other
## [85] Other Other Other
## Levels: A D Other

OK, on voit des Other là où il y avait d’autres choses, mais qui, quoi, comment, pourquoi ???? Essayons d’y voir plus clair.

f %>% fct_lump() %>% fct_count()
## # A tibble: 3 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 D        27
## 3 Other    20

Tiens, c’est pas mal ce truc %>%.

Bon alors, il a gardé les 2 modalités les plus présentes et il a regroupé les autres dans Other, d’accord mais pourquoi les 2 premières seulement.

Parce que : If both n and prop are missing, fct_lump lumps together the least frequent levels into “other”, while ensuring that “other” is still the smallest level.

Effectivement, je n’ai précisé ni n ni prop, donc il a regroupé des modalités tout en s’assurant que Other soit le niveau le moins représenté. OK, pourquoi pas.

On va jouer avec n et prop pour voir…

fct_lump(f, n=3)
##  [1] A     A     A     A     A     A     A     A     A     A     A     A    
## [13] A     A     A     A     A     A     A     A     A     A     A     A    
## [25] A     A     A     A     A     A     A     A     A     A     A     A    
## [37] A     A     A     A     B     B     B     B     B     B     B     B    
## [49] B     B     Other Other Other Other Other D     D     D     D     D    
## [61] D     D     D     D     D     D     D     D     D     D     D     D    
## [73] D     D     D     D     D     D     D     D     D     D     Other Other
## [85] Other Other Other
## Levels: A B D Other
fct_count(fct_lump(f, n=3))
## # A tibble: 4 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 B        10
## 3 D        27
## 4 Other    10

Bouh, c’est lourd cette dernière commande, et si… oui, vas-y, just do it.

f %>% fct_lump(n=3) %>% fct_count()
## # A tibble: 4 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 B        10
## 3 D        27
## 4 Other    10

Ouais, pas mal quand même. Et donc, fct_lump a gardé ici les 3 modalités les plus représentées et a regroupé les autres dans Other. Et pour prop, on commence à deviner :

f %>% fct_lump(prop=.3) %>% fct_count()
## # A tibble: 3 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 D        27
## 3 Other    20
f %>% fct_lump(prop=.1) %>% fct_count()
## # A tibble: 4 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 B        10
## 3 D        27
## 4 Other    10

La sélection se fait sur la proportion que représente chaque modalité.

Si vous voulez modifier le nom de cette modalité “autre”, c’est possible.

f %>% fct_lump(n=3, other_level = "Autre") %>% fct_count()
## # A tibble: 4 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 B        10
## 3 D        27
## 4 Autre    10

Une façon plus “autoritaire” de réaliser des choses assez similaires consiste à utiliser la fonction fct_other.

MonFact <- fct_other(f, keep=c("A","E","I"))
MonFact %>% fct_count()
## # A tibble: 4 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 E         1
## 3 I         1
## 4 Other    45
MonFactBis <- fct_other(f, drop=c("B","F","G"))
fct_count(MonFactBis)
## # A tibble: 7 x 2
##   f         n
##   <fct> <int>
## 1 A        40
## 2 C         5
## 3 D        27
## 4 E         1
## 5 H         1
## 6 I         1
## 7 Other    12

On décide ainsi de conserver (keep) ou de laisser tomber (drop) les modalités de notre choix sans aucune considération des effectifs ou des proportions.

Il y a encore tout plein de fonctions à explorer dans le package forcats. Commencez à taper fct_ dans la console RStudio et regardez… J’ai l’impression d’avoir déjà lu ça quelque part.

tidyr

L’utilisation du package tidyr vise à obtenir des données tidy. Des données tidy sont caractérisées par 3 règles :

Tous les packages du tidyverse sont conçus pour travailler avec des données tidy. Quand les jeux de données que l’on manipule ne le sont pas, les fonctions du package tidyr vont nous permettre de les tidyser ou tidyfier (choisissez votre néologisme préféré).

Il est difficile de passer en revue tous les cas de figure de données non tidy à rendre tidy car Tidy datasets are all alike, but every messy dataset is messy in its own way (HW) , mais essayons quand même d’illustrer quelques cas.

pivot_longer

relig_income
## # A tibble: 18 x 11
##    religion `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k` `$75-100k`
##    <chr>      <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>      <dbl>
##  1 Agnostic      27        34        60        81        76       137        122
##  2 Atheist       12        27        37        52        35        70         73
##  3 Buddhist      27        21        30        34        33        58         62
##  4 Catholic     418       617       732       670       638      1116        949
##  5 Don’t k…      15        14        15        11        10        35         21
##  6 Evangel…     575       869      1064       982       881      1486        949
##  7 Hindu          1         9         7         9        11        34         47
##  8 Histori…     228       244       236       238       197       223        131
##  9 Jehovah…      20        27        24        24        21        30         15
## 10 Jewish        19        19        25        25        30        95         69
## 11 Mainlin…     289       495       619       655       651      1107        939
## 12 Mormon        29        40        48        51        56       112         85
## 13 Muslim         6         7         9        10         9        23         16
## 14 Orthodox      13        17        23        32        32        47         38
## 15 Other C…       9         7        11        13        13        14         18
## 16 Other F…      20        33        40        46        49        63         46
## 17 Other W…       5         2         3         4         2         7          3
## 18 Unaffil…     217       299       374       365       341       528        407
## # … with 3 more variables: `$100-150k` <dbl>, `>150k` <dbl>, `Don't
## #   know/refused` <dbl>
relig_income %>%
 pivot_longer(-religion, names_to = "income", values_to = "count")
## # A tibble: 180 x 3
##    religion income             count
##    <chr>    <chr>              <dbl>
##  1 Agnostic <$10k                 27
##  2 Agnostic $10-20k               34
##  3 Agnostic $20-30k               60
##  4 Agnostic $30-40k               81
##  5 Agnostic $40-50k               76
##  6 Agnostic $50-75k              137
##  7 Agnostic $75-100k             122
##  8 Agnostic $100-150k            109
##  9 Agnostic >150k                 84
## 10 Agnostic Don't know/refused    96
## # … with 170 more rows

Oups, ça m’a échappé, je voulais bien sûr écrire

pivot_longer(relig_income, -religion,
             names_to = "income", values_to = "count")
## # A tibble: 180 x 3
##    religion income             count
##    <chr>    <chr>              <dbl>
##  1 Agnostic <$10k                 27
##  2 Agnostic $10-20k               34
##  3 Agnostic $20-30k               60
##  4 Agnostic $30-40k               81
##  5 Agnostic $40-50k               76
##  6 Agnostic $50-75k              137
##  7 Agnostic $75-100k             122
##  8 Agnostic $100-150k            109
##  9 Agnostic >150k                 84
## 10 Agnostic Don't know/refused    96
## # … with 170 more rows

On passe ainsi d’un tableau de dimension 18 x 11 à un tableau de dimension 180 x 3. Le tableau en sortie étant plus long (plus de lignes) que le tableau en entrée, c’est la fonction pivot_longer qui a permis de rendre tidy le jeu de données qui avait initialement une variable en nom de colonnes.

pivot_wider

A l’opposé, pour générer un tableau ayant à la sortie plus de colonnes qu’en entrée, c’est la fonction pivot_wider qui est utilisée.

fish_encounters
## # A tibble: 114 x 3
##    fish  station  seen
##    <fct> <fct>   <int>
##  1 4842  Release     1
##  2 4842  I80_1       1
##  3 4842  Lisbon      1
##  4 4842  Rstr        1
##  5 4842  Base_TD     1
##  6 4842  BCE         1
##  7 4842  BCW         1
##  8 4842  BCE2        1
##  9 4842  BCW2        1
## 10 4842  MAE         1
## # … with 104 more rows
fish_encounters %>%
  pivot_wider(names_from = station, values_from = seen)
## # A tibble: 19 x 12
##    fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE   MAW
##    <fct>   <int> <int>  <int> <int>   <int> <int> <int> <int> <int> <int> <int>
##  1 4842        1     1      1     1       1     1     1     1     1     1     1
##  2 4843        1     1      1     1       1     1     1     1     1     1     1
##  3 4844        1     1      1     1       1     1     1     1     1     1     1
##  4 4845        1     1      1     1       1    NA    NA    NA    NA    NA    NA
##  5 4847        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA
##  6 4848        1     1      1     1      NA    NA    NA    NA    NA    NA    NA
##  7 4849        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
##  8 4850        1     1     NA     1       1     1     1    NA    NA    NA    NA
##  9 4851        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
## 10 4854        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
## 11 4855        1     1      1     1       1    NA    NA    NA    NA    NA    NA
## 12 4857        1     1      1     1       1     1     1     1     1    NA    NA
## 13 4858        1     1      1     1       1     1     1     1     1     1     1
## 14 4859        1     1      1     1       1    NA    NA    NA    NA    NA    NA
## 15 4861        1     1      1     1       1     1     1     1     1     1     1
## 16 4862        1     1      1     1       1     1     1     1     1    NA    NA
## 17 4863        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
## 18 4864        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
## 19 4865        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA

On passe ici d’un tableau 19 x 12 à un tableau 114 x 3.

Le package tidyr a connu une évolution importante ces derniers temps. Celles et ceux qui l’avaient déjà utilisé connaissait peut-être les fonctions gather et spread. Ces fonctions existent toujours, mais les développeurs suggèrent d’utiliser maintenant les fonctions pivot_longer et pivot_wider qui leur ont succédé.

purrr

Le package purrr (au fait purr signifie ronronner ce qui explique le chat que l’on voit confortablement installé dans le hex sticker du package) est peut-être l’un des plus puissants du tidyverse. En contrepartie, il est d’accès un peu délicat. En bref, on peut le voir comme une extension de la famille des *apply de R base. Voyons quelques exemples sachant qu’une découverte approfondie de ce package prendrait un temps certain. Notons également qu’en date du 4 mars 2020, ce package est en encore en cours d’évolution (version 0.3.3) et qu’il est susceptible de connaître des changements dans les mois à venir (voir par exemple l’aide de la fonction rerun qui précise que cette fonction is in the questioning lifecycle stage because we are no longer convinced NSE functions are a good fit for purrr).

detect et detect_index

Ces fonctions permettent de trouver la valeur (detect) ou la position (detect_index) d’un élément vérifiant une condition.

Regardons des exemples tirés de l’aide en ligne de ces fonctions. Cela commence avec la définition d’une fonction qui teste la parité d’un nombre avec l’opérateur %% qui renvoie le reste de la division entière de 2 nombres. Pour obtenir de l’aide sur cet opérateur : ?"%%".

is_even <- function(x) x %% 2 == 0
vect <- 5:12
vect
## [1]  5  6  7  8  9 10 11 12
detect(vect, is_even)
## [1] 6
detect_index(vect, is_even)
## [1] 2

Dans le vecteur 5:12, le premier nombre pair est 6 et il est en position 2 dans le vecteur.

Il va de soi que l’on obtient les mêmes résultats avec vous savez quoi.

vect %>% detect(is_even)
## [1] 6
vect %>% detect_index(is_even)
## [1] 2

keep et discard

Sur la base du même exemple que précédemment, on peut vouloir conserver toutes les éléments qui vérifient une condition. On utilise pour cela la fonction keep. A contrario, si on veut les supprimer, c’est la fonction discard qui fait le travail.

keep(vect, is_even)
## [1]  6  8 10 12
discard(vect, is_even)
## [1]  5  7  9 11

OK, on peut très bien s’en sortir avec nos vieilles habitudes de R user de la première heure.

vect[is_even(vect)]
## [1]  6  8 10 12
setdiff(vect, vect[is_even(vect)])
## [1]  5  7  9 11

Mais, en toute sincérité, reconnaissons que la version purrresque est quand même plus lisible, non ? Et en plus %>% !

vect %>% keep(is_even)
## [1]  6  8 10 12

flatten

La fonction flatten est assez similaire à la fonction unlist pour “délister” un objet list

(x_list <- list(1:4, 10:15))
## [[1]]
## [1] 1 2 3 4
## 
## [[2]]
## [1] 10 11 12 13 14 15
flatten(x_list) # équivalent à vous savez quoi
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 2
## 
## [[3]]
## [1] 3
## 
## [[4]]
## [1] 4
## 
## [[5]]
## [1] 10
## 
## [[6]]
## [1] 11
## 
## [[7]]
## [1] 12
## 
## [[8]]
## [1] 13
## 
## [[9]]
## [1] 14
## 
## [[10]]
## [1] 15
unlist(x_list)
##  [1]  1  2  3  4 10 11 12 13 14 15

Elle est accompagnée d’autres fonctions (flatten_*) qui permettent de contrôler le type de l’objet en sortie.

x_list %>% flatten_int()
##  [1]  1  2  3  4 10 11 12 13 14 15
x_list %>% flatten_chr()
##  [1] "1"  "2"  "3"  "4"  "10" "11" "12" "13" "14" "15"

map

Un des intérêts principaux du package purrr réside dans les fonctions map et map_*. Elles visent à rendre plus clair et plus lisible un code nécessitant de reproduire la même action sur un ensemble de choses.

Considérons l’exemple tiré de r4ds.had.co.nz (section Iteration).

(MyData <- tibble(
    a = rnorm(10),
    b = rnorm(10),
    c = rnorm(10),
    d = rnorm(10)
))
## # A tibble: 10 x 4
##         a      b      c       d
##     <dbl>  <dbl>  <dbl>   <dbl>
##  1 -0.136  0.192 -1.80   0.212 
##  2 -0.364  0.319  1.79  -0.176 
##  3  0.932 -0.164 -0.792  0.575 
##  4 -0.849  0.115  0.450 -2.36  
##  5 -1.17  -1.09   0.774  0.620 
##  6  0.798  0.952 -0.543  1.70  
##  7 -0.170 -1.01   1.52  -1.42  
##  8 -0.809  0.127 -0.789 -0.0617
##  9 -0.341 -1.33   0.770 -0.752 
## 10 -0.311 -1.37   0.728 -1.00
MyData %>% map(mean)
## $a
## [1] -0.2422708
## 
## $b
## [1] -0.3264686
## 
## $c
## [1] 0.2101694
## 
## $d
## [1] -0.2665096
MyData %>% map_dbl(mean)
##          a          b          c          d 
## -0.2422708 -0.3264686  0.2101694 -0.2665096
MyData %>% map_dbl(sd)
##         a         b         c         d 
## 0.6721710 0.8093341 1.1440113 1.1613673

OK, on sait très bien faire ça à coup de apply.

apply(MyData, 2, mean)
##          a          b          c          d 
## -0.2422708 -0.3264686  0.2101694 -0.2665096

Et on peut retrouver la plupart des résultat fournis par la fonction map en utilisant la famille des fonctions apply : lapply, sapply, mapply. Mais, encore une fois, l’intérêt de map réside essentiellement dans la clarté du code qu’elle permet d’écrire.

A noter également, les sympathiques fonctions map_if et map_at qui réalisent un map sous condition.

map_if(vect, is_even, log2)
## [[1]]
## [1] 5
## 
## [[2]]
## [1] 2.584963
## 
## [[3]]
## [1] 7
## 
## [[4]]
## [1] 3
## 
## [[5]]
## [1] 9
## 
## [[6]]
## [1] 3.321928
## 
## [[7]]
## [1] 11
## 
## [[8]]
## [1] 3.584963
map_if(vect, is_even, log2) %>% flatten_dbl()
## [1]  5.000000  2.584963  7.000000  3.000000  9.000000  3.321928 11.000000
## [8]  3.584963
map_at(vect, c(2,5), exp) %>% flatten_dbl()
## [1]    5.0000  403.4288    7.0000    8.0000 8103.0839   10.0000   11.0000
## [8]   12.0000

Le package purrr contient bien d’autres fonctions que vous aurez l’occasion de découvrir selon vos besoins…

Mais quel est donc ce symbole %>% ?

Finalement, est-il toujours utile d’en parler ?

Bon, si juste un dernier petit truc

library(ggplot2)
mtcars %>% ggplot(aes(x=disp, y=drat)) +
  geom_point() +
  facet_wrap(~cyl)

Et oui, ça marche aussi pour les graphiques. Bienvenue dans le tidyverse !