Grundlagen in R:
Variablen und Vektoren

Data Science 1 - Programmieren & Visualisieren

Saskia Otto

Universität Hamburg, IMF

Wintersemester 2023/2024

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

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

Deskriptive Statistik mit iris | 3

Das Skript enthält

  • viele Kommentare zur Nachvollziehbarkeit und Skriptstrukturierung
  • viele Variablen bzw. Objekte
  • viele Operatoren
  • viele built-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 <-:
Speichern von Variablen verschiedenen Datentyps
neun <- 9
dezimalzahl <- 1.75
zeichen <- "a"
zeichenkette <- "Hallo Welt"
logisch <- TRUE

Variablen | Zugriff

Über den Namen kann auf den Inhalt zugegriffen werden:

  • es kann der Inhalt in der Konsole nur angezeigt werden
  • oder es können weitere Operationen erfolgen, die sich auch wieder abspeichern lassen.
Inhalt anzeigen
dezimalzahl
[1] 1.75
zeichenkette
[1] "Hallo Welt"
logisch
[1] TRUE
Berechnungen
drei <- sqrt(neun)
drei
[1] 3
neun * drei + dezimalzahl
[1] 28.75

Variablen | Die globale Umgebung

  • Variablen, Objekte und Funktionen, die Sie in R generieren, erscheinen im Environment Reiter unter Global Environment.
  • Die globale Umgebung ist der erste Ort des Suchverzeichnisses von R und stellt Ihren aktuellen Arbeitsbereich dar.
  • Dieser Arbeitsbereich wird mit jedem Schließen von R/RStudio gelöscht (es sei denn Sie verwenden ein RStudio Projekt und speichern es explizit).

Variablen | Entfernen

Einzelne Variablen, Objekte und Funktionen lassen sich aus dem Arbeitsbereich mit rm() und dem entsprechenden Namen löschen:

rm(logisch2)

Sie können die Liste aller Objekte des Arbeitsbereichs auch in der Konsole anzeigen lassen mit ls():

ls()
[1] "dezimalzahl"     "drei"            "has_annotations" "logisch"        
[5] "neun"            "zeichen"         "zeichenkette"   

→ Wie Sie sehen, ist logisch2 nicht mehr gelistet, nachdem es gelöscht wurde.

Variablen | Elementare Datentypen in R

Das Datum (date) und Faktoren (factor) stellen zusammengesetzte Datentypen dar.

Datentyp Definition Variablentyp Skalenniveau
logical Logische (Boolean) Werte (TRUE oder FALSE) kategorial nominalskaliert
integer Natürliche ganze Zahlen quantitativ (diskret) ordinal-/intervall-/verhältnisskaliert
double Gleitkommazahl quantitativ (kontinuierlich) intervall-/verhältnisskaliert
numeric Alle Zahlen (integer und double) quantitativ
complex Komplexe Zahlen (z.B. 5i) quantitativ
character Zeichen (oder Zeichenkette) qualitativ/kategorial nominalskaliert
NULL leerer Inhalt

Den Datentyp ermitteln | typeof()

Explizite Deklaration
my_double <- 42.5
my_integer <- 5
# Explizite Definition 
# von Typ 'integer': 
my_integer_correct <- 5L

my_logical <- TRUE
my_char <- "some text"
# Zeichenketten in 
# Anführungszeichen 
# setzen!
Datentypabfrage
typeof(my_double)
[1] "double"
typeof(my_integer)
[1] "double"
typeof(my_integer_correct)
[1] "integer"

Datentypen gezielt abfragen | is.xxx()

Diese Funktionen geben ein TRUE oder FALSE zurück:

Function lgl int dbl num chr
is.logical() x
is.integer() x
is.double() x
is.numeric() x x x
is.character() x
Beispiel
int_var <- 10L
is.integer(int_var)
[1] TRUE
dbl_var <- 4.5
is.double(dbl_var)
[1] TRUE

Datentypen umwandeln | as.xxx()

  • Der Datentyp lässt sich ineinander umwandeln, allerdings nicht in jede Richtung.
  • Vom spezifischeren in den allgemeineren Datentyp funktioniert immer und ohne Datenverlust: logical > integer > double > character
Positivbeispiel
as.integer(TRUE)
[1] 1
as.logical(as.integer(TRUE))
[1] TRUE
as.character(2.5)
[1] "2.5"
as.double(as.character(2.5))
[1] 2.5
Negativbeispiel
as.logical(100L)
[1] TRUE
as.integer(as.logical(100L))
[1] 1
as.integer(1.78965)
[1] 1
as.double(as.integer(1.78965))
[1] 1
# as.double("a") # gibt Fehlermeldung

