
Data Science 1 - Programmieren & Visualisieren
Saskia Otto & Monika Eberhard
Universität Hamburg, IMF
Wintersemester 2025/2026
![]()

| Typische Manipulationen | Kernfunktion in ‘dplyr’ |
|---|---|
| Manipuliere Beobachtungen (Zeilen) | filter(), arrange() |
| Manipuliere Variablen (Spalten) | select(), rename(), mutate(), transmute(), |
| Fasse Beobachtungen zusammen | summarise() |
| Gruppiere Beobachtungen | group_by(), ungroup() |
| Kombiniere Tabellen | bind_rows, bind_cols und join_ Funktionen |
(‘Linf’ = mittlere maximale Länge, ‘K’ = Rate in der sich der Fisch an ‘Linf’ annähert)
Mit freundlicher Genehmigung der Fotografen von fishbase.org (Konstantinos I. Stergiou, Jim Greenfield) und uwphoto.no(Rudolf Svensen).

arrange() → sortiert Zeilen (also Beobachtungen) nach spezifischen Variablen:
filter() → extrahiert Reihen, die ein logisches Kriterium erfüllen:
Verknüpfte Abfragen in filter() werden mit Kommata aufgeführt (UND-Operator):
select() → extrahiert Spalten nach Namen oder mittels Helferfunktion:
select()Quelle: ältere Version des sog. cheatsheets
Data Transformation with dplyr (lizensiert unter CC-BY-SA).
rename() → ändert die Namen einzelner Variablen (neuerName = alterName):
mutate() und transmute() → erstellen neue Variablen:
mutate() / transmute()Sie können jede Berechnung mit einer Variablen machen, solange diese vektorisiert ist:

Quelle: ältere Version des sog. cheatsheets Data Transformation with dplyr (lizensiert unter CC-BY-SA).
Hilfreiches Tool
Bevor wir jetzt in die Datenmanipulation starten, werden wir ein sehr hilfreiches Werkzeug für verknüpfte Operationen kennenlernen!!!

%>%
|>|> arbeiten!|> können diverse Funktionsaufrufe sequenziell miteinander verknüpfen werden, ohne Zwischenobjekte zu erstellen.|> leitet den Inhalt des Objekts auf der linken Seite in den Ausdruck auf der rechten Seite.|> | Wie?|> | InterpretationErinnert doch fast an ein Kochrezept, oder?
|>Kleiner Tipp:
Der Pipe-Operator lässt sich mit dem Shortcut strg (bzw. cmd) + shift + m automatisch schreiben.
Um den nativen Operator standardmäßig zu nutzen, muss vorweg unter
ein Häkchen gesetzt werden!

![]()
![]()
Wir wollen uns die Verteilung der Kelchblattlänge bei der Art Iris versicolor anschauen:
Gibt es eine Beziehung zwischen dem Längen/Breiten-Verhältnis bei Kron- und Kelchblättern der Art Iris setosa? Um dies grafisch untersuchen zu können, transformieren Sie den iris Datensatz:
Erstellen Sie einen ‘tibble’ basierend auf dem iris Datensatz, welcher nur die Spalte ‘Species’ enthält und eine neue (absteigend sortierte) Spalte mit dem Quotienten aus der Kelchblattlänge zu -breite. Der ‘tibble’ soll aber nur die Arten I. versicolor und I. virginica und Quotientenwerte größer 2 enthalten:
# A tibble: 79 × 2
Species sepal_lw
<fct> <dbl>
1 virginica 2.96
2 versicolor 2.82
3 virginica 2.75
4 versicolor 2.74
5 versicolor 2.73
6 virginica 2.73
7 virginica 2.68
8 virginica 2.64
9 virginica 2.57
10 virginica 2.53
# ℹ 69 more rows

