Prepro 2: Demo

Veröffentlichungsdatum

16. Oktober 2023

Diese Demo kann auch als R Script heruntergeladen werden (Rechtsklick → Save Target As..)

Piping

Gegeben ist ein character string (diary). Wir wollen aus diesem Text die Temperaturangabe aus dem String extrahieren und danach den Wert von Kelvin in Celsius nach der folgenden Formel umwandeln und zum Schluss den Mittelwert über all diese Werte berechnen.

\[°C = K - 273.15\]

diary <- c(
  "The temperature is 310° Kelvin",
  "The temperature is 322° Kelvin",
  "The temperature is 410° Kelvin"
)

diary
## [1] "The temperature is 310° Kelvin" "The temperature is 322° Kelvin"
## [3] "The temperature is 410° Kelvin"

Dazu brauchen wir die Funktion substr(), welche aus einem character einen Teil “raus schnipseln” kann.

# Wenn die Buchstaben einzelne _Elemente_ eines Vektors wären, würden wir diese
# folgendermassen subsetten:

charvec1 <- c("a", "b", "c", "d", "e", "f", "g", "h")
charvec1[4:6]
## [1] "d" "e" "f"

# Aber wenn diese in einem einzigen character gespeichert sind, brauchen wir substr:
charvec2 <- "abcdefgh"
substr(charvec2, 4, 6)
## [1] "def"

Zudem nutzen haben wir eine Hilfsfunktion subtrahieren, welche zwei Werte annimmt, den minuend und den subtrahend:

subtrahieren <- function(minuend, subtrahend) {
  minuend - subtrahend
}

subtrahieren(10, 4)
## [1] 6

Übersetzt in R-Code entsteht folgende Operation:

output <- mean(subtrahieren(as.numeric(substr(diary, 20, 22)), 273.15))
#                                             \_1_/
#                                      \________2__________/
#                           \___________________3___________/
#              \________________________________4__________________/
#         \_____________________________________5____________________/

# 1. Nimm diary
# 2. Extrahiere auf jeder Zeile die Werte 20 bis 22
# 3. Konvertiere "character" zu "numeric"
# 4. Subtrahiere 273.15
# 5. Berechne den Mittlwert

Die ganze Operation liest sich etwas leichter, wenn diese sequentiell notiert wird:

temp <- substr(diary, 20, 22)      # 2
temp <- as.numeric(temp)           # 3
temp <- subtrahieren(temp, 273.15) # 4
output <- mean(temp)               # 5

Umständlich ist dabei einfach, dass die Zwischenresultate immer abgespeichert und in der darauf folgenden Operation wieder abgerufen werden müssen. Hier kommt “piping” ins Spiel: Mit “piping” wird der Output der einen Funktion der erste Parameter der darauf folgenden Funktion.

diary |>                  # 1
  substr(20, 22) |>       # 2
  as.numeric() |>         # 3
  subtrahieren(273.15) |> # 4
  mean()                  # 5
## [1] 74.18333
Wichtig
  • der |> Pipe Operator wurde erst in R 4.1 eingeführt
  • Neben dem base R Pipe Operator existiert im Package magrittr ein sehr ähnlicher1 Pipe Operator: %>%
  • Die Tastenkombination Ctrl+Shift+M in RStudio fügt einen Pipe Operator ein.
  • Welcher Pipe Operator |> oder %>% mit der obigen Tastenkombination eingeführt wird, kann über die RStudio Settings ToolsGlobal OptionsCode → Häckchen setzen bei Use nativ pipe operator
  • Wir empfehlen die base-R Pipe |> zu verwenden

Joins

studierende <- data.frame(
  Matrikel_Nr = c(100002, 100003, 200003),
  Studi = c("Patrick", "Manuela", "Eva"),
  PLZ = c(8006, 8001, 8820)
)

studierende
##   Matrikel_Nr   Studi  PLZ
## 1      100002 Patrick 8006
## 2      100003 Manuela 8001
## 3      200003     Eva 8820

ortschaften <- data.frame(
  PLZ = c(8003, 8006, 8810, 8820),
  Ortsname = c("Zürich", "Zürich", "Horgen", "Wädenswil")
)

ortschaften
##    PLZ  Ortsname
## 1 8003    Zürich
## 2 8006    Zürich
## 3 8810    Horgen
## 4 8820 Wädenswil
# Load library
library("dplyr")

inner_join(studierende, ortschaften, by = "PLZ")
##   Matrikel_Nr   Studi  PLZ  Ortsname
## 1      100002 Patrick 8006    Zürich
## 2      200003     Eva 8820 Wädenswil

left_join(studierende, ortschaften, by = "PLZ")
##   Matrikel_Nr   Studi  PLZ  Ortsname
## 1      100002 Patrick 8006    Zürich
## 2      100003 Manuela 8001      <NA>
## 3      200003     Eva 8820 Wädenswil

right_join(studierende, ortschaften, by = "PLZ")
##   Matrikel_Nr   Studi  PLZ  Ortsname
## 1      100002 Patrick 8006    Zürich
## 2      200003     Eva 8820 Wädenswil
## 3          NA    <NA> 8003    Zürich
## 4          NA    <NA> 8810    Horgen

full_join(studierende, ortschaften, by = "PLZ")
##   Matrikel_Nr   Studi  PLZ  Ortsname
## 1      100002 Patrick 8006    Zürich
## 2      100003 Manuela 8001      <NA>
## 3      200003     Eva 8820 Wädenswil
## 4          NA    <NA> 8003    Zürich
## 5          NA    <NA> 8810    Horgen
studierende <- data.frame(
  Matrikel_Nr = c(100002, 100003, 200003),
  Studi = c("Patrick", "Manuela", "Pascal"),
  Wohnort = c(8006, 8001, 8006)
)

left_join(studierende, ortschaften, by = c("Wohnort" = "PLZ"))
##   Matrikel_Nr   Studi Wohnort Ortsname
## 1      100002 Patrick    8006   Zürich
## 2      100003 Manuela    8001     <NA>
## 3      200003  Pascal    8006   Zürich

  1. siehe https://stackoverflow.com/q/67633022/4139249↩︎