Grundlagen in R:
Komplexere Objekte

Data Science 1 - Programmieren & Visualisieren

Saskia Otto

Universität Hamburg, IMF

Wintersemester 2023/2024

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

  • einen Überblick über alle Objekte in R haben.
  • Daten bzw. Elemente in Listen, Matrizen und data frames filtern, auswählen und ändern können.
  • deskriptive Statistiken wie den Mittelwert, Median oder die Varianz in R berechnen können.
  • sauberen Programmcode schreiben 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 ‘Data frame’ (& ‘Tibbles’)
>2D ‘Array’

Listen

Listen | Erstellen

  • Sind anders als atomare Vektoren weil ihre Elemente unterschiedliche Datentypen und auch Datenstrukturen haben dürfen.
  • Sie sind besonders praktisch in Schleifen und werden oft als Output von Funktionen verwendet.
  • Werden mit list() erstellt:
x <- list(
  1:3, 
  "a", 
  c(TRUE, FALSE, TRUE), 
  c(2.3, 5.9, 1.1, 4.8, 11.0)
)
x
[[1]]
[1] 1 2 3

[[2]]
[1] "a"

[[3]]
[1]  TRUE FALSE  TRUE

[[4]]
[1]  2.3  5.9  1.1  4.8 11.0

Listen zählen auch zu den Vektoren

Erstellung eines Vektors vom Typ 'Liste'
vector("list", 2)
[[1]]
NULL

[[2]]
NULL

Beide Listenelemente sind erstmal leer (NULL steht oft für die Abwesenheit eines Vektors und verhält sich typischerweise wie ein Vektor der Länge 0).

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

Warum wird eine Liste als Vektor betrachtet?

Listen | Struktur

Eine nützliche Funktion zum Anzeigen der Objektstruktur ist str():

x <- list(1, 2, 3)
str(x)
List of 3
 $ : num 1
 $ : num 2
 $ : num 3
x_named <- list(a=1, b=2, c=3)
str(x_named)
List of 3
 $ a: num 1
 $ b: num 2
 $ c: num 3

Listen | Rekursion

  • Werden manchmal als rekursive Vektoren bezeichnet, weil eine Liste weitere Listen enthalten kann.
x <- list(list(list(list("aha"))))
str(x)
List of 1
 $ :List of 1
  ..$ :List of 1
  .. ..$ :List of 1
  .. .. ..$ : chr "aha"

Visualisierung folgender Listen

x1 <- list(c(1, 2), c(3, 4))
x2 <- list(list(1, 2), list(3, 4))
x3 <- list(1, list(2, list(3)))

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

2- und mehrdimensionale Objekte

Matrizen

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

  • werden mit matrix() erstellt:
matrix(1:6, nrow = 2, byrow = TRUE)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
matrix(1:6, ncol = 2, byrow = FALSE)
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
  • oder mit cbind() und rbind():
x <- 1:4
y <- 5:8
cbind(x, y)
     x y
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8
rbind(x, y)
  [,1] [,2] [,3] [,4]
x    1    2    3    4
y    5    6    7    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.

‘Data frames’ | Was ist das?

  • Die gebräuchlichste Datenstruktur zum Speichern von Daten in R.
  • Repräsentiert eine Liste von gleich langen Vektoren als Spalten
    • → dadurch 2-dimensionale Struktur
  • Sehr flexibel da sie die gleichen Eigenschaften wie eine Liste und Matrix besitzt.
  • Datentypen dürfen pro Vektor, also Spalte, unterschiedlich sein!

‘Data frames’ | Erstellen

  • ‘Data frames’ 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 data frames
'data.frame':   3 obs. of  3 variables:
 $ x: num  5 1 9
 $ y: chr  "b" "k" "x"
 $ z: logi  TRUE FALSE TRUE

‘Data frames’ | Aus Matrix konvertieren

  • Matrizen lassen sich in ‘data frames’ umwandeln mit as.data.frame() und wieder zurück mit as.matrix() (solange der Datentyp gleich ist):
x <- 1:3
y <- 4:6
mat <- cbind(x, y)
mat
     x y
[1,] 1 4
[2,] 2 5
[3,] 3 6
mat2df <- as.data.frame(mat)
mat2df
  x y
