Kapitel 1 und 2 https://rpubs.com/Exilkaerntner1970/1132315

3. Datentransformation

Für eine Einführung in das Thema Datenmanipulation mit dplyr -eher ein schlechte Bezeichnung, da man ja nichts “manipuliert”, eher bereinigt oder effizienter Daten bearbeitet, empfehle ich die Seite von William Surles: https://rpubs.com/williamsurles/292547

Als Vorbereitung auf dieses Kapitel muss der Datensatz, nycflights13, installiert werden

library(nycflights13)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(knitr)
library(janitor)
## 
## Attache Paket: 'janitor'
## 
## Die folgenden Objekte sind maskiert von 'package:stats':
## 
##     chisq.test, fisher.test
library(Lahman)

Ich verwende nun das Datenframe flights, der über 300.000 Datensätze von Abflügen aus NYC beinhaltet.

kable(flights[1:7,],
      caption = "Anfang der Flight Datenbank")
Anfang der Flight Datenbank
year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum origin dest air_time distance hour minute time_hour
2013 1 1 517 515 2 830 819 11 UA 1545 N14228 EWR IAH 227 1400 5 15 2013-01-01 05:00:00
2013 1 1 533 529 4 850 830 20 UA 1714 N24211 LGA IAH 227 1416 5 29 2013-01-01 05:00:00
2013 1 1 542 540 2 923 850 33 AA 1141 N619AA JFK MIA 160 1089 5 40 2013-01-01 05:00:00
2013 1 1 544 545 -1 1004 1022 -18 B6 725 N804JB JFK BQN 183 1576 5 45 2013-01-01 05:00:00
2013 1 1 554 600 -6 812 837 -25 DL 461 N668DN LGA ATL 116 762 6 0 2013-01-01 06:00:00
2013 1 1 554 558 -4 740 728 12 UA 1696 N39463 EWR ORD 150 719 5 58 2013-01-01 05:00:00
2013 1 1 555 600 -5 913 854 19 B6 507 N516JB EWR FLL 158 1065 6 0 2013-01-01 06:00:00

Struktur der DB

glimpse(flights)
## Rows: 336,776
## Columns: 19
## $ year           <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2…
## $ month          <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ day            <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ dep_time       <int> 517, 533, 542, 544, 554, 554, 555, 557, 557, 558, 558, …
## $ sched_dep_time <int> 515, 529, 540, 545, 600, 558, 600, 600, 600, 600, 600, …
## $ dep_delay      <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2, -2, -1…
## $ arr_time       <int> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 753, 849,…
## $ sched_arr_time <int> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 745, 851,…
## $ arr_delay      <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -3, 7, -1…
## $ carrier        <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV", "B6", "…
## $ flight         <int> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79, 301, 4…
## $ tailnum        <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN", "N394…
## $ origin         <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR", "LGA",…
## $ dest           <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL", "IAD",…
## $ air_time       <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138, 149, 1…
## $ distance       <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 944, 733, …
## $ hour           <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6…
## $ minute         <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0…
## $ time_hour      <dttm> 2013-01-01 05:00:00, 2013-01-01 05:00:00, 2013-01-01 0…

3.1 Basics der dplyr Library

Um die DB zu bearbeiten, werde ich Befehle der deplyr library benutzen. Die Syntax ist ähnlich zum magrittr Package, welches ebenfalls un tidyverse vorhanden ist. Der unterschied ist nur die “Pipe”. Pipe ist eine “Funktion”, welche R anzeigt…….

Magrittr verwendet als Zeichenfolge für die “Pipe” %>%, dplyr nutzt die Zeichen |>.

3.1.1 Der Filterbefehl

Der Filterbefehl filter die DB nach einen oder mehrere Ausprägungen. Im ersten Beispiel sollten nur mehr Flüge angezeigt werden, die mindestens 120 minuten Verspätung hatten:

flights |>
  filter(dep_delay > 120)