Your turn …

01:30

Quiz 1 | Zuweisungen

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:

name <- 'John Doe'

Quiz 2 | Zuweisungen

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:

x <- 50

Quiz 3 | Datentypen

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?

my_value <- 'A1'
is.character(my_value)
[1] TRUE

Die einfachste Struktur: Vektoren

Vektoren erstellen | 1

..werden mit 'c()' generiert ('combine')
dbl_var <- c(1, 2.5, 4.5)
log_var <- c(TRUE, FALSE, TRUE, FALSE)
chr_var <- c("these are", "some strings")
..oder 'rep()' ('repeat')
rep("a", times = 5)
[1] "a" "a" "a" "a" "a"

Vektoren erstellen | 2

..oder mit 'seq()' ('sequence')
seq(from = 0, to = 1, by = 0.2)
[1] 0.0 0.2 0.4 0.6 0.8 1.0
# wenn 'by = 1' ist, nutze Kurzform:
1:10
 [1]  1  2  3  4  5  6  7  8  9 10
..oder  mit 'vector()'
vector(mode = "logical", length = 4)
[1] FALSE FALSE FALSE FALSE

Für Schleifen wichtig!

Struktur von Vektoren | 1

  • sind immer flach, auch wenn man c() verschachtelt:
c(1, 2, 5:10, rep(15,4), c(20,21))
 [1]  1  2  5  6  7  8  9 10 15 15 15 15 20 21
  • ist das gleiche wie:
c(1, 2, 5, 6, 7, 8, 9, 10, 15, 15, 15, 15, 20, 21)
 [1]  1  2  5  6  7  8  9 10 15 15 15 15 20 21

Struktur von Vektoren | 2

  • haben eine bestimmte Länge und Struktur die mit length() und str() ermittelt werden kann:
x <- c(200, 50, 40, 1, 100, 20)
length(x)
[1] 6
str(x)
 num [1:6] 200 50 40 1 100 20

Your turn …

01:00

Quiz 4 | Vektoren erstellen

Quiz 5 | Vektoren erstellen

Bei Zahlenfolgen mit einer Zahlenerhöhung von 1 kann die Shortcut Variante für seq() verwendet werden: :

6:10
[1]  6  7  8  9 10

Vektorregeln

Arbeiten mit Vektoren

4 wichtige Regeln

  1. Implizierte Datentyp-Umwandlung (‘coercion’)

  2. Handling von Vektoren unterschiedlicher Länge (‘recycling’)

  3. Namen für Elemente in Vektoren

  4. Extrahieren von Elementen bzw. Teilmengen bilden (Indexierung oder ‘indexing’)

1. ‘Coercion’ | 1

  • Alle Elemente eines Vektors müssen den gleichen Datentypen haben.
  • Unterschiedliche Typen werden zwangsumgewandelt (‘coerced’) und zwar zum flexibleren Typen (‘logical’ → ‘integer’ → ‘double’ → ‘character’)
Beispiel: 'character' und 'integer' wird zu 'character'
str(c("a", 1))
 chr [1:2] "a" "1"

1. ‘Coercion’ | 2

Nutzen beim Rechnen

  • Wenn logische Elemente zu ‘integer’ oder ‘double’ umgewandelt werden, wird jedes TRUE zu einer 1 und FALSE wird zu 0.
  • Dies kann bei Berechnungen mit sum() und mean() sehr nützlich sein:
x <- c(FALSE, FALSE, TRUE)
as.numeric(x)
[1] 0 0 1
sum(x) # Summe aller TRUEs
[1] 1

2. Recycling-Regel

  • Implizierte Verlängerung von Vektoren bei Operationen mit 2 Vektoren durch:
    • der kürzere Vektor wird auf die gleiche Länge des längeren Vektors verlängert, indem die Lücke mit den bereits vorhandenen Elementen gefüllt wird.
1:10 + 100
 [1] 101 102 103 104 105 106 107 108 109 110
# Was passiert hier?
1:10 + 1:3
 [1]  2  4  6  5  7  9  8 10 12 11

3. Vektorelemente benennen

Alle Elemente in Objekten können Namen erhalten - auch in Vektoren:

  • Entweder beim Erstellen mit der Funktion c()
x <- c(a = 1, b = 2, c = 4)
x
a b c 
1 2 4 
  • oder anschließend mit der Funktion names().
y <- c(1,5,3)
names(y) <- c("a", "b", "c")
y
a b c 
1 5 3 

