einen ersten Eindruck für eine deskriptive statistische Analyse in R bekommen haben.
das erste der 4 Grundelemente (Variablen) in R kennen und beherrschen.
Datentypen abfragen und umwandeln können.
Vektoren und Zahlenfolgen in R erstellen können.
Vektoren indexieren und mittels Operatoren filtern können.
den Unterschied zwischen Zuweisungs- Vergleichs- und Verknüpfungsoperatoren kennen.
Deskriptive Statistik mit iris | 1
Von Calc zu R wechseln
Beispiel der Übungsaufgaben in Wochen 1-3
Deskriptive Statistik mit iris | 2
Das vollständige 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.)
# ------------------------------ Vorbereitung ----------------------------------#### Laden von Paketenlibrary(tidyverse) # laedt 9 Pakete#### Eigene Funktionen# Variantionskoeffizientcv <-function(x) {sd(x)/mean(x)}# -------------------- Import und Datenaufbereitung ----------------------------#### Import von CSV-Dateien# Import des weiten (falsch strukturierten) Datensatzes --> KLAPPT NICHTiris <-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 --> KLAPPTiris <-read.csv("iris_transponiert.csv")#### Datensichtungiris# 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 absteigendarrange(iris, Species, desc(Sepal.Length))# ------------ Alternative Variante (ohne Vorbehandlung in Calc) ---------------# --> weiten Datensatz mit Funktion aus 'readr' Paket einlesen und anpassen#### Importiris2 <-read_delim("iris.csv", delim =";", col_names =FALSE)iris2class(iris2) # ein tibble#### Datenaufbereitungiris2 <-t(iris2)class(iris2)iris2_names <- iris2[1, ]iris2 <- iris2[-1, ]iris2colnames(iris2) <- iris2_namesrownames(iris2) <-NULLiris2 <- iris2 |>as.data.frame() |>mutate(across(Sepal.Length:Petal.Width, as.double))# Pruefen ob die Umwandlung richtig isthead(iris2)str(iris2)# ------------------- Numerische deskriptive Statistik -------------------------#### Berechnung verschiedener Statistiken pro Variable (hier Kronblattlaenge)# Lageparametermean(iris$Petal.Length)median(iris$Petal.Length)# Streuungsparametermin(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 erstellenmeine_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 in1: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 genausoiris |>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 Standardabweichungiris_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 speichernmutate(Species =factor(paste0("Iris ", Species))) |># nun die Reihenfolge der Faktorstufen nach PL_mean sortierenmutate(Species =fct_reorder(.f = Species, .x = PL_mean, .desc =TRUE))# Datensatz pruefeniris_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()
Deskriptive Statistik mit iris | 3
Das Skript enthält
viele Kommentare zur Nachvollziehbarkeit und Skriptstrukturierung
viele Variablen bzw. Objekte
viele Operatoren
vielebuilt-in Funktionen aus base R und tidyverse Paketen
mit entsprechenden Datenverweisen (analog zu Zellverweisen in Calc und Excel)
die Definition einer eigenen Funktion
eine Schleife
Grundelement - Variablen
Variablen
Zur Erinnerung
Eine Variable ist eine Möglichkeit, um im Programm eine Zahl, ein Zeichen oder Zeichenkette oder einen boolschen Wert (wahr oder falsch) zu speichern.
Variablen | Zuweisung
In R betrachtet man einzelne Werte oft als Skalare oder Vektoren mit einem Element.
Werte werden gespeichert, indem man sie einem Variablen- bzw. Skalarnamen zuweist - und zwar mit dem Zuweisungsoperator<-:
Das Gleichheitszeichen wäre theoretisch auch möglich, aber dies sollte nur innerhalb von Funktionsaufrufen bei der Argumentzuweisung genutzt werden! Die richtige Anweisung lautet daher:
Wenn der nach links zeigende Zuweisungsoperator verwendet wird (Standard!), muss der Skalar- oder Objektname links stehen. Ihm wird der Inhalt auf der rechten Seite zugewiesen. Die richtige Anweisung lautet daher:
Bevor auf my_value in Zeile 2 zugegriffen werden kann, muss das Skalar erstmal definiert werden. Dies geschieht mit dem Zuweisungsoperator (<-).
Anschl. muss eine Funktion aufgerufen werden, die einen logischen Wert zurückgibt. Dies kann nur eine der is.xxx Funktionen sein. Welchen Datentyp könnte ‘A1’ haben?
Auswahl von Positionen, die es nicht gibt, werden mit NA gefüllt:
x[c(1, 6, 10)]
[1] "eins" NA NA
4. Indexierung | Über die Position 2
Calc vs. R
4. Indexierung | Mittels logischem Vektor
Hier erfolgt die Auswahl über eine logische Abfrage (Vektor[Abfrage]) mittels Vergleichs- und Verknüpfungsoperatoren oder Funktionen, die auch TRUE/FALSE zurückgeben:
'Eigenabfrage'
x <-c(17,6,1,0,23,31,12)# Alle Elemente in x, deren Werte > 15:x[x >15]
[1] 17 23 31
# Alle geraden Werte von xx[x %%2==0]
[1] 6 0 12
'Fremdabfrage'
# Abfrage bezogen auf anderen Vektor:y <-1:10x[y <=5]
[1] 17 6 1 0 23
Die logische Indexierung ist das, was man typischerweise als filtern bezeichnet.
Logische Indexierung für NA Handling
Fehlende Werte werden durch NA angezeigt (= ‘not available’).
NA nimmt immer den Datentyp der anderen Elemente an, auch wenn das meist nicht sichtbar ist.
Mit is.na() kann geprüft werden, ob ein Element ein NA, um sich anschl. die Summe aller NAs ausgeben zu lassen.
Anzahl an NAs ermitteln
x <-c(10, 3, NA, 5, 8, 1, NA)is.na(x)
[1] FALSE FALSE TRUE FALSE FALSE FALSE TRUE
sum(is.na(x))
[1] 2
Auschluss aller NAs
x[!is.na(x)] # Alle Elemente, wo die Abfrage 'is.na(z)' NICHT TRUE ergibt
Die unendliche Menge an Zahlen kann nicht einfach in zwei Zustände umgewandelt werden, während TRUE oder FALSE recht einfach in die Zahlen 1 und 0 umgewandelt werden können. Da hier die Zahl 1 nicht explizit als ‘integer’ deklariert ist (mit 1L), wird TRUE zum Typ ‘double’ umgewandelt.
R füllt die Lücke der kürzeren Vektoren mit den existierenden Elementen auf: Position 4 in a erhält das 1. Element, die Position 5 das 2. Element. Und die Zahl 3 wird auch auf die Länge von b verlängert in dem sie 5 mal wiederholt wird: c(10,5,100,10,5)\*c(1,2,3,4,5)\*c(3,3,3,3,3)
Gegeben ist eine Messreihe der Spinnendichte (\(no./m^2\)) auf verschiedenen Inseln im Golf von Kalifornien aus dem Jahre 1992 (aus Studie von Polis et al., 1998).
Calc vs. R | Bsp. proportionaler Anteil 2
Nun soll der proportionale Anteil der Dichte pro Insel berechnet werden: \(p_i=\frac{d_i}{\sum(d_i)}\)
Der Skalar n in der letzten Operation wurde vorher nicht definiert. Daher muss sich die vorherige Zuweisung auf dieses Skalar beziehen. Auch y wurde vorher nicht definiert, daher kann es sich beim ‘Grösser’-Zeichen in in der letzten Zeile nicht um einen Vergleichsoperator handeln, sondern muss der erste Teil des Zuweisungsoperators sein.
Eine Zeichenkette (in diesem Fall ‘a’) hat keine korrespondierende Zahl, in die es umgewandelt werden kann. Dagegen kann eine Zahl einfach in eine Zeichenkette umgewandelt werden.
Zuerst wird mit der is.na() Funktion bei jedem Element abgefragt, ob es sich um ein NA handelt oder nicht.
Anschließend kann mit dem zurückgegebenen logischen Vektor die Summe aller TRUEs berechnet werden - denn R wandelt bei mathematischen Operationen von logischen Werten alle FALSEs in eine 0 um und alle TRUEs in eine 1!
x <-c(3,0,1,8,0,NA,8,0,4,NA,5,1,NA,7,7,9,2,1,NA,5,1,NA,0)is.na(x)
Wir nutzen dazu den Modulo-Operator, welcher eine Restwert-Division zweier Elemente ausführt. Bei der Restwert-Division von 43 (Dividend) durch 5 (Divisor) wird z.B. gefragt, wie man die Zahl 43 als Vielfaches von 5 und einem kleinen Rest darstellen kann: \(43=5*c+r\) In diesem Beispiel wäre die 4 der sog. Ganzzahlquotient c und die 3 der Restwert r.
Ein Rest ungleich 0 ergibt sich folglich genau dann, wenn der Dividend kein Vielfaches des Divisors ist. Man sagt auch: Der Dividend ist nicht durch den Divisor teilbar, weshalb ein Rest übrigbleibt.
Dies können wir uns zunutze machen, indem wir als Divisor die 2 nehmen. Wenn kein Restbetrag übrig bleibt, muss der Dividend gerade sein!
Der kürzere Vektor 1:3 wird durch das recyceln der eigenen Werte auf die gleiche Länge wie der erste Vektor gebracht (=6): c(1,2,3,1,2,3). Nun wird das 5. Element (=2) mit dem 5.Element des 1. Vektors (=10) multipliziert.
Zur Erinnerung die Formel der Varianz: \(s^{2} = \frac{\sum\limits_{i=1}^{n} \left(x_{i} - \bar{x}\right)^{2}} {n-1}\)
df im Quiz steht für ‘degrees of freedom’, was im Deutschen die Freiheitsgrade sind. Und die betragen bei der Varianz n-1 (die Stichprobengröße oder Länge des Vektors minus 1).
Bei der Teilanweisung x-mean_x wird der eine Wert in mean_x auf die Länge von x recycelt. Anschl. wird der 1. Wert in mean_x vom 1. Wert in x, abgezogen, dann der zweite Wert, etc.
Das Ergebnis ist ein Vektor der gleichen Länge wie x mit den Differenzen, die anschl. quadriert und aufsummiert werden.