## # A tibble: 9,723 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      848           1835       853     1001           1950
##  2  2013     1     1      957            733       144     1056            853
##  3  2013     1     1     1114            900       134     1447           1222
##  4  2013     1     1     1540           1338       122     2020           1825
##  5  2013     1     1     1815           1325       290     2120           1542
##  6  2013     1     1     1842           1422       260     1958           1535
##  7  2013     1     1     1856           1645       131     2212           2005
##  8  2013     1     1     1934           1725       129     2126           1855
##  9  2013     1     1     1938           1703       155     2109           1823
## 10  2013     1     1     1942           1705       157     2124           1830
## # ℹ 9,713 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Als Operanden dürfen folgende Zeichen verwendet werden

  • > oder < für größer oder kleiner
  • >= oder <= für größer oder kleiner gleich
  • == für ist gleich, bzw != ist ungleich
  • sowie & oder , was “und” symbolisiert. Ein “Oder” wird mit dem Zeichen | dargestellt.

Im zweiten Beispiel sollen nur Flüge angezeigt werden, die am 1. Januar abgingen:

flights |>
  filter(day == 1 & month == 1)
## # A tibble: 842 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 832 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Man kann im Filter auch einen “oder- Operanden” benutzen. Im nächsten Beispiel solle nach allen flügen im Jänner und Februar rausgefiltert werden.

flights |>
  filter(month == 1 | month == 2)
## # A tibble: 51,955 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 51,945 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

3.1.2 Sortierung der Spalten

Es kann oft hilfreich sein, die Spalten neu zu ordnen. Dabei hilft der Befehl arrange(). Im nächsten Beispiel sollte neben dem Filter noch die Spaltenreihenfolge der ersten vier Spalten festgelegt werden. Es werden die ersten vier Spalten absteigend sortiert. Ich arbeite hier mit dem Anfangscode weiter. Im Buch selbst wird nur der Befehl arrange() selbst ausgeführt.

flights |> 
  filter(month == 1 | month == 2) |>  # Filtern nach den Monaten
  arrange(year, month, day, dep_time) # Ersten Vier Spalten nach der Reihe sortiert
## # A tibble: 51,955 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 51,945 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Man kann im Sortierbefehle auch nach werten Sortieren. Absteigend -asc- ist defaultmäßig vorgegeben. Im Beispiel sollte nun nach Verspätung absteigend -desc- sortiert werden. Dabei muss im Sortierbefehl die Absteigende Spalte an erster Stelle stehen,

flights |>
  filter(month == 1 | month == 2 ) |>
  arrange(desc(dep_delay), year, month, day, dep_time)
## # A tibble: 51,955 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     9      641            900      1301     1242           1530
##  2  2013     1    10     1121           1635      1126     1239           1810
##  3  2013     1     1      848           1835       853     1001           1950
##  4  2013     2    10     2243            830       853      100           1106
##  5  2013     2    19     2324           1016       788      114           1227
##  6  2013     2    24     1921            615       786     2135            842
##  7  2013     2    16      757           1930       747     1013           2149
##  8  2013     1    13     1809            810       599     2054           1042
##  9  2013     2    13     2022           1030       592     2247           1252
## 10  2013     1    16     1622            800       502     1911           1054
## # ℹ 51,945 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

#### 3.1.3 Der distinct()-Befehl

Wenn der Distinct-Befehle ohne Angabe von Spalten angewendet wird, werden alle Doubletten entfernt.

flights |> 
  filter(month == 1 | month == 2) |>
  arrange(desc(dep_delay)) |>
  distinct()
## # A tibble: 51,955 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     9      641            900      1301     1242           1530
##  2  2013     1    10     1121           1635      1126     1239           1810
##  3  2013     1     1      848           1835       853     1001           1950
##  4  2013     2    10     2243            830       853      100           1106
##  5  2013     2    19     2324           1016       788      114           1227
##  6  2013     2    24     1921            615       786     2135            842
##  7  2013     2    16      757           1930       747     1013           2149
##  8  2013     1    13     1809            810       599     2054           1042
##  9  2013     2    13     2022           1030       592     2247           1252
## 10  2013     1    16     1622            800       502     1911           1054
## # ℹ 51,945 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

In diesem Fall gab es keine Doubletten. es ist aber sinnvoll bei anderen Datenquellen zumindest einen Testballon steigen zu lassen.

Wenn Spaltennamen angegeben werden, werden nur die Datensätze ausgewält, die den Wert beider Datensätzebesitzen. Es wird also festgestellt, wieviele destinationen angeflogen werden.

flights |>
  distinct(origin, dest)