4. Indexierung (‘indexing’) | 1

  • [...] ist die Funktion mit der Vektoren indexiert werden.
  • Die entstandene Teilmenge lässt sich dann als neuer Vektor abspeichern:
    neuer_vektor <- alter_vektor[auswahl].
  • Wenn >1 Element ausgewählt/ausgeschlossen werden, müssen diese als Vektor übergeben werden!

3 Arten einen Vektor zu indexieren:

  1. Über die Angabe der Position der auszuwählenden (oder auszuschließenden!) Elemente.
  2. Über die Namen der auszuwählenden (oder auszuschließenden!) Elemente
  3. Mittels logischem Vektor.

4. Indexierung (‘indexing’) | 2

Ausschluss von Elementen

  • Ein negatives Vorzeichen definiert alle auszuschließenden Elemente (bei Positionsindexierung).
  • Der Nicht-Operator ! wählt genau das Gegenteil von dem was angegeben ist (bei logischer Indexierung).

4. Indexierung | Über die Position 1

Die Positionsangabe erfolgt über eine Ganzzahl oder einen numerischen Vektor mit Ganzzahlen. Der Index startet immer mit 1.

x <- c("eins", "zwei", "drei", "vier", "fünf")
Index bestehend aus einer Zahl
x[2] # Auswahl des. 2. Elements
[1] "zwei"
x[-2] # Alle Element AUSSER das Zweite
[1] "eins" "drei" "vier" "fünf"
Zahlenvektor als Index
x[c(5, 1, 3)] # Auswahl >1 Elemente mittels Vektor
[1] "fünf" "eins" "drei"
x[-c(5, 1, 3)] # Alle Elemente AUSSER das 5., 1. und 3.
[1] "zwei" "vier"
x[1:3] # Zusammenhängende Elemente
[1] "eins" "zwei" "drei"
x[3:1] # Reihenfolge drehen
[1] "drei" "zwei" "eins"
Sich wiederholende Zahlen verlängern den Vektor
x[c(1,1,2,2,3,3,3,3)]
[1] "eins" "eins" "zwei" "zwei" "drei" "drei" "drei" "drei"
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 x
x[x %% 2 == 0]
[1]  6  0 12
'Fremdabfrage'
# Abfrage bezogen auf anderen Vektor:
y <- 1:10
x[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
[1] 10  3  5  8  1

Your turn …

01:30

Quiz 6 | ‘Coercion’-Regel

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.

Quiz 7 | Recycling-Regel

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)

Quiz 8 | Indexierung

Ein Vektor x enthält 20 verschiedene Elemente.

x <- 1:20
sum(x[3:12])
[1] 75

Operatoren

Nützliche Operatoren für Abfragen

Vergleichs- und Verknüpfungsoperatoren geben immer einen logischen Wert (TRUE oder FALSE) zurück.

Vergleichsoperatoren

Im Englischen ‘relational operators’

Operator Anwendung Beschreibung
< a < b a ist KLEINER als b
> a > b a ist GRÖSSER als b
== a == b a ist GLEICH wie b
<= a <= b a ist KLEINER als oder GLEICH wie b
>= a >= b a ist GRÖSSER als oder GLEICH wie b
!= a!=b a ist NICHT GLEICH wie b

Vergleichsoperatoren | Beispiele

# Beispiele für Zahlen
a <- 10
b <- 5
a < b # a ist kleiner als b
a >= b # a ist grösser oder gleich b
a != b # a ist nicht gleich b
[1] FALSE
[1] TRUE
[1] TRUE

Verknüpfungsoperatoren

Im Englischen ‘logical operators’

Operator Anwendung Beschreibung
& a & b Elementweise UND Operation (arbeiten mit Vektoren)
| a | b Elementweise ODER Operation (arbeiten mit Vektoren)
! !a Elementweise NICHT Operation (arbeiten mit Vektoren)

Verknüpfungsoperatoren | 2

‘Regenschirm-Logik’

Verknüpfungsoperatoren | 3

Beispiel 1 zu kombinierten logischen Abfragen

Beide Abfragen sind wahr
a <- 20
b <- 5
a > b & a <= 100
[1] TRUE
Schritt Operation Ergebnis
1 a > b TRUE
2 a <= 100 TRUE
3 TRUE & TRUE TRUE

Verknüpfungsoperatoren | 4

Beispiel 2 zu kombinierten logischen Abfragen

Nicht alle Abfragen sind wahr
a <- 20
b <- 5
a > b & a <= 10
[1] FALSE
Schritt Operation Ergebnis
1 a > b TRUE
2 a <= 10 FALSE
3 TRUE & FALSE FALSE

