Eine Liste mit 3 Elementen
fang <- list(
station = "Ostsee_01",
arten = c("Hering", "Dorsch", "Sprotte"),
anzahl = c(120, 15, 300)
)
fang$station
[1] "Ostsee_01"
$arten
[1] "Hering" "Dorsch" "Sprotte"
$anzahl
[1] 120 15 300

Data Science 1 - Programmieren & Visualisieren
Saskia Otto & Monika Eberhard
Universität Hamburg, IMF
Wintersemester
![]()
Datenstrukturen in R lassen sich bzgl. ihrer Dimensionalität und der Homogenität bzw. Heterogenität ihrer Datentypen in fünf verschiedene Objekttypen unterscheiden:
| Dimensionen | Homogen | Heterogen |
|---|---|---|
| 1D | (Atomarer) Vektor | Liste |
| 2D | Matrix | ‘Dataframe’ (& ‘Tibble’) |
| >2D | ‘Array’ |

lm() bei der Regression) und sind praktisch bei Schleifen.
lm() bei der Regression) und sind praktisch bei Schleifen.list() erstellt – am besten gleich mit Namen für die Elemente:Mit str() erhalten Sie einen kompakten Überblick über den Aufbau einer Liste:
List of 3
$ station: chr "Ostsee_01"
$ arten : chr [1:3] "Hering" "Dorsch" "Sprotte"
$ anzahl : num [1:3] 120 15 300
Listen können sogar weitere Listen enthalten (man nennt sie daher auch rekursive Vektoren):
[ ] gibt wieder eine Liste zurück (eine ‘Teilliste’).[[ ]] und $ geben den Inhalt eines Elements zurück – z.B. einen Vektor.
Matrizen sind 2-dimensionale Objekte, deren Elemente alle den gleichen Datentyp haben müssen. Sie werden vor allem in der numerischen Modellierung verwendet.
matrix() erstellt:Arrays sind multi-dimensionale Objekte des gleichen Datentyps. Sie werden in der Datenanalyse in R aber eher selten genutzt und daher hier nicht näher beschrieben.


data.frame() erstellen, welche Vektoren mit Namen als Input nimmt:read_csv()) oder mit readODS/readxl importieren, erhalten Sie meist ein Tibble.length() in 2- und multi-dimensionalen Objekten lässt sich verallgemeinern zu
names() zeigt in ‘Dataframes’ die Spaltennamen an:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa

[Zeilen, Spalten] x_neu y_neu
1 5 b
2 1 k
3 9 x
[1] "b" "x"
→ Achtung: Bei einer einzelnen Spalte gibt ein Dataframe einen Vektor zurück, ein Tibble bleibt ein Tibble.
Teile einer Matrix mittels Positionsindizierung auswählen und neu abspeichern:
$$ ein benanntes Element auswählen.$ hier eine Spalte aus – und gibt sie als Vektor zurück:df[Zeilenabfrage, Spalten]Auswahl aller Spalten und der Zeilen, wo die Werte in Spalte ‘x_neu’ >= 5 sind.
Logische Spalte als Filter
x_neu y_neu z_neu
1 5 b TRUE
3 9 x TRUE
$ Operator anhängenNeue Spalten erzeugen
x_neu y_neu z_neu gemessen x_log x_char
1 NA b TRUE FALSE NA <NA>
2 1 k FALSE FALSE 0.000000 1
3 9 x FALSE FALSE 2.197225 9
→ Die neue Spalte muss entweder genauso lang sein wie der Dataframe oder ein Einzelwert (dann greift die Recycling-Regel).
![]()
PlantGrowth - Objekttyp![]()
Schauen Sie sich folgenden Datensatz an:
PlantGrowth - Objektstruktur![]()
Schauen Sie sich die Struktur vom PlantGrowth Datensatz an:
'data.frame': 30 obs. of 2 variables:
$ weight: num 4.17 5.58 5.18 6.11 4.5 4.61 5.17 4.53 5.33 5.14 ...
$ group : Factor w/ 3 levels "ctrl","trt1",..: 1 1 1 1 1 1 1 1 1 1 ...
![]()
fang[2] gibt eine Liste mit einem Element zurück, fang[[2]] (oder fang$arten) dagegen den Inhalt – also den Vektor. fang[arten] sucht nach einem Objekt namens arten (Anführungszeichen fehlen!) und fang(2) würde fang als Funktion aufrufen.
![]()
Mit == wird für jede Zeile geprüft, ob in der Spalte group der Wert ‘ctrl’ steht. Das Komma trennt die Zeilenabfrage von der Spaltenauswahl – da danach nichts steht, werden alle Spalten ausgewählt.