## # A tibble: 224 × 2
##    origin dest 
##    <chr>  <chr>
##  1 EWR    IAH  
##  2 LGA    IAH  
##  3 JFK    MIA  
##  4 JFK    BQN  
##  5 LGA    ATL  
##  6 EWR    ORD  
##  7 EWR    FLL  
##  8 LGA    IAD  
##  9 JFK    MCO  
## 10 LGA    ORD  
## # ℹ 214 more rows
# gleicher befehl, der alle spalten anzeigt
flights |>
  distinct(origin, dest, 
           .keep_all = T)
## # A tibble: 224 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 214 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Um die anzahl der Flüge mit Abflughaten und Ankunftsflughafen zu ermitteln kann man die Funktion count() verwenden.

flights |>
  count(origin, dest, sort = T)
## # A tibble: 224 × 3
##    origin dest      n
##    <chr>  <chr> <int>
##  1 JFK    LAX   11262
##  2 LGA    ATL   10263
##  3 LGA    ORD    8857
##  4 JFK    SFO    8204
##  5 LGA    CLT    6168
##  6 EWR    ORD    6100
##  7 JFK    BOS    5898
##  8 LGA    MIA    5781
##  9 JFK    MCO    5464
## 10 EWR    BOS    5327
## # ℹ 214 more rows

3.2 Bearbeiten und manipulieren von gesamten Spalten

Mit folgenden befehlen können ganze Spalten manipuliert und bearbeitet werden:

  • Der Befehl mutate() generiert neue Spalten, die aus existierenden Spalten abgeleitet werden.
  • Mit dem Befehl select() werden Spalten ausgewählt werden und in einer neuen Tabelle zusammengefasst werden.
  • Mit rename()können die Namen der Spalten verändert werden.
  • und mit dem Befehle relocate() kann man die Spaltenreihenfolge ändern

3.2.1 Der mutate() Befehl

Mit diesen Befehl kann man, mit den Werten der existierenden Spalten, neue Spalten generieren.

Bsp: (weiterer Text folgt)

flights |>
  mutate(gain =  dep_delay- arr_delay,
         speed = distance / air_time *60)
## # A tibble: 336,776 × 21
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 13 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>, gain <dbl>, speed <dbl>

Um die beiden Spalten vorne dazufügen zu können muss ein weiterer befehlt in mutate verwendet werden.

flights |>
  mutate(gain = dep_delay - arr_delay,
         speed_kmh = distance / air_time * 60 * 1.60934 ,
         .before = 1)
## # A tibble: 336,776 × 21
##     gain speed_kmh  year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl>     <dbl> <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1    -9      596.  2013     1     1      517            515         2      830
##  2   -16      602.  2013     1     1      533            529         4      850
##  3   -31      657.  2013     1     1      542            540         2      923
##  4    17      832.  2013     1     1      544            545        -1     1004
##  5    19      634.  2013     1     1      554            600        -6      812
##  6   -16      463.  2013     1     1      554            558        -4      740
##  7   -24      651.  2013     1     1      555            600        -5      913
##  8    11      417.  2013     1     1      557            600        -3      709
##  9     5      651.  2013     1     1      557            600        -3      838
## 10   -10      513.  2013     1     1      558            600        -2      753
## # ℹ 336,766 more rows
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
## #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

Der Punkt for dem before-Befehl zeigt an, dass es sich nicht um eine weitere zu berechnende Spalte handelt, sondern um eine Anweisung. Man kann bei before oder after auch einen Spaltennamen verwenden, um die neuen spalten in der Tabelle dem gewünschten Platz zuzuweisen.

flights |>
  mutate(gain = dep_delay - arr_delay,
         speed_mih = distance / air_time * 60,
         speed_kmh = speed_mih * 1.60934,
         .after = day)
## # A tibble: 336,776 × 22
##     year month   day  gain speed_mih speed_kmh dep_time sched_dep_time dep_delay
##    <int> <int> <int> <dbl>     <dbl>     <dbl>    <int>          <int>     <dbl>
##  1  2013     1     1    -9      370.      596.      517            515         2
##  2  2013     1     1   -16      374.      602.      533            529         4
##  3  2013     1     1   -31      408.      657.      542            540         2
##  4  2013     1     1    17      517.      832.      544            545        -1
##  5  2013     1     1    19      394.      634.      554            600        -6
##  6  2013     1     1   -16      288.      463.      554            558        -4
##  7  2013     1     1   -24      404.      651.      555            600        -5
##  8  2013     1     1    11      259.      417.      557            600        -3
##  9  2013     1     1     5      405.      651.      557            600        -3
## 10  2013     1     1   -10      319.      513.      558            600        -2
## # ℹ 336,766 more rows
## # ℹ 13 more variables: arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
## #   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

