Grundlagen in R:
Komplexere Objekte

Data Science 1 - Programmieren & Visualisieren

Saskia Otto & Monika Eberhard

Universität Hamburg, IMF

Wintersemester

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

  • einen Überblick über die wichtigsten Objekttypen in R haben.
  • Listen, Matrizen und Dataframes erstellen und deren Aufbau prüfen können.
  • Elemente in Listen und Dataframes auswählen, filtern und ändern können.
  • deskriptive Statistiken wie den Mittelwert, Median oder die Varianz in R berechnen können.

Objekttypen

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’

Listen

Listen

  • Anders als bei atomaren Vektoren dürfen die Elemente einer Liste unterschiedliche Datentypen und auch unterschiedliche Längen haben.
  • Listen begegnen Ihnen v.a. als Output von Funktionen (z.B. von lm() bei der Regression) und sind praktisch bei Schleifen.

Quelle: R for Data Science von Wickam & Grolemund, 2017 (lizensiert unter CC-BY-NC-ND 3.0 US).

Listen | Erstellen

  • Anders als bei atomaren Vektoren dürfen die Elemente einer Liste unterschiedliche Datentypen und auch unterschiedliche Längen haben.
  • Listen begegnen Ihnen v.a. als Output von Funktionen (z.B. von lm() bei der Regression) und sind praktisch bei Schleifen.
  • Sie werden mit list() erstellt – am besten gleich mit Namen für die Elemente:
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

Listen | Struktur

Mit str() erhalten Sie einen kompakten Überblick über den Aufbau einer Liste:

Struktur der Liste anzeigen
str(fang)
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):

Liste in einer Liste
survey <- list(name = "Ostsee-Survey 2026", fang_1 = fang)
str(survey)
List of 2
 $ name  : chr "Ostsee-Survey 2026"
 $ fang_1:List of 3
  ..$ station: chr "Ostsee_01"
  ..$ arten  : chr [1:3] "Hering" "Dorsch" "Sprotte"
  ..$ anzahl : num [1:3] 120 15 300

Listen | Indizierung

  • [ ] gibt wieder eine Liste zurück (eine ‘Teilliste’).
  • [[ ]] und $ geben den Inhalt eines Elements zurück – z.B. einen Vektor.
  • Auf den Inhalt kann dann wie gewohnt die Vektorindizierung angewendet werden.
Teilliste vs. Inhalt
fang[2]    # Liste mit 1 Element
$arten
[1] "Hering"  "Dorsch"  "Sprotte"
fang[[2]]  # der Vektor selbst
[1] "Hering"  "Dorsch"  "Sprotte"
fang$arten # das gleiche per Name
[1] "Hering"  "Dorsch"  "Sprotte"
Listen- + Vektorindizierung kombinieren
fang$arten[1]
[1] "Hering"
fang$anzahl[fang$anzahl > 100]
[1] 120 300

2- und mehrdimensionale Objekte

Matrizen

Matrizen sind 2-dimensionale Objekte, deren Elemente alle den gleichen Datentyp haben müssen. Sie werden vor allem in der numerischen Modellierung verwendet.

  • werden mit matrix() erstellt:
Matrix mit 2 Zeilen
matrix(1:6, nrow = 2)
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
  • oder durch Zusammenfügen von Vektoren als Spalten (cbind()) oder Zeilen (rbind()):
Vektoren spaltenweise verbinden
x <- 1:4
y <- 5:8
mat <- cbind(x, y)
mat
     x y
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8

Arrays

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.

‘Dataframes’ | Was ist das?

  • Die gebräuchlichste Datenstruktur zum Speichern von Daten in R.
  • Ein Dataframe ist eine Liste von gleich langen Vektoren, die als Spalten angeordnet sind
    • → dadurch 2-dimensionale Struktur.
  • Datentypen dürfen pro Vektor, also Spalte, unterschiedlich sein!
  • Jede Spalte entspricht einer Variable, jede Zeile einer Beobachtung.

‘Dataframes’ | Erstellen

  • ‘Dataframes’ kann man mit der Funktion data.frame() erstellen, welche Vektoren mit Namen als Input nimmt:
df <- data.frame(  # Achte auf den Punkt!
  x = c(5, 1, 9),           # 3 Elemente
  y = c("b", "k", "x"),     # 3 Elemente
  z = c(TRUE, FALSE, TRUE)  # 3 Elemente
)
str(df)  # Struktur des Dataframes
'data.frame':   3 obs. of  3 variables:
 $ x: num  5 1 9
 $ y: chr  "b" "k" "x"
 $ z: logi  TRUE FALSE TRUE

‘Tibbles’ | Die moderne Variante

  • Wenn Sie Daten mit Funktionen aus dem Tidyverse (z.B. read_csv()) oder mit readODS/readxl importieren, erhalten Sie meist ein Tibble.
  • Ein Tibble ist ein Dataframe – mit ein paar praktischen Unterschieden, z.B. einer übersichtlicheren Ausgabe mit Angabe der Datentypen:
Dataframe
df
  x y     z
1 5 b  TRUE
2 1 k FALSE
3 9 x  TRUE
Tibble
tb <- tibble(
  x = c(5, 1, 9),
  y = c("b", "k", "x"),
  z = c(TRUE, FALSE, TRUE)
)
tb
# A tibble: 3 × 3
      x y     z    
  <dbl> <chr> <lgl>
1     5 b     TRUE 
2     1 k     FALSE
3     9 x     TRUE 

Längenattribute

length() in 2- und multi-dimensionalen Objekten lässt sich verallgemeinern zu

  • nrow() und ncol() bei 2 Dim.
Anzahl Zeilen und Spalten
nrow(df)
[1] 3
ncol(df)
[1] 3
nrow(mat)
[1] 4
ncol(mat)
[1] 2
  • dim() für alle Dimensionen auf einmal
Alle Dimensionen
dim(df)
[1] 3 3
dim(mat)
[1] 4 2

(zeigt erst die Anzahl der Zeilen, dann der Spalten)

Namensattribute

names() zeigt in ‘Dataframes’ die Spaltennamen an:

Spaltennamen abfragen
names(df)
[1] "x" "y" "z"

Diese können auch überschrieben werden:

Spaltennamen ändern
names(df) <- c("x_neu", "y_neu", "z_neu")
df
  x_neu y_neu z_neu
1     5     b  TRUE
2     1     k FALSE
3     9     x  TRUE

Erste und letzte Zeilen anzeigen

Die ersten 6 Zeilen
head(iris)
  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
Die letzten 6 Zeilen
tail(iris)
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
145          6.7         3.3          5.7         2.5 virginica
146          6.7         3.0          5.2         2.3 virginica
147          6.3         2.5          5.0         1.9 virginica
148          6.5         3.0          5.2         2.0 virginica
149          6.2         3.4          5.4         2.3 virginica
150          5.9         3.0          5.1         1.8 virginica

2-dimensionale Indizierung

Indizierung | [Zeilen, Spalten]

  • Die Indizierung von Matrizen und ‘Dataframes’ funktioniert genauso wie die Vektor-basierte Indizierung, nur dass die Auswahl für jede Dimension erfolgen muss.
  • Die Indizes für Zeilen und Spalten werden durch ein Komma getrennt (Position, Name oder logischer Vektor sind erlaubt).
  • Ein leerer Index wählt alle Zeilen bzw. Spalten aus.
Anhand der Position auswählen
df[ , 1:2]    # alle Zeilen, Spalte 1-2
  x_neu y_neu
1     5     b
2     1     k
3     9     x
df[c(1,3), 2] # Zeile 1+3, Spalte 2
[1] "b" "x"

→ Achtung: Bei einer einzelnen Spalte gibt ein Dataframe einen Vektor zurück, ein Tibble bleibt ein Tibble.

Anhand der Namen auswählen
# alle Zeilen, Spalte 'x_neu':
df[ , "x_neu"]
[1] 5 1 9
# das gleiche beim Tibble:
tb[ , "x"]
# A tibble: 3 × 1
      x
  <dbl>