| Funktion | Statistik |
|---|---|
sum() |
Summe |
mean() |
Arithmetischer Mittelwert |
median() |
Median |
min() |
Minimalwert |
max() |
Maximalwert |
range() |
Minimum und Maximum |
var() |
Varianz |
sd() |
Standardabweichung |
quantile() |
Quantile |
cov() |
Kovarianz |
cor() |
(Pearsons) Korrelationskoeffizient |
summary() |
Berechnet unterschiedliche Statistiken |
na.rm = TRUE!summary() Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
describe_df()Numerische Variablen
# A tibble: 4 × 15
variable n n_missing mean median sd var iqr min max skewness kurtosis se ci_lower ci_upper
<chr> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Sepal.Length 150 0 5.84 5.8 0.828 0.686 1.3 4.3 7.9 0.312 -0.574 0.0676 5.71 5.98
2 Sepal.Width 150 0 3.06 3 0.436 0.190 0.5 2 4.4 0.316 0.181 0.0356 2.99 3.13
3 Petal.Length 150 0 3.76 4.35 1.77 3.12 3.5 1 6.9 -0.272 -1.40 0.144 3.47 4.04
4 Petal.Width 150 0 1.20 1.3 0.762 0.581 1.5 0.1 2.5 -0.102 -1.34 0.0622 1.08 1.32
Kategoriale Variablen
# A tibble: 1 × 7
variable type n n_missing n_categories mode mode_rel
<chr> <chr> <int> <int> <int> <chr> <dbl>
1 Species nominal 150 0 3 setosa 0.333
List of 2
$ numeric : tibble [4 × 15] (S3: tbl_df/tbl/data.frame)
..$ variable : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
..$ n : int [1:4] 150 150 150 150
..$ n_missing: int [1:4] 0 0 0 0
..$ mean : num [1:4] 5.84 3.06 3.76 1.2
..$ median : num [1:4] 5.8 3 4.35 1.3
..$ sd : num [1:4] 0.828 0.436 1.765 0.762
..$ var : num [1:4] 0.686 0.19 3.116 0.581
..$ iqr : num [1:4] 1.3 0.5 3.5 1.5
..$ min : num [1:4] 4.3 2 1 0.1
..$ max : num [1:4] 7.9 4.4 6.9 2.5
..$ skewness : num [1:4] 0.312 0.316 -0.272 -0.102
..$ kurtosis : num [1:4] -0.574 0.181 -1.396 -1.336
..$ se : num [1:4] 0.0676 0.0356 0.1441 0.0622
..$ ci_lower : num [1:4] 5.71 2.99 3.47 1.08
..$ ci_upper : num [1:4] 5.98 3.13 4.04 1.32
$ categorical: tibble [1 × 7] (S3: tbl_df/tbl/data.frame)
..$ variable : chr "Species"
..$ type : chr "nominal"
..$ n : int 150
..$ n_missing : int 0
..$ n_categories: int 3
..$ mode : chr "setosa"
..$ mode_rel : num 0.333
- attr(*, "class")= chr "ds_description"
- attr(*, "language")= chr "de"
explore_var()explore_var() erkennt den Typ einer Variable und erstellt passende Grafiken und eine Tabelle mit deskriptiven Statistiken.$ auswählen.