Eine weitere Anweisung ist .keep =. Mit dem Wert “used” wird eine neue Tabelle generiert, die nur die benutzten und die neuen Spalten enthält.

flights |>
  mutate(gain = dep_delay - arr_delay,
         speed_mih = distance / air_time * 60,
         speed_kmh = speed_mih * 1.60934,
         .keep = "used")
## # A tibble: 336,776 × 7
##    dep_delay arr_delay air_time distance  gain speed_mih speed_kmh
##        <dbl>     <dbl>    <dbl>    <dbl> <dbl>     <dbl>     <dbl>
##  1         2        11      227     1400    -9      370.      596.
##  2         4        20      227     1416   -16      374.      602.
##  3         2        33      160     1089   -31      408.      657.
##  4        -1       -18      183     1576    17      517.      832.
##  5        -6       -25      116      762    19      394.      634.
##  6        -4        12      150      719   -16      288.      463.
##  7        -5        19      158     1065   -24      404.      651.
##  8        -3       -14       53      229    11      259.      417.
##  9        -3        -8      140      944     5      405.      651.
## 10        -2         8      138      733   -10      319.      513.
## # ℹ 336,766 more rows

3.2.2 Spalten selektieren

Mit dem Befehl select() kann man einzelne Spalten zu einer neuen Tabelle zusammenführen. Man kann dadurch Teiltabellen gestallten, die für die weitere Verarbeitung besser geeignet sind. Einerseits kann man nach den individuellen Namen selektiern:

flights |>
  select(year, day, month)
## # A tibble: 336,776 × 3
##     year   day month
##    <int> <int> <int>
##  1  2013     1     1
##  2  2013     1     1
##  3  2013     1     1
##  4  2013     1     1
##  5  2013     1     1
##  6  2013     1     1
##  7  2013     1     1
##  8  2013     1     1
##  9  2013     1     1
## 10  2013     1     1
## # ℹ 336,766 more rows

Das gleiche Ergebnis kann man mit dem von- bis Befehl halten.

flights |>
  select(year : day)
## # A tibble: 336,776 × 3
##     year month   day
##    <int> <int> <int>
##  1  2013     1     1
##  2  2013     1     1
##  3  2013     1     1
##  4  2013     1     1
##  5  2013     1     1
##  6  2013     1     1
##  7  2013     1     1
##  8  2013     1     1
##  9  2013     1     1
## 10  2013     1     1
## # ℹ 336,766 more rows

Im nächsten Beispiel sollen alle Spalten, außer year, month date, selektiert werden

flights |>
  select(!year:day)
## # A tibble: 336,776 × 16
##    dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier
##       <int>          <int>     <dbl>    <int>          <int>     <dbl> <chr>  
##  1      517            515         2      830            819        11 UA     
##  2      533            529         4      850            830        20 UA     
##  3      542            540         2      923            850        33 AA     
##  4      544            545        -1     1004           1022       -18 B6     
##  5      554            600        -6      812            837       -25 DL     
##  6      554            558        -4      740            728        12 UA     
##  7      555            600        -5      913            854        19 B6     
##  8      557            600        -3      709            723       -14 EV     
##  9      557            600        -3      838            846        -8 B6     
## 10      558            600        -2      753            745         8 AA     
## # ℹ 336,766 more rows
## # ℹ 9 more variables: flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

Nur Spalten zurück geben, die mit Zeichen befüllt sind.

flights |> 
  select(where(is.character))
## # A tibble: 336,776 × 4
##    carrier tailnum origin dest 
##    <chr>   <chr>   <chr>  <chr>
##  1 UA      N14228  EWR    IAH  
##  2 UA      N24211  LGA    IAH  
##  3 AA      N619AA  JFK    MIA  
##  4 B6      N804JB  JFK    BQN  
##  5 DL      N668DN  LGA    ATL  
##  6 UA      N39463  EWR    ORD  
##  7 B6      N516JB  EWR    FLL  
##  8 EV      N829AS  LGA    IAD  
##  9 B6      N593JB  JFK    MCO  
## 10 AA      N3ALAA  LGA    ORD  
## # ℹ 336,766 more rows