summarise() → reduziert Variablen zu Einzelwerten:
Quelle: ältere Version des sog. cheatsheets
Data Transformation with dplyr (lizensiert unter CC-BY-SA).
![]()
Es gibt 2 sehr nützliche Funktionen, die man anstelle von summarise() nutzen kann:
count() → zur Berechnung der Anzahl an Zeilendistinct() → zum Entfernen von Duplikaten (Zeilen mit komplett gleichem Inhalt in den jeweiligen Spalten)distinct()
# A tibble: 15 × 2
Species Sepal.Length
<fct> <dbl>
1 setosa 5.1
2 setosa 4.9
3 setosa 4.7
4 setosa 4.6
5 setosa 5
6 setosa 5.4
7 setosa 4.4
8 setosa 4.8
9 setosa 4.3
10 setosa 5.8
11 setosa 5.7
12 setosa 5.2
13 setosa 5.5
14 setosa 4.5
15 setosa 5.3
→ Wie Sie sehen, wurden die 50 Zeilen auf 15 reduziert.
iris 1Berechnung einer Statistik für mehrere Variablen gleichzeitig:
SL_mean SW_mean PL_mean PW_mean
1 5.843333 3.057333 3.758 1.199333
→ Viel Schreibarbeit wenn mehr als nur der Mittelwert berechnet werden soll…
across()Berechnung einer Statistik für mehrere Variablen gleichzeitig:
across() | 2Berechnung mehrerer deskriptiver Statistiken für alle kontinuierlichen Variablen → hier muss eine Liste dem .fns Argument übergeben werden:
Sepal.Length_mean Sepal.Length_median Sepal.Length_sd Sepal.Width_mean
1 5.843333 5.8 0.8280661 3.057333
Sepal.Width_median Sepal.Width_sd Petal.Length_mean Petal.Length_median
1 3 0.4358663 3.758 4.35
Petal.Length_sd Petal.Width_mean Petal.Width_median Petal.Width_sd
1 1.765298 1.199333 1.3 0.7622377
…was ist, wenn wir die Statistiken für bestimmte Gruppen (wie hier die Arten) getrennt bestimmen wollen????
group_by() nimmt eine existierende Tabelle und konvertiert sie in eine gruppierte Tabelle, in der Operationen gruppenweise durchgeführt werden können.ungroup() entfernt Gruppierungen (bei summarise() nicht nötig, aber bei z.B. count()).iris# A tibble: 3 × 5
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 3.43 1.46 0.246
2 versicolor 5.94 2.77 4.26 1.33
3 virginica 6.59 2.97 5.55 2.03
irisiris![]()
![]()
Berechnen Sie pro Art: Median, Mittelwert, Standardabweichung und Minimalwert für die Kronblattlänge:
# A tibble: 3 × 5
Species pl_median pl_mean pl_sd pl_min
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 1.5 1.46 0.174 1
2 versicolor 4.35 4.26 0.470 3
3 virginica 5.55 5.55 0.552 4.5
Berechnen Sie die Stichprobengröße (= Zeilenanzahl) pro Ernährungsgruppe im ChickWeight Datensatz:
Rows: 578
Columns: 4
$ weight <dbl> 42, 51, 59, 64, 76, 93, 106, 125, 149, 171, 199, 205, 40, 49, 5…
$ Time <dbl> 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 21, 0, 2, 4, 6, 8, 10, 1…
$ Chick <ord> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
$ Diet <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …

bind_rows() → hängt 2 oder mehr Tabellen zeilenweise aneinander:
intersect(), union(), setdiff()bind_cols() → hängt 2 oder mehr Tabellen spaltenweise aneinander:
XXX_join() Funktionen!XXX_join() → Die Funktionsgruppe verbindet Tabellen basierend auf gleichen Werten in übereinstimmenden Spalten:


