Zeilenweise Operationen (tidyverse-Stil)

1 Aufgabe

Berechnen Sie Zeilensummen! … Oder Zeilen-Mittelwerte oder eine andere zeilenbasierte Funktion.

2 Setup

library(tidyverse)  # Datenjudo

3 Daten erzeugen

d <- tribble(
  ~"x1", ~"x2", ~"x3",
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
)
d
#> # A tibble: 3 x 3
#>      x1    x2    x3
#>   <dbl> <dbl> <dbl>
#> 1     1     2     3
#> 2     4     5     6
#> 3     7     8     9

4 Spalten addieren, die Erste

d %>% 
  mutate(summe = x1 + x2 + x3) %>% 
  mutate(mw = (x1 + x2 + x3)/3)
#> # A tibble: 3 x 5
#>      x1    x2    x3 summe    mw
#>   <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3     6     2
#> 2     4     5     6    15     5
#> 3     7     8     9    24     8

Läuft!

5 Spalten addieren, die Zweite

d %>% 
  mutate(summe = sum(c(x1, x2, x3)),
         mw = mean(c(x1, x2, x3)))
#> # A tibble: 3 x 5
#>      x1    x2    x3 summe    mw
#>   <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3    45     5
#> 2     4     5     6    45     5
#> 3     7     8     9    45     5

Läuft nicht!

Leider “verstehen” sum und mean nicht die zeilenweisen Operationen. Wir müssen ihnen erst vorab verklickern, dass sie zeilenoperiert arbeiten sollen. Das geht mit dem Befehl rowwise, den wir in den Code von oben einfügen:

d %>% 
  rowwise() %>% 
  mutate(summe = sum(c(x1, x2, x3)),
         mw = mean(c(x1, x2, x3)))
#> # A tibble: 3 x 5
#> # Rowwise: 
#>      x1    x2    x3 summe    mw
#>   <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3     6     2
#> 2     4     5     6    15     5
#> 3     7     8     9    24     8

Läuft!

6 Spalten addieren, die Dritte

Das Prinzip rowwise funktioniert mit beliebigen Befehlen, die zeilenweise arbeiten sollen.

Es gibt auch ein paar praktische Hilfen, etwa wenn man nicht alle Spalten händisch aufführen will oder kann:

cols_to_sum <- c("x1", "x2", "x3")
d %>% 
  rowwise() %>% 
  mutate(summe = sum(across(any_of(cols_to_sum)))
         )
#> # A tibble: 3 x 4
#> # Rowwise: 
#>      x1    x2    x3 summe
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3     6
#> 2     4     5     6    15
#> 3     7     8     9    24

any_of() sagt sinngemäß “nimm jede (any) Spalte aus diesem Vektor”. Allerdings muss dieser Befehl innerhalb von select() oder across()` gesetzt werden – nur innerhalb von Tidyverse-Befehlen, die Spalten auswählen, funktioniert er.

7 Von erster Spalte bis zu letzter Spalte

d %>% 
  select(1:last_col()) %>% 
  rowwise() %>% 
  mutate(summe = sum(across(everything()))
         )
#> # A tibble: 3 x 4
#> # Rowwise: 
#>      x1    x2    x3 summe
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3     6
#> 2     4     5     6    15
#> 3     7     8     9    24

8 Fazit

Möchte man Funktionen über Spalten hinweg aber zeilenweise ausführen, so hilft der Befehl rowwise(). Möchte man die spaltenweise Orientierung der Tabelle wieder aufheben, so hilft ungroup().