1     5
2     1
3     9

Neue Objekte über Indizierung erstellen

Teile einer Matrix mittels Positionsindizierung auswählen und neu abspeichern:

Zeile 1 und 4, Spalte 2 bis 7
mat <- matrix(1:90, ncol = 10, byrow = TRUE)
new_mat <- mat[c(1,4), 2:7]
new_mat
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    3    4    5    6    7
[2,]   32   33   34   35   36   37

Positionsindizierung genauer erklärt

Spaltenindizierung | $

  • Wie bei Listen können Sie mit $ ein benanntes Element auswählen.
  • Da ‘Dataframes’ Listen von Vektoren darstellen (in Spalten angelegt), wählt $ hier eine Spalte aus – und gibt sie als Vektor zurück:
Ganze Spalten auswählen
df
  x_neu y_neu z_neu
1     5     b  TRUE
2     1     k FALSE
3     9     x  TRUE
df$y_neu
[1] "b" "k" "x"
df[ , 2] # das gleiche
[1] "b" "k" "x"
Spaltenwahl + Vektorindizierung
df$x_neu[1]
[1] 5
df$y_neu[1:2]
[1] "b" "k"
df$z_neu[c(1,3)]
[1] TRUE TRUE

Daten filtern mit logischer Indizierung | 1

Calc vs. R

  • Typischerweise filtert man die Zeilen, nicht die Spalten (wie auch in Calc):
    df[Zeilenabfrage, Spalten]
  • D.h. der Zeilenindex stellt eine Abfrage dar, die sich auf die Werte einer Spalte bezieht.

Daten filtern mit logischer Indizierung | 2

Calc vs. R - ein Vergleich

Auswahl aller Spalten und der Zeilen, wo die Werte in Spalte ‘x_neu’ >= 5 sind.

Calc

R

Ausgangsdaten
df
  x_neu y_neu z_neu
1     5     b  TRUE
2     1     k FALSE
3     9     x  TRUE
Gefilterte Zeilen
df[df$x_neu >= 5, ]
  x_neu y_neu z_neu
1     5     b  TRUE
3     9     x  TRUE

Daten filtern mit logischer Indizierung | 3

Weitere Beispiele

Logische Spalte als Filter
# Alle Spalten, aber nur die Zeilen mit TRUE in 'z_neu'
# (die Spalte ist bereits logisch, ein '== TRUE' ist nicht nötig)
df[df$z_neu, ]
  x_neu y_neu z_neu
1     5     b  TRUE
3     9     x  TRUE
Filtern nach Kategorien
# Spalte 1 und 2 und die Zeilen, die in 'y_neu' ein "k" enthalten
df[df$y_neu == "k", 1:2]
  x_neu y_neu
2     1     k
# Zeilen, die in 'y_neu' ein "k" ODER "x" enthalten
df[df$y_neu %in% c("k", "x"), ]
  x_neu y_neu z_neu
2     1     k FALSE
3     9     x  TRUE

Werte mittels Indizierung ersetzen

Einzelne Werte überschreiben
df
  x_neu y_neu z_neu
1     5     b  TRUE
2     1     k FALSE
3     9     x  TRUE
df[1,1]
[1] 5
df[1,1] <- NA
df$z_neu[3] <- FALSE
df
  x_neu y_neu z_neu
1    NA     b  TRUE
2     1     k FALSE
3     9     x FALSE

Neue Spalten mit dem $ Operator anhängen

Neue Spalten erzeugen
df$gemessen <- FALSE  # Einzelwert wird auf alle Zeilen recycelt
df$x_log <- log(df$x_neu)
df$x_char <- as.character(df$x_neu)
df
  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).

Your turn …

Quiz 1 | PlantGrowth - Objekttyp

Schauen Sie sich folgenden Datensatz an:

head(PlantGrowth, 3)
  weight group
1   4.17  ctrl
2   5.58  ctrl
3   5.18  ctrl

Quiz 2 | PlantGrowth - Objektstruktur

Schauen Sie sich die Struktur vom PlantGrowth Datensatz an:

str(PlantGrowth)
'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 ...

