Dplyr mutate(): Lage kolonner (variabler)

Med mutate() lages nye variabler. Funksjonen legger de nye variablene til de eksisterende. Du kan også bruke mutate() til å endre eksisterende variabler.

Funksjonen transmute() lager også variabler, men transmute() fjerner alle andre variabler som ikke lages eller nevnes i transmute().

For å lage eller endre variabler med mutate() angir du navnet på variabelen (som skal lages eller endres), etterfulgt av hvordan variabelen skal defineres. I eksempelet nedenfor lages variabelen ny_variabel ved å multiplisere cyl med 2:

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

Du kan lage flere nye variabler samtidig med mutate() ved å skille variablene med komma. Du kan også bruke variabler som nettopp er laget. I eksempelet nedenfor lages ny_variabel, som deretter brukes direkte til å lage 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

Funksjonen case_when() kan brukes til å lage en variabel basert på betingelser. Dette er mer effektivt enn funksjonen ifelse(), som ofte gir tungvint kode. Nedenfor lages variabelen ny_variabel basert på informasjonen i variabelen displ. Hvis displ er <2, blir ny_variabel lik 0. Hvis displ er <3, blir ny_variabel lik 1. Hvis displ er >3, blir ny_variabel lik 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 bruke case_when() til å lage kategoriske variabler med tekststrenger:

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

Funksjonen across() gjør det mulig å bruke mutate() på mange kolonner samtidig. Funksjonen er nyttig når du vil gjøre endringer i mange eksisterende variabler samtidig. Funksjonen mutate() kombineres med <tidy-select>, som er funksjoner som angir kolonner på en svært effektiv måte. Et eksempel på <tidy-select> er everything(), som betyr "alle variabler".

For å demonstrere across lager vi en ny dataframe ved hjelp av funksjonen 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

Det finnes to numeriske kolonner (var1, var3), og nå skal vi beregne kvadratroten av dem. Kvadratroten beregnes med funksjonen sqrt. Kolonnene var1 og var3 er kolonne nummer 1 og 3. Følgende kommandoer er ekvivalente:

## Kvadratroten av var1 og var3
my_data %>%
  mutate(across(c(var1, var3), sqrt))

## Som over, men nå med indeks på kolonnene
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 over, erstattes de eksisterende kolonnene. Hvis vi vil at funksjonen skal lage nye kolonner, bruker vi argumentet .names, der vi kan angi et suffiks eller prefiks for de nye kolonnene:

## Kvadratroten av 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

Mer kompliserte funksjoner kan defineres med tilde (~), og den aktuelle verdien på hver rad representeres med plassholderen .x. I neste eksempel velger vi alle numeriske kolonner, kvadrerer verdien og lagrer resultatet i en ny kolonne med prefikset "ny_":

## Velg numeriske kolonner, kvadrer dem, lagre resultatet i nye kolonner med prefikset "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 søk etter mønstre i variabelnavnene:

Her endres kolonner som inneholder tegnet "1":

## Endrer kolonner som inneholder sifferet 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 endres kolonner som slutter med tegnet "3":

## Endrer kolonner som 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