Es gibt noch weiter “Helferlein-Funktionen”, die man mit der select-Funktion benutzen kann. für eine aufzählung schreibe ?select() in der R Console.

Es gibt noch die Möglichkeit, mit dem Befehl die Spaltennamen zu ändern. Dabei dabei muss der neue Namen links vom Operanden = stehen.

flights |>
  select(tail_num = tailnum)
## # A tibble: 336,776 × 1
##    tail_num
##    <chr>   
##  1 N14228  
##  2 N24211  
##  3 N619AA  
##  4 N804JB  
##  5 N668DN  
##  6 N39463  
##  7 N516JB  
##  8 N829AS  
##  9 N593JB  
## 10 N3ALAA  
## # ℹ 336,766 more rows

3.2.3 Spalten umbenennen

Falls man mehrere Namen zu bereinigen hat, ist der Befehl rename() eine bessere Variante als select. Der Befehl funktioniert gleich, wie select. Der neue Namen steht links vom =.

flights |> 
  rename(tail_num = tailnum)
## # A tibble: 336,776 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tail_num <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

3.2.4 Verschieben von Spalten

Manchmal ist es nötig, Spalten zur besseren Darstellung zu verschieben. Dabei benutzt man den Befehl relocate().

flights |>
  relocate(time_hour, air_time) # setzt die Spalten an die erste Stelle
## # A tibble: 336,776 × 19
##    time_hour           air_time  year month   day dep_time sched_dep_time
##    <dttm>                 <dbl> <int> <int> <int>    <int>          <int>
##  1 2013-01-01 05:00:00      227  2013     1     1      517            515
##  2 2013-01-01 05:00:00      227  2013     1     1      533            529
##  3 2013-01-01 05:00:00      160  2013     1     1      542            540
##  4 2013-01-01 05:00:00      183  2013     1     1      544            545
##  5 2013-01-01 06:00:00      116  2013     1     1      554            600
##  6 2013-01-01 05:00:00      150  2013     1     1      554            558
##  7 2013-01-01 06:00:00      158  2013     1     1      555            600
##  8 2013-01-01 06:00:00       53  2013     1     1      557            600
##  9 2013-01-01 06:00:00      140  2013     1     1      557            600
## 10 2013-01-01 06:00:00      138  2013     1     1      558            600
## # ℹ 336,766 more rows
## # ℹ 12 more variables: dep_delay <dbl>, arr_time <int>, sched_arr_time <int>,
## #   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
## #   dest <chr>, distance <dbl>, hour <dbl>, minute <dbl>

Ohne die Befehle .before = oder .after= werden die Spalten an den Anfang versetzt. Falls es nötig ist, die Spalten an anderer Stelle zu setzen, sind diese beiden Anweisungen hilfreich. Ich benutze in diesem Beispiel mal die magrittr Pipe als alternative. Nur um zu zeigen, dass beide Arten funktionieren.

flights %>%                     # diesmal mit magrittr Pipe
  relocate(time_hour, air_time, 
           .after = day)
## # A tibble: 336,776 × 19
##     year month   day time_hour           air_time dep_time sched_dep_time
##    <int> <int> <int> <dttm>                 <dbl>    <int>          <int>
##  1  2013     1     1 2013-01-01 05:00:00      227      517            515
##  2  2013     1     1 2013-01-01 05:00:00      227      533            529
##  3  2013     1     1 2013-01-01 05:00:00      160      542            540
##  4  2013     1     1 2013-01-01 05:00:00      183      544            545
##  5  2013     1     1 2013-01-01 06:00:00      116      554            600
##  6  2013     1     1 2013-01-01 05:00:00      150      554            558
##  7  2013     1     1 2013-01-01 06:00:00      158      555            600
##  8  2013     1     1 2013-01-01 06:00:00       53      557            600
##  9  2013     1     1 2013-01-01 06:00:00      140      557            600
## 10  2013     1     1 2013-01-01 06:00:00      138      558            600
## # ℹ 336,766 more rows
## # ℹ 12 more variables: dep_delay <dbl>, arr_time <int>, sched_arr_time <int>,
## #   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
## #   dest <chr>, distance <dbl>, hour <dbl>, minute <dbl>

3.3 Die Pipe

Man kann auch die vorhergehenden Befehle kombinieren.