Quiz 3 | Listenindizierung

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.

fang[2]
$arten
[1] "Hering"  "Dorsch"  "Sprotte"
fang[[2]]
[1] "Hering"  "Dorsch"  "Sprotte"

Quiz 4 | Zeilen filtern

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.

PlantGrowth[PlantGrowth$group == 'ctrl', ]
   weight group
1    4.17  ctrl
2    5.58  ctrl
3    5.18  ctrl
4    6.11  ctrl
5    4.50  ctrl
6    4.61  ctrl
7    5.17  ctrl
8    4.53  ctrl
9    5.33  ctrl
10   5.14  ctrl

Dataframes numerisch zusammenfassen

Übersicht der built-in Funktionen

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
  • Es gibt keine built-in Funktion für den Standardfehler und den Variationskoeffizienten sowie die Schiefe und Kurtosis!
  • Denken Sie bei fehlenden Werten an na.rm = TRUE!

Beispiel: Mittelwert

Beispielvektor
x <- 1:30
Manuelle Berechnung
sum(x) / length(x)
[1] 15.5
Built-in Funktion
mean(x)
[1] 15.5

Deskriptive Zusammenfassung

Shortcut mit summary()

Zusammenfassung aller Spalten
summary(iris)
  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                  

Weitere Shortcuts mit DSBtools | describe_df()

Einen Dataframe zusammenfassen
library(DSBtools) # Paket laden (auf dem Server und mit Setup-Skript installiert)
options(DSBtools.language = "de") # Ausgabe auf Deutsch
iris_desc <- describe_df(data = iris)
iris_desc
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
str(iris_desc)
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"

Weitere Shortcuts mit DSBtools | explore_var()

Eine Variable explorieren
explore_var(x = iris$Petal.Length, xlab = "Kronblattlänge (cm)")

  • explore_var() erkennt den Typ einer Variable und erstellt passende Grafiken und eine Tabelle mit deskriptiven Statistiken.
  • Der Funktion wird ein Vektor übergeben, also z.B. eine Spalte, die Sie mit $ auswählen.
  • Enthält auch Statistiken, für die es keine built-in Funktion gibt (z.B. den Standardfehler).

Zurück zu unseren Demos..

Von Calc zu R wechseln | Demo A

Lineare Regression zum
Fütterungsversuch beim Kabeljau

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()

Von Calc zu R wechseln | Demo B

Deskriptive Statistik mit iris

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()

Übungen

Zu bearbeitende swirl-Lektionen

Kurs DSB-01-R Grundlagen

  • L13-Listen
  • (L14-Matrizen und Arrays)
  • L15-Dataframes
  • (L16-Praktische Tipps rund ums Programmieren)

Kurs DSB-02-Datenexploration mit R (optional)

  • L01-Erste numerische Analyse
  • (L02-Erste grafische Analyse)
  • (L03-Regressionsgerade berechnen)

Übungsaufgaben Woche 6

Alle Aufgaben der Übungswoche finden Sie im Handbuch:

  • die zu bearbeitenden Übungsskripte
  • die (optionalen) swirl-Lektionen und
  • den aktuellen Stand der Fallstudie.
  • Die Übungsskripte und Daten liegen in Ihrem R-Projektordner DS1-R-Uebungen (Unterordner uebungsskripte bzw. data).
  • Öffnen Sie immer zuerst die Projektdatei DS1-R-Uebungen.Rproj, dann stimmen alle Dateipfade.

Wie fühlen Sie sich jetzt…?

Total konfus?


Keine Sorge…

… im swirl-Kurs werden Sie direkt an die Hand genommen und Stück für Stück angeleitet.

Überblick aller Objekttypen

Siehe auch DSB Cheatsheet
R-Grundlagen und Data Wrangling
(auf Moodle oder DSB Website).

Überblick aller Objektindizierungen

Siehe auch DSB Cheatsheet
R-Grundlagen und Data Wrangling
(auf Moodle oder DSB Website).

Total gelangweilt?


Dann machen Sie doch einfach die nächsten swirl Lektionen auch schon…

Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

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