Dplyr mutate(): Opret kolonner (variabler)

Med mutate() oprettes nye variabler. Funktionen tilføjer de nye variabler til de eksisterende. Du kan også bruge mutate() til at ændre eksisterende variabler.

Funktionen transmute() opretter også variabler, men transmute() fjerner alle andre variabler, som ikke oprettes eller nævnes i transmute().

For at oprette eller ændre variabler med mutate() angives navnet på variablen (som skal oprettes eller ændres) efterfulgt af, hvordan variablen skal defineres. I følgende eksempel oprettes variablen ny_variabel ved at multiplicere cyl med 2:

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

Du kan oprette flere nye variabler på én gang med mutate() ved at adskille variablerne med kommaer. Du kan også bruge variabler, som netop er blevet oprettet. I eksemplet nedenfor oprettes ny_variabel, som derefter bruges direkte til at oprette 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

Funktionen case_when() kan bruges til at oprette en variabel ud fra betingelser. Dette er mere effektivt end funktionen ifelse(), som ofte resulterer i besværlig kode. Nedenfor oprettes variablen ny_variabel ud fra informationen i variablen displ. Hvis displ er <2, bliver ny_variabel lig med 0. Hvis displ er <3, bliver ny_variabel lig med 1. Hvis displ er >3, bliver ny_variabel lig med 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

Du kan bruge case_when() til at oprette kategoriske variabler med strenge:

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()

Funktionen across() gør det muligt at anvende mutate() på mange kolonner på én gang. Funktionen er nyttig, når man vil foretage ændringer i mange eksisterende variabler på én gang. Funktionen mutate() kombineres med <tidy-select>, som er funktioner, der angiver kolonner på en meget effektiv måde. Et eksempel på <tidy-select> er everything(), som betyder "alle variabler".

For at demonstrere across opretter vi en ny dataframe ved hjælp af funktionen 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

Der er to numeriske kolonner (var1, var3), som vi nu skal beregne kvadratroden af. Kvadratroden beregnes med funktionen sqrt. Kolonnerne var1 og var3 er kolonne nummer 1 og 3. Følgende kommandoer er ækvivalente:

## Kvadratroden af var1 og var3
my_data %>%
  mutate(across(c(var1, var3), sqrt))

## Som ovenfor, men nu med indeks på kolonnerne
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

Som det fremgår ovenfor, erstattes de eksisterende kolonner. Hvis vi vil have funktionen til at oprette nye kolonner, bruger vi argumentet .names, hvor vi har mulighed for at angive et suffiks eller præfiks for de nye kolonner:

## Kvadratroden af var1 og var3.
## Nye kolonner får suffikset "_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

Mere komplicerede funktioner kan defineres med tilde (~), og den aktuelle værdi på hver række repræsenteres med pladsholderen .x. I næste eksempel vælger vi alle numeriske kolonner, kvadrerer værdien og gemmer den i en ny kolonne med præfikset "ny_":

## Vælg numeriske kolonner, kvadrér dem, gem resultatet i nye kolonner med præfikset "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

Nedenfor følger mutate() og across() med matchning på variabelnavnenes strenge:

Her modificeres kolonner, der indeholder tegnet "1":

## Modificerer kolonner, der indeholder tallet 1 i kolonnenavnet
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

Her modificeres kolonner, der slutter med tegnet "3":

## Modificerer kolonner, der slutter med tegnet 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