flights |>
  filter(dest == "IAH") |>             # nur Flüge nach IAH
  mutate(speed_mih = distance / air_time * 60,
         speed_kmh = speed_mih * 1.609) |>
  select(year:day, 
         dep_time, 
         carrier:tailnum, 
         speed_mih, 
         speed_kmh) |>
  arrange(desc(speed_kmh))
## # A tibble: 7,198 × 9
##     year month   day dep_time carrier flight tailnum speed_mih speed_kmh
##    <int> <int> <int>    <int> <chr>    <int> <chr>       <dbl>     <dbl>
##  1  2013     7     9      707 UA         226 N553UA       522.      839.
##  2  2013     8    27     1850 UA        1128 N13750       521.      839.
##  3  2013     8    28      902 UA        1711 N57852       519.      834.
##  4  2013     8    28     2122 UA        1022 N76269       519.      834.
##  5  2013     6    11     1628 UA        1178 N26123       515.      829.
##  6  2013     8    27     1017 UA         333 N438UA       515.      829.
##  7  2013     8    27     1205 UA        1421 N12218       515.      829.
##  8  2013     8    27     1758 UA         302 N498UA       515.      829.
##  9  2013     9    27      521 UA         252 N536UA       515.      829.
## 10  2013     8    28      625 UA         559 N468UA       515.      828.
## # ℹ 7,188 more rows

3.4 Weitere Befehle um die Daten zu groupieren

3.4.1 die Befehle group_by() und summarise()

Im Buch selbst werden die Befehle einzeln dargestellt. Ich finde aber, dass man nicht genau versteht, für was die einzelnen Befehle alleine stehen. Daher habe ich eine ganze Pipe gebaut. In diesem Beispiel wird zuerst nach Fluglinien groupiert. Aufgrund dieser Groupierung werden dann weitere Zusammenfassungen -Mittelwert an Verspätung und Anzahl der Flüge - in neuen Spalten berechnet. Zu guter Letzt sollen noch der DF nach Geschwindigkeit, absteigend, sortiert werden.

flights |>
  group_by(carrier) |>                # als Groupierung den Carrier festlegen
  summarise(my_verspaetung = mean(dep_delay, na.rm = T),
            n = n()) |>               # MW der Verspätung und Anzahl der Flüge
  arrange(desc(n))                    # sortieren nach Anzahlt der Flüge
## # A tibble: 16 × 3
##    carrier my_verspaetung     n
##    <chr>            <dbl> <int>
##  1 UA               12.1  58665
##  2 B6               13.0  54635
##  3 EV               20.0  54173
##  4 DL                9.26 48110
##  5 AA                8.59 32729
##  6 MQ               10.6  26397
##  7 US                3.78 20536
##  8 9E               16.7  18460
##  9 WN               17.7  12275
## 10 VX               12.9   5162
## 11 FL               18.7   3260
## 12 AS                5.80   714
## 13 F9               20.2    685
## 14 YV               19.0    601
## 15 HA                4.90   342
## 16 OO               12.6     32

3.4.2 slice Befehle