Was haben wir gerade gelernt?
# ------------------------------ Vorbereitung ----------------------------------
#### Laden von Paketen
library(tidyverse) # laedt 9 Pakete
# # (das gleiche wie alle Pakete einzeln zu laden)
# library(dplyr)
# library(forcats)
# library(ggplot2)
# library(lubridate)
# library(purrr)
# library(readr)
# library(stringr)
# library(tibble)
# library(tidyr)
#### Eigene Funktionen
# Variantionskoeffizient
cv <- function(x) {
sd(x)/mean(x)
}
# -------------------- Import und Datenaufbereitung ----------------------------
#### Import von CSV-Dateien
# (-> Swirl-Lektion L01 in DSB-03-Datenaufbereitung oder per Anleitung durchs Tidyversum)
# Import der ODS-Datei, welche in den Zeilen 66-68 noch Text enthaelt
iris <- readODS::read_ods("DS1_W03_Saeulendiagramm_mit_iris.ods")
#### Pruefung des Imports und Datensichtung
# (-> Swirl-Lektion L02 in DSB-03)
# Pruefung des Datentyps --> IMMER DIREKT NACH DEM IMPORT VERWENDEN!
str(iris) # str = structure
# Betrachtung des Inhalts
iris
# View(iris)
# Korrektur des Datentyps und der Zeilen
iris <- iris[1:60, ] |>
mutate(across(Sepal.Length:Petal.Width, as.numeric)) |>
mutate(Species = as.factor(Species))
str(iris)
# Welche Werte kommen in jeder Spalte vor?
lapply(iris, unique)
### Weitere Funktionen zur Sichtung einzelner Aspekte
head(iris) # zeigt erste 6 Zeilen (Kopfzeilen)
tail(iris) # zeigt letzte 6 Zeilen (Endzeilen)
class(iris) # Identifikation der Objektklasse (Vektor, Matrix, dataframe,..)
nrow(iris) # Anzahl Zeilen
ncol(iris) # Anzahl Spalten
dim(iris) # Anzahl aller Dimensionen
names(iris) # Spaltennamen
typeof(iris$Sepal.Length) # Datentyp von Spalte 'Sepal.Length'
typeof(iris$Species) # Datentyp von Spalte 'Species'
# ----------------------- Deskriptive Statistik --------------------------------
#### Berechnung mehrerer Statistiken für jede Spalte im data frame
summary(iris)
#### Berechnung versch. Statistiken der Kronblattlaenge, gruppiert nach Art
# (-> Lektion L01 in DSB-02-Datenexploration mit R)
# (-> Lektion L06-Gruppierte Aggregation in DSB-03)
iris_summary <- iris |>
group_by(Species) |>
summarise(
PL_mean = mean(Petal.Length), # Mittelwert
PL_median = median(Petal.Length), # Median
PL_var = var(Petal.Length), # Varianz
PL_sd = sd(Petal.Length), # Standardabweichung
PL_se = sd(Petal.Length)/sqrt(length(Petal.Length)), # Standardfehler
PL_cv = cv(Petal.Length) # Variationskoeffizient
) |>
# die Artnamen anpassen (hier Gattungsnamen anfuegen) und als Faktor speichern
mutate(Species = factor(paste0("Iris ", Species))) |>
# nun die Reihenfolge der Faktorstufen nach PL_mean sortieren
mutate(Species = fct_reorder(.f = Species, .x = PL_mean, .desc = TRUE))
# Zusammenfassung ansehen
iris_summary
#### Saeulendiagramm erstellen mit dem 'ggplot2' Paket
# (siehe auch swirl-Kurs DSB-04-Datenvisualisierung mit ggplot2)
iris_summary |>
ggplot(aes(x = Species, y = PL_mean)) + # initiert Plot
# die Saeulen hinzufuegen
geom_col(fill = "#004586") +
# die Fehlerbalken hinzufuegen
geom_errorbar((aes(ymin = PL_mean - PL_sd, ymax = PL_mean + PL_sd)),
width = 0.2) +
# Achsenbeschriftung anpassen
ylab("Kronblattlänge (in cm)") +
xlab("Schwertlilienart (Gattung Iris)") +
# das Layout anpassen
theme_bw()DS1_VL04b_Demo_DeskriptiveStatistik_iris.R

![]()
![]()
starwars: DS1_W08_Uebungsskript_Datentransformation.R
Sie sind jetzt so weit, …
inner_XXX() Funktionen aus dem dplyr Paket zusammenführen könnten.
Cheatsheet zum dplyr Paket frei verfügbar unter diesem Link.
Enthält wichtigste Funktionen der Datenaufbereitung
Download Link über die DSB Website (alternativ auch im Moodle-Kurs)
Dann testen Sie doch Ihr Wissen in folgendem Abschlussquiz…
![]()
Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

Diese Arbeit is lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.
Kurswebseite: Data Science 1