Die hervorgehobenen Funktionen kennen wir jetzt alle schon:
# ------------------------------ Vorbereitung ----------------------------------
#### Laden von Paketen
library(tidyverse)
# library(readODS)
# library(readxl)
library(DSBtools)
options(DSBtools.language = "de") # Ausgabe auf Deutsch
#### Eigene Funktionen
# -------------------- Import und Datenaufbereitung ----------------------------
#### Import einer Textdatei im CSV-Format (das gängigste Format)
kabeljau_csv <- read.csv(file = "data/Wachstum-Futter.csv")
str(kabeljau_csv) # --> Output ist ein data frame
#### Import von Calc- und Excel-Dateien (ODS- und XLSX-Format)
# Import einer ODS-Datei mit dem 'readODS' Paket
kabeljau <- readODS::read_ods("data/DS1_W03_Streudiagramm_Kabeljau.ods",
sheet = "Daten_Visualisierung")
str(kabeljau) # --> Output ist ein Tibble
# Import einer XLSX-Datei mit z.B. dem 'readxl' Paket
kabeljau_xlsx <- readxl::read_excel("data/DS1_W03_Streudiagramm_Kabeljau.xlsx",
sheet = "Daten_Visualisierung")
str(kabeljau_xlsx) # --> Output ist ein Tibble
#### Datensichtung und -transformation
# Anpassen der Spaltennamen
names(kabeljau) <- c("verzehr", "wachstum")
str(kabeljau)
# Wertebereich prüfen
summary(kabeljau)
# Beziehung explorieren: Ist sie linear? Gibt es Ausreisser?
explore_var(x = kabeljau$verzehr, y = kabeljau$wachstum,
xlab = "Verzehr/Konsum (J/g/Tag)", ylab = "Wachstum (J/g/Tag)")
# ---------------------- Lineare Regression: Berechnung ------------------------
# (-> Lektion L03 in DSB-02-Datenexploration mit R)
#### Manuelle Berechnung
# Um Tipparbeit zu sparen, speichern wir die Spalten als einzelne Vektoren
x <- kabeljau$verzehr
y <- kabeljau$wachstum
# Steigungsparameter b berechnen
b <- cov(x = x, y = y)/ var(x) # der shortcut mit der Kovarianz und Varianz
b
# Achsenabschnitt a berechnen
a <- mean(y) - b*mean(x)
a
# Das Bestimmtheitsmass R^2 berechnen
y_pred <- a + b*x # die vorhergesagten Werte
ss_gesamt <- sum( (y - mean(y))^2 ) # Summenquadrate Gesamt
ss_regression <- sum( (y_pred - mean(y))^2 ) # Summenquadrate der Regression
R2 <- round(ss_regression/ss_gesamt, 4)
R2
##### Zum Vergleich die Regression automatisch berechnen mit lm()
# Erstellung des Modells
mod <- lm(formula = wachstum ~ verzehr, data = kabeljau)
mod
# Ausgabe nur der beiden Koeffizienten
coef(mod)
# Ausgabe aller wichtigen Statistiken des Modells, inklusive von R^2
# (mehr dazu in Data Science 2)
summary(mod)
# ------------------- Lineare Regression: Visualisierung ----------------------
#### Visualisierung mit den Basisfunktionen (-> Lektion L02 und L03 in DSB-02)
# Sog. high-level Funktion plot()
plot(x = kabeljau$verzehr, y = kabeljau$wachstum,
pch = 15, cex = 1.2, col = "#004586",
xlab = "Verzehr/Konsum (J/g/Tag)", ylab = "Wachstum (J/g/Tag)")
# Sog. low-level Funktionen, die Elemente in den angezeigten Plot einfügen
abline(a = a, b = b)
title(
main = paste0("wachstum = ", round(a, 3), " + ", round(b, 3), "*verzehr"),
sub = paste0("Bestimmtheitsmaß R^2 = ", R2)
) # (paste0() verkettet Zeichen miteinander)
#### Visualisierung mit ggplot2 (-> siehe swirl-Kurs DSB-04)
kabeljau |>
ggplot(aes(x = verzehr, y = wachstum)) + # initiert Plot
geom_point(colour = "#004586", shape = 15, size = 3) +
# Punktelemente hinzufügen
geom_abline(slope = b, intercept = a) +
# Achsenbeschriftung anpassen und Titel hinzufügen
labs(x = "Verzehr/Konsum (J/g/Tag)", y = "Wachstum (J/g/Tag)",
title = str_c("wachstum = ", round(a, 3), " + ", round(b, 3), "*verzehr"),
subtitle = str_c("Bestimmtheitsmaß R^2 = ", R2)) +
# das Layout anpassen
theme_bw()DS1_W04_Demo_LineareRegression_Kabeljau.R

Die hervorgehobenen Funktionen kennen wir jetzt alle schon:
# ------------------------------ 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)
library(DSBtools)
options(DSBtools.language = "de") # Ausgabe auf Deutsch
#### 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("data/DS1_W03_Saeulendiagramm_mit_iris.ods")
#### Prüfung des Imports und Datensichtung
# (-> Swirl-Lektion L02 in DSB-03)
# Prüfung 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
# Klassische Zusammenfassung mit base R (Ausgabe nur in der Konsole)
summary(iris)
# Shortcut mit DSBtools: Statistiken für jede Spalte, passend zum erkannten
# Variablentyp (z.B. Häufigkeiten bei 'Species', Mittelwert & Co. bei den
# metrischen Spalten). Das Ergebnis ist ein Objekt, mit dem Sie weiterarbeiten
# können - speichern Sie es dazu unter einem Namen:
describe_df(data = 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 anfügen) 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
# Kontrolle mit DSBtools: Stimmen Ihre Werte? describe_var() berechnet die
# Statistiken der Variable 'x' getrennt für jede Gruppe in 'by'
# (Angaben zum 95%-Konfidenzintervall -> kommt in Data Science 2)
iris_stats <- describe_var(x = iris$Petal.Length, by = iris$Species)
iris_stats
#### 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 hinzufügen
geom_col(fill = "#004586") +
# die Fehlerbalken hinzufügen
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_W04_Demo_DeskriptiveStatistik_iris.R

![]()
![]()

Alle Aufgaben der Übungswoche finden Sie im Handbuch:

… im swirl-Kurs werden Sie direkt an die Hand genommen und Stück für Stück angeleitet.
Siehe auch DSB Cheatsheet
R-Grundlagen und Data Wrangling
(auf Moodle oder DSB Website).
Siehe auch DSB Cheatsheet
R-Grundlagen und Data Wrangling
(auf Moodle oder DSB Website).
Dann machen Sie doch einfach die nächsten swirl Lektionen auch schon…
Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

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