Vektorisierte Operationen in R

Einfache Berechnungen

a <- c(2, 4, 6, 8)
c <- (a + sqrt(a))/(exp(2)+1)
c
[1] 0.4069842 0.7152175 1.0072039 1.2907802

Warum 4 Werte???

Vektorisierte Berechnungen

Berechnungen in R sind vektorisiert, d.h. die Berechnung wird auf jedes einzelne Element des Vektors angewendet.

a <- 1:4
b <- 10
Raten Sie den Output
a + b 
a * b 
Lösung
a + b 
[1] 11 12 13 14
# = a[1] + b[1], a[2] + b["2"], a[3] + b["3"], a[4] + b["4"]

a * b # = a[1] * b[1], ...
[1] 10 20 30 40

Calc vs. R | Bsp. proportionaler Anteil 1

Spinnendichte im Golf von Kalifornien

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)}\)

In Calc gäbe es 2 Ansätze

Calc vs. R | Bsp. proportionaler Anteil 3

Berechnung in R

dichte <- c(26.1, 35.4, 75.9, 73.2, 107.9, 25.2, 
  75.8, 102, 10.7, 38.2, 75.3, 9.4, 7.3, 10.5, 
  20.3, 20.7, 21.7, 2.2, 4.4, 1.22)
summe <- sum(dichte)  
summe
[1] 743.42

Calc vs. R | Bsp. proportionaler Anteil 4

Berechnung in R

proportion <- dichte / summe 
proportion
 [1] 0.035108014 0.047617767 0.102095720 0.098463856 0.145140029 0.033897393
 [7] 0.101961206 0.137203734 0.014392941 0.051384144 0.101288639 0.012644266
[13] 0.009819483 0.014123914 0.027306233 0.027844287 0.029189422 0.002959296
[19] 0.005918592 0.001641064

Übungsaufgabe

Zu bearbeitende Swirl-Lektionen

Kurs DS1-01-R Grundlagen

  • L08-Atomare Vektoren als einfachster Objekttyp
  • L09-Zahlenfolgen
  • L10-Verhalten von Vektoren
  • L11-Vektorindexierung
  • L12-Filtern von Vektoren

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.

Total gelangweilt?

Dann testen Sie doch Ihr Wissen in folgendem Abschlussquiz…

Abschlussquiz

1 | Zuweisungen

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.

a <- 20
n <- 4
y <- n * a + 110

2 | ‘Coercion’-Regel

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.

3 | ‘Coercion’-Regel

In diesem Fall ist 1 klar als ‘integer’ definiert, daher wird das TRUE zum ‘integer’ umgewandelt.

4 | ‘Coercion’-Regel

Alle TRUEs werden zu 1 umgewandelt und alle FALSEs zu 0. Summiere einfach den Vektor mit der sum() Funktion: sum(x)

5 - Challenge

Wie könnten alle NAs in einem Vektor x mit sehr vielen Elementen schnell ermittelt 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)
 [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE
[13]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
sum(is.na(x))
[1] 5

6 | Indexierung

Ein Vektor x enthält 20 verschiedene Elemente.

x <- 1:20
x[5]
[1] 5

7 | Indexierung

Ein Vektor x enthält 20 verschiedene Elemente.

x <- 1:20
sum(x[-c(2,18)])
[1] 190

8 | Indexierung

Ein Vektor vec enthält mehrere Zahlen.

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!

# Demo des Modulo-Operators bei 43/5
43 %% 5
[1] 3
# Quizfrage
vec <- 1:15
vec[vec %% 2 == 0]
[1]  2  4  6  8 10 12 14

9 | Indexierung

Ein Vektor vec enthält mehrere Zahlen.

vec <- 1:15
vec[vec %% 2 == 1]
[1]  1  3  5  7  9 11 13 15

10 | Indexierung

Ein numerischer Vektor nvec enthält eine unbekannte Anzahl an Elementen.

nvec <- 1:25
nvec[(length(nvec)-9):length(nvec)]
 [1] 16 17 18 19 20 21 22 23 24 25

Abschlussquiz 11 | Indexierung

Der Vektor wird tatsächlich recycled, aber die Lücke wird mit NAs aufgefüllt.

12 | Vektorisierte Berechnung

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.

13 | Vektorisierte Berechnung

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.

x <- c(26, 35, 76, 73, 108, 25, 76, 102, 11)
mean_x <- mean(x)
df <- length(x) - 1
var_x <- sum( (x-mean_x)^2 ) / df
var_x
[1] 1268.611
# Oder die Verwendung der built-in Funktion var()
var(x)
[1] 1268.611

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.