Dplyr mutate() : créer des colonnes (variables)

La fonction mutate() permet de créer de nouvelles variables. Elle ajoute les nouvelles variables à celles qui existent déjà. Vous pouvez également utiliser mutate() pour modifier des variables existantes.

La fonction transmute() crée elle aussi des variables, mais transmute() supprime toutes les autres variables qui ne sont pas créées ou mentionnées dans transmute().

Pour créer ou modifier des variables avec mutate(), on indique le nom de la variable (à créer ou à modifier), suivi de la manière dont elle doit être définie. Dans l'exemple suivant, la variable ny_variabel est créée en multipliant cyl par 2 :

mpg |>
  mutate(ny_variabel = cyl*2)
cyl         ny_variabel
4           8
4           8
4           8
4           8
6          12

Vous pouvez créer plusieurs nouvelles variables en même temps avec mutate() en les séparant par des virgules. Vous pouvez aussi utiliser des variables qui viennent d'être créées. Dans l'exemple ci-dessous, ny_variabel est créée puis utilisée immédiatement pour créer ny_variabel2.

mpg |>
  mutate(ny_variabel  = cyl*2,
         ny_variabel2 = ny_variabel^2)
cyl     ny_variabel  ny_variabel2
4       8            64
4       8            64
4       8            64
4       8            64
6       12           144

La fonction case_when() permet de créer une variable à partir de conditions. Elle est plus efficace que la fonction ifelse(), qui conduit souvent à un code alambiqué. Ci-dessous, la variable ny_variabel est créée à partir des informations contenues dans la variable displ. Si displ est <2, ny_variabel vaut 0. Si displ est <3, ny_variabel vaut 1. Si displ est >3, ny_variabel vaut 2.

mpg |> mutate(ny_variabel = case_when(displ < 2 ~ 0,
                                      displ < 3 ~ 1,
                                      displ > 3 ~ 2))
## A tibble: 234 × 2
displ ny_variabel
1.8           0
1.8           0
2             1
2             1
2.8           1
2.8           1
3.1           2
1.8           0
1.8           0
2             1

Vous pouvez utiliser case_when() pour créer des variables catégorielles à partir de chaînes de caractères :

mpg |> mutate(ny_variabel = case_when(displ < 2 ~ 'Lite',
                                      displ < 3 ~ 'Lagom',
                                      displ > 3 ~ 'Mycket'))
## A tibble: 234 × 2
displ ny_variabel
1.8   Lite
1.8   Lite
2     Lagom
2     Lagom
2.8   Lagom
2.8   Lagom
3.1   Mycket
1.8   Lite
1.8   Lite
2     Lagom

across()

La fonction across() permet d'appliquer mutate() à de nombreuses colonnes simultanément. Elle est utile pour modifier de nombreuses variables existantes en une seule fois. La fonction mutate() se combine avec <tidy-select>, c'est-à-dire des fonctions qui désignent des colonnes de manière très efficace. Un exemple de <tidy-select> est everything(), qui signifie « toutes les variables ».

Pour illustrer across, nous créons un nouveau data frame à l'aide de la fonction tibble() :

my_data <-
  tibble(var1 = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
         var2 = c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
         var3 = c(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000))

my_data
var1  var2   var3
1     a       100
2     b       200
3     c       300
4     d       400
5     e       500
6     f       600
7     g       700
8     h       800
9     i       900
10    j      1000

Il y a deux colonnes numériques (var1, var3) dont nous allons maintenant calculer la racine carrée. La racine carrée se calcule avec la fonction sqrt. Les colonnes var1 et var3 sont les colonnes numéro 1 et 3. Les commandes suivantes sont équivalentes :

## Racine carrée de var1 et var3
my_data %>%
  mutate(across(c(var1, var3), sqrt))

## Comme ci-dessus, mais avec l'indice des colonnes
my_data %>%
  mutate(across(c(1, 3), sqrt))
var1  var2   var3
1     a      10
1.41  b      14.1
1.73  c      17.3
2     d      20
2.24  e      22.4
2.45  f      24.5
2.65  g      26.5
2.83  h      28.3
3     i      30
3.16  j      31.6

Comme on le voit ci-dessus, les colonnes existantes sont remplacées. Si nous voulons que la fonction crée de nouvelles colonnes, nous utilisons l'argument .names, qui permet de spécifier un suffixe ou un préfixe pour les nouvelles colonnes :

## Racine carrée de var1 et var3.
## Les nouvelles colonnes reçoivent le suffixe "_kvadratrot"
my_data %>%
  mutate(across(c(1, 3), sqrt, .names="{col}_kvadratrot"))
    var1 var2   var3     var1_kvadratrot   var3_kvadratrot
       1 a       100            1               10
       2 b       200            1.41            14.1
       3 c       300            1.73            17.3
       4 d       400            2               20
       5 e       500            2.24            22.4
       6 f       600            2.45            24.5
       7 g       700            2.65            26.5
       8 h       800            2.83            28.3
       9 i       900            3               30
       10 j      1000            3.16            31.6

Des fonctions plus complexes peuvent être définies avec le tilde (~), et la valeur courante de chaque ligne est représentée par l'espace réservé .x. Dans l'exemple suivant, nous sélectionnons toutes les colonnes numériques, élevons leur valeur au carré et l'enregistrons dans une nouvelle colonne avec le préfixe "ny_" :

## Sélectionner les colonnes numériques, les élever au carré, enregistrer le résultat dans de nouvelles colonnes avec le préfixe "ny_"
my_data %>%
  mutate(across(where(is.numeric), ~ .x^2, .names = "ny_{col}"))
## A tibble: 10 × 5
    var1 var2   var3 ny_var1 ny_var3
   <dbl> <chr> <dbl>   <dbl>   <dbl>
 1     1 a       100       1   10000
 2     2 b       200       4   40000
 3     3 c       300       9   90000
 4     4 d       400      16  160000
 5     5 e       500      25  250000
 6     6 f       600      36  360000
 7     7 g       700      49  490000
 8     8 h       800      64  640000
 9     9 i       900      81  810000
10    10 j      1000     100 1000000

Voici maintenant mutate() et across() avec des correspondances sur les chaînes de caractères des noms de variables :

Ici, on modifie les colonnes qui contiennent le caractère "1" :

## Modifie les colonnes dont le nom contient le chiffre 1
my_data %>%
  mutate(across(matches('1'), ~ .x^2, .names = "ny_{col}"))
## A tibble: 10 × 4
    var1 var2   var3 ny_var1
   <dbl> <chr> <dbl>   <dbl>
 1     1 a       100       1
 2     2 b       200       4
 3     3 c       300       9
 4     4 d       400      16
 5     5 e       500      25
 6     6 f       600      36
 7     7 g       700      49
 8     8 h       800      64
 9     9 i       900      81
10    10 j      1000     100

Ici, on modifie les colonnes qui se terminent par le caractère "3" :

## Modifie les colonnes qui se terminent par le caractère 3
my_data %>%
  mutate(across(ends_with('3'), ~ .x^2, .names = "ny_{col}"))
## A tibble: 10 × 4
    var1 var2   var3 ny_var3
   <dbl> <chr> <dbl>   <dbl>
 1     1 a       100   10000
 2     2 b       200   40000
 3     3 c       300   90000
 4     4 d       400  160000
 5     5 e       500  250000
 6     6 f       600  360000
 7     7 g       700  490000
 8     8 h       800  640000
 9     9 i       900  810000
10    10 j      1000 1000000