1 1 4
2 2 5
3 3 6
as.matrix(mat2df)
     x y
[1,] 1 4
[2,] 2 5
[3,] 3 6

Längenattribute

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

  • nrow() and ncol() bei 2 Dimensionen
nrow(df)
[1] 3
ncol(df)
[1] 3
nrow(mat)
[1] 3
ncol(mat)
[1] 2
  • dim() bei 2 oder 3 Dimensionen
dim(df)
[1] 3 3
dim(mat)
[1] 3 2

(zeigt erst die Zeile, dann die Spalte, dann ggf. die Anzahl der 3. Dim.)

Namensattribute

names() zeigt in ‘data frames’ den Spaltennamen an:

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

Diese können auch überschrieben werden:

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

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
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 Indexierung

Indexierung | [Zeilen, Spalten]

  • Die Indexierung von Matrizen und ‘data frames’ funktioniert genauso wie die Vektor-basierte Indexierung, nur dass die Auswahl für jede Dimension erfolgen muss.
  • Es wird jede Dimension mit einem 1D Index getrennt durch ein Komma angegeben (‘integer’, ‘logical’, oder ‘character’ Indizes sind erlaubt).
  • Leere Indizes sind erlaubt um alle Zeilen bzw. Spalten auszuwählen.
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"
Anhand der Namen auswählen
# alle Zeilen, Spalte 'x_neu':
df[ , c("x_neu") ]
[1] 5 1 9

Neue Objekte über Indexierung erstellen

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

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

Positionsindexierung genauer erklärt

Spalten-Indexierung | $

  • $ ist eine Kurzschreibweise (‘shorthand notation’) zum Extrahieren von benannten Elementen in einer Liste.
  • Da ‘data frames’ Listen von Vektoren darstellen (in Spalten angelegt), kann diese Kurzschreibweise hier auch zur Auswahl von Spalten verwendet werden:
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 + Vektorenindexierung
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 Indexierung | 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, und diese bezieht sich aber immer auf Elemente der ausgewählten Spalte(n).

Daten filtern mit logischer Indexierung | 2

Calc vs. R - ein Vergleich

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

Calc

R

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

Daten filtern mit logischer Indexierung | 3

Weitere Beispiele

# Wähle alle Spalten, aber nur die Zeilen mit den Werten TRUE in 'z_neu'
df[df$z_neu == TRUE, ]
  x_neu y_neu z_neu
1     5     b  TRUE
3     9     x  TRUE
# Wähle nur 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

Werte mittels Indexierung ersetzen

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 (Vektoren) mit dem $ Operator anhängen

df$z_neuer <- rep("FALSE", 3)
df$x_log <- log(df$x_neu)
df$x_char <- as.character(df$x_neu)
df
  x_neu y_neu z_neu z_neuer    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

Your turn …

00:40

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

Der Datensatz ist 2-dimensional und die Spalten haben unterschiedliche Datentypen (heterogen).

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 ...

In einem geordneten, sauberen Datensatz sind die Variablen immer spaltenmäßig angeordnet und die Beobachtungseinheiten (observations) zeilenmäßig. ‘PlantGrowth’ enthält 30 Beobachtungen und 2 Variablen, sprich 20 Zeilen und 2 Spalten.

Data frames numerisch zusammenfassen

Übersicht der built-in Funktionen

Funktion Statistik
sum() Summe
mean() Arithmetischer Mittelwert
median() Median
min() Minimalwert
max() Maximalwert
range() Bereich zwischen Minimum und Maximum
var() Varianz
sd() Standardabweichung
quantile() Quantilen
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!

Beispiel: Mittelwert

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

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
summary(iris)
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300  
 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  
       Species  
 setosa    :50  
 versicolor:50  
 virginica :50  
                
                
                

Zurück zu unserem iris Skript

Was kennen wir jetzt?

# ------------------------------ Vorbereitung ----------------------------------

#### Laden von Paketen
library(tidyverse) # laedt 9 Pakete


#### Eigene Funktionen

# Variantionskoeffizient
cv <- function(x) {
  sd(x)/mean(x)
}