Man kann auch einzelne Zeilen ausgeben. In Kapitel XX wird genauer auf die `slice_*-Befehle eingegangen.

flights |> 
  group_by(dest) |>              # dest auswählen
  slice_max(arr_delay, n = 2) |> # den DS mit den größten zwei Verpätungen je zielflughafen zurückgeben 
  relocate(dest) # dest an erster stelle stellen
## # A tibble: 211 × 19
## # Groups:   dest [105]
##    dest   year month   day dep_time sched_dep_time dep_delay arr_time
##    <chr> <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1 ABQ    2013     7    22     2145           2007        98      132
##  2 ABQ    2013    12    14     2223           2001       142      133
##  3 ACK    2013     7    23     1139            800       219     1250
##  4 ACK    2013     6    11     1246           1135        71     1512
##  5 ALB    2013     1    25      123           2000       323      229
##  6 ALB    2013    12     5     2219           1721       298     2322
##  7 ANC    2013     8    17     1740           1625        75     2042
##  8 ANC    2013     7    20     1618           1615         3     2003
##  9 ANC    2013     8     3     1615           1615         0     2003
## 10 ATL    2013     7    22     2257            759       898      121
## # ℹ 201 more rows
## # ℹ 11 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Gleicher Befehl mit minimum

flights |> 
  group_by(dest) |>              # dest auswählen
  slice_min(arr_delay, n = 2) |>
  relocate(dest)
## # A tibble: 240 × 19
## # Groups:   dest [105]
##    dest   year month   day dep_time sched_dep_time dep_delay arr_time
##    <chr> <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1 ABQ    2013    11    13     1953           2000        -7     2202
##  2 ABQ    2013     5    14     1958           2001        -3     2210
##  3 ACK    2013     8    11      751            800        -9      844
##  4 ACK    2013     6    19     1128           1135        -7     1218
##  5 ALB    2013     6    12      738            746        -8      823
##  6 ALB    2013     8    20      711            720        -9      800
##  7 ANC    2013     7    27     1617           1615         2     1906
##  8 ANC    2013     8    10     1613           1615        -2     1922
##  9 ATL    2013     3     2     1951           2000        -9     2146
## 10 ATL    2013     1    26     1945           2000       -15     2148
## # ℹ 230 more rows
## # ℹ 11 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Zufällige Auswahl von Zeilen

flights |>
  group_by(dest) |>
  slice_sample(n = 2) |>
  relocate(dest)
## # A tibble: 208 × 19
## # Groups:   dest [105]
##    dest   year month   day dep_time sched_dep_time dep_delay arr_time
##    <chr> <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1 ABQ    2013    11     4     1955           2000        -5     2306
##  2 ABQ    2013     6     6     1957           2001        -4     2314
##  3 ACK    2013     6    27     1207           1209        -2     1319
##  4 ACK    2013     7    16     1201           1209        -8     1305
##  5 ALB    2013     1     3     2031           2038        -7     2131
##  6 ALB    2013     1    29     1609           1619       -10     1706
##  7 ANC    2013     8    17     1740           1625        75     2042
##  8 ANC    2013     8     3     1615           1615         0     2003
##  9 ATL    2013     4     3     1656           1700        -4     1923
## 10 ATL    2013     1    12     1848           1855        -7     2100
## # ℹ 198 more rows
## # ℹ 11 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Erste oder letzte Zeile zurückgeben mit slice_head(x,n=1) oder slice_tail().

3.5 setwas komplizierteres Beispiel aus dem Lahman Datensatz

batters <- Batting |>
  group_by(playerID) |>
  summarise(performance = sum(H, na.rm = T) / sum(AB, na.rm = T),
            n = sum(AB, na.rm =  T))
  
batters
## # A tibble: 20,469 × 3
##    playerID  performance     n
##    <chr>           <dbl> <int>
##  1 aardsda01      0          4
##  2 aaronha01      0.305  12364
##  3 aaronto01      0.229    944
##  4 aasedo01       0          5
##  5 abadan01       0.0952    21
##  6 abadfe01       0.111      9
##  7 abadijo01      0.224     49
##  8 abbated01      0.254   3044
##  9 abbeybe01      0.169    225
## 10 abbeych01      0.281   1756
## # ℹ 20,459 more rows

3.5.1 Grafische aufbereitung

Einen ggplot mit Ponktdiagramm und einer Regression machen. zuerst ohne einschränkungen.

batters |>
  ggplot(aes(x = n,
             y = performance)) +
  geom_point()
## Warning: Removed 2466 rows containing missing values (`geom_point()`).

In der Grafik sieht man, dass es gerade bei Spieler, die wenige Spiele hatten, sehr grosse abweichungen in der Performance gibt. Um diesen “Noise” auszuschliessen, sollen nur Spieler berücksichtigt werden, die zumindest 100 Spiele gespielt haben.

batters |>
  filter(n >=100) |>
  ggplot(aes(x = n,
             y = performance)) +
  geom_point()

Die gleiche Grafik sollte noch durchsichtige Punkte bekommen und eine Regressionslinie soll durchgelegt werden.

batters |>
  filter(n >= 100) |>
  ggplot(aes(x = n,
             y = performance)) +
  geom_point(alpha = 1/10) +
  geom_smooth() +
  labs(title = "Schlageffizienz des Batters beim Baseball",
       subtitle = "Der Datensatz umfasst über 100.000 Beobachtungen seit 1871",
       x = "Anzahl der Versuche",
       y = "Schlageffizienz"
       )
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

nächstes Kapitel: https://rpubs.com/Exilkaerntner1970/1133543