# -------------------- Import und Datenaufbereitung ----------------------------

#### Import von CSV-Dateien

# Import des weiten (falsch strukturierten) Datensatzes --> KLAPPT NICHT
iris <- read.csv("iris.csv", sep = ";")
iris <- read.delim("iris.csv", sep = ";", header = FALSE)

# Import des in Calc transponierten (und dann als CSV-Datei gespeicherten)
# Datensatzes --> KLAPPT
iris <- read.csv("iris_transponiert.csv")


#### Datensichtung
iris
# View(iris)
head(iris)
tail(iris)
class(iris)

nrow(iris)
ncol(iris)
dim(iris)

names(iris)
typeof(iris$Sepal.Length)
typeof(iris$Species)

# Diese Funktion fasst die obigen zusammen --> IMMER VERWENDEN!
str(iris)


#### Aufgabe aus Uebungswoche 1: Daten zuerst nach Artnamen alphabetisch
# sortieren und dann innerhalb der Arten nach Kelchblattlaenge absteigend
arrange(iris, Species, desc(Sepal.Length))


# ------------ Alternative Variante (ohne Vorbehandlung in Calc) ---------------
# --> weiten Datensatz mit Funktion aus 'readr' Paket einlesen und anpassen

#### Import
iris2 <- read_delim("iris.csv", delim = ";", col_names = FALSE)
iris2
class(iris2) # ein tibble

#### Datenaufbereitung

iris2 <- t(iris2)
class(iris2)

iris2_names <- iris2[1, ]
iris2 <- iris2[-1, ]
iris2

colnames(iris2) <- iris2_names
rownames(iris2) <- NULL

iris2 <- iris2 |>
  as.data.frame() |>
  mutate(across(Sepal.Length:Petal.Width, as.double))

# Pruefen ob die Umwandlung richtig ist
head(iris2)
str(iris2)



# ------------------- Numerische deskriptive Statistik -------------------------

#### Berechnung verschiedener Statistiken pro Variable (hier Kronblattlaenge)

# Lageparameter
mean(iris$Petal.Length)
median(iris$Petal.Length)

# Streuungsparameter
min(iris$Petal.Length)
max(iris$Petal.Length)
range(iris$Petal.Length)

var(iris$Petal.Length)
sd(iris$Petal.Length)
sd(iris$Petal.Length)/sqrt(length(iris$Petal.Length))
cv(iris$Petal.Length) # mit eigener Funktion (siehe oben)

quantile(iris$Petal.Length, probs = c(0.25, 0.5, 0.75))


#### Berechnung der Statistiken fuer mehrere Spalten -> hier in einer Schleife

# Leere Liste erstellen
meine_statistiken <- vector("list", length = 4)
names(meine_statistiken) <- names(iris)[1:4]

# for-Schleife mit 4 Iterationen (fuer Spalte 1-4 in iris)
for (i in 1:4) {

  meine_statistiken[[i]] <- c(
    Min = min(iris[[i]]),
    unteres_Quartil = quantile(iris[[i]], probs = 0.25),
    Median = median(iris[[i]]),
    Mittelwert = mean(iris[[i]]),
    oberes_Quartil = quantile(iris[[i]], probs = 0.75),
    Max = max(iris[[i]]),
    Varianz = var(iris[[i]]),
    Standardabweichung = sd(iris[[i]]),
    Standardfehler = sd(iris[[i]])/sqrt(length(iris[[i]])),
    Variationskoeffizient = cv(iris[[i]])
  )

}

meine_statistiken


#### Shortcut-Funktion: summary()
summary(iris)

# Bei Faktoren ist die summary Anzeige anders als beim Typ 'character'
iris |>
  mutate(Species = as.factor(Species)) |>
  summary()


#### Eigene (gruppierte) Statistiken fuer verschiedene Spalten mit 'tidyverse'
iris |>
  summarise(mean_sl = mean(Sepal.Length))

iris |>
  summarise(across(Sepal.Length:Petal.Width, .fns = list(mean = mean, sd = sd)))

# Statistiken gruppiert nach Species berechnen geht fast genauso
iris |>
  group_by(Species) |>
  summarise(mean_sl = mean(Sepal.Length))

iris |>
  group_by(Species) |>
  summarise(across(Sepal.Length:Petal.Width, .fns = list(mean = mean, sd = sd)))



# ------------------- Grafische deskriptive Statistik --------------------------

#### Berechnung von Mittelwert und Standardabweichung
iris_summary <- iris |>
  group_by(Species) |>
  summarise(
    PL_mean = mean(Petal.Length),
    PL_sd = sd(Petal.Length)
  ) |>
  # 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))

# Datensatz pruefen
iris_summary

# Grafik erstellen mit dem 'ggplot2' Paket (in 'tidyverse enthalten')
iris_summary |>
  ggplot(aes(x = Species, y = PL_mean)) +
  geom_col(fill = "#004586") +
  geom_errorbar((aes(ymin = PL_mean - PL_sd, ymax = PL_mean + PL_sd)),
    width = 0.2) +
  ylab("Blütenblattlänge (in cm)") +
  xlab("Schwertlilienart (Gattung Iris)") +
  theme_bw()

Übungsaufgabe

Lineare Regression zum Fütterungsversuch beim Kabeljau | 1

Von Calc zu R wechseln

Beispiel der Übungsaufgabe in Woche 3

Lineare Regression zum Fütterungsversuch beim Kabeljau | 2

Ein unvollständiges R Skript

(Beim folgenden Code-Fenster sind oben rechts 2 Buttons versteckt: Fullscreen und In die Zwischenablage kopieren
\(\rightarrow\) einfach mit der Maus rüber hovern und Button wählen.)

# AUFGABE: Fuellen Sie die Luecken '...' und fuehren Sie den Code in R aus.
# Bitte vorab pruefen ob das readODS bzw. readxl Paket installiert werden muss!

# ------------------------------ Vorbereitung ----------------------------------

#### Laden von Paketen
...(tidyverse)


#### Eigene Funktionen


# -------------------- Import und Datenaufbereitung ----------------------------

#### Import von Calc- und Excel-Dateien (ODS- und XLSX-Format)

# Import einer ODS-Datei mit dem 'readODS' Paket
kabeljau <- readODS::read_ods("DS1_W03_Streudiagramm_Kabeljau.ods",
  sheet = "Daten_Visualisierung")
# Struktur anzeigen lassen
...(kabeljau)

# Import einer XLSX-Datei mit z.B. dem 'readxl' Paket
kabeljau2 <- readxl::read_excel("DS1_W03_Streudiagramm_Kabeljau.xlsx",
  sheet = "Daten_Visualisierung")
# Struktur anzeigen lassen
...(kabeljau2)


#### Datensichtung und -transformation

# Anpassen der Spaltennamen
...(kabeljau) <- c("verzehr", "wachstum")
...(kabeljau) # Struktur nochmal pruefen

# Wertebereich pruefen mit der 'Zusammenfassung'-Funktion
...(kabeljau)


# ---------------------- 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... # richtige Indexierung für die Spalte 'verzehr'
y <- kabeljau... # richtige Indexierung für die Spalte 'wachstum'

# Steigungsparameter b berechnen
b <- ...(x = x, y = y)/ ...(x) # der shortcut mit der Kovarianz und Varianz
b

# Achsenabschnitt a berechnen
a <- ...(y) - b*...(x)
a

# Das Bestimmtheitsmass R^2 berechnen
y_obs <- ...   # die vorhergesagten Werte
ss_gesamt <- ...( (y - ...(y))^2 ) # Summenquadrate Gesamt
ss_regression <- ...( (y_obs - ...(y))^2 ) # Summenquadrate der Regression
R2 <- round(.../..., 4) # was wird durch was geteilt?
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 einfuegen
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 hinzufuegen
  geom_abline(slope = b, intercept = a) +
  # Achsenbeschriftung anpassen und Titel hinzufuegen
  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_classic()

Zu bearbeitende Swirl-Lektionen

Kurs DS1-01-R Grundlagen

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

Kurs DS1-02-Datenexploration mit R

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

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
Basic R functions (auf Moodle).

Überblick aller Objektindexierungen

Siehe auch DSB cheatsheet
Basic R functions (auf Moodle).

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 is lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.