Grundlagen in R:
Variablen und Vektoren

Data Science 1 - Programmieren & Visualisieren

Saskia Otto & Monika Eberhard

Universität Hamburg, IMF

Wintersemester

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

  • das erste der 4 Grundelemente (Variablen - in R Objekte genannt) 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.
  • mit fehlenden Werten (NA) umgehen können.

Grundelement - Variablen

Variablen

Zur Erinnerung

Eine Variable ist eine Möglichkeit, um im Programm eine Zahl, ein Zeichen oder eine Zeichenkette oder einen booleschen Wert (wahr oder falsch) zu speichern.

Begriffe in R

  • In R nennt man alles, was unter einem Namen gespeichert wird, ein Objekt - egal ob Einzelwert, Zahlenreihe oder ganze Tabelle.
  • Den Begriff Variable verwenden wir für die Spalten einer Tabelle, also die Messgrößen (z.B. Länge, Gewicht, Art) - so wie in der Statistik.

Objekte | Zuweisung

Objekte werden gespeichert, indem man sie einem Namen zuweist - und zwar mit dem Zuweisungsoperator <-:

Speichern von Objekten verschiedenen Datentyps
neun <- 9
dezimalzahl <- 1.75
zeichen <- "a"
zeichenkette <- "Hallo Welt"
logisch <- TRUE
logisch2 <- FALSE

Hier wird jeweils nur ein einzelner Wert gespeichert. Auch so ein Objekt nennt man in R bereits einen Vektor (mit einem Element) – dazu gleich mehr!

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

Objekte | Die globale Umgebung

  • Alle Objekte und eigenen Funktionen, die Sie in R erzeugen, erscheinen im Environment Reiter unter Global Environment.
  • Die globale Umgebung stellt Ihren aktuellen Arbeitsbereich dar.
  • Empfehlung: Speichern Sie den Arbeitsbereich nie ab (Tools → Global Options → General → Save workspace to .RData on exit: Never).
  • Alles, was Sie brauchen, sollte sich jederzeit aus Ihrem Skript neu erzeugen lassen - das Skript ist das eigentliche Ergebnis Ihrer Arbeit, nicht der Arbeitsbereich.

Objekte | Entfernen

Einzelne Objekte lassen sich mit rm() aus dem Arbeitsbereich löschen, ls() listet alle Objekte auf:

ls()
[1] "dezimalzahl"  "drei"         "logisch"      "logisch2"     "neun"        
[6] "timer"        "zeichen"      "zeichenkette"
rm(zeichen)
ls()
[1] "dezimalzahl"  "drei"         "logisch"      "logisch2"     "neun"        
[6] "timer"        "zeichenkette"

→ zeichen ist nicht mehr gelistet.

Elementare Datentypen in R

Datentyp Definition Variablentyp Skalenniveau
logical Logische (Boolean) Werte (TRUE oder FALSE) kategorial nominalskaliert
integer Ganze Zahlen (z.B. Anzahlen) quantitativ (diskret) intervall-/verhältnisskaliert
double Gleitkommazahlen (Dezimalzahlen) quantitativ (kontinuierlich) intervall-/verhältnisskaliert
character Zeichen (oder Zeichenkette) qualitativ/kategorial nominalskaliert


  • integer und double werden zusammen als numeric bezeichnet. In der Praxis müssen Sie die beiden selten unterscheiden - R speichert Zahlen standardmäßig als ‘double’.
  • Das Datum (date) und Faktoren (factor) sind zusammengesetzte Datentypen, die wir später kennenlernen.

Den Datentyp ermitteln | typeof()

Variablen anlegen
my_logical <- TRUE

my_double <- 42.5
my_number <- 5
my_integer <- 5L # Zusatz 'L'

my_char <- "some text"
# Zeichenketten in Anführungszeichen!
Datentypabfrage
typeof(my_logical)
[1] "logical"
typeof(my_double)
[1] "double"
typeof(my_number) # auch ganze Zahlen sind 'double'!
[1] "double"
typeof(my_integer)
[1] "integer"
typeof(my_char)
[1] "character"

Datentypen gezielt abfragen | is.xxx()

Diese Funktionen geben ein TRUE oder FALSE zurück:

Funktion TRUE bei …
is.logical() logischen Werten
is.numeric() Zahlen (‘integer’/‘double’)
is.character() Zeichen(ketten)
is.na() fehlenden Werten (NA)
Beispiel
num_var <- 4.5
is.numeric(num_var)
[1] TRUE
is.character(num_var)
[1] FALSE

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

Your turn …

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 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 Objekt erst angelegt werden. Dies geschieht mit dem Zuweisungsoperator (<-).

Anschließend 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

  • Bisher haben wir immer nur einen einzelnen Wert unter einem Namen gespeichert.
  • Möchte man mehrere Werte (= Elemente) zusammen speichern, z.B. eine Messreihe, fasst man sie mit der Funktion c() zu einem Vektor zusammen. Die Elemente werden durch Kommas getrennt.
..werden mit 'c()' generiert ('combine')
laenge <- c(12.5, 14.1, 13.8)
gefangen <- c(TRUE, FALSE, TRUE, FALSE)
art <- c("Hering", "Kabeljau")
..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
..oder 'rep()' ('repeat')
rep("a", times = 5)
[1] "a" "a" "a" "a" "a"
wenn 'by=1' ist, nutze die Kurzform ':'
1:10
 [1]  1  2  3  4  5  6  7  8  9 10

Struktur von Vektoren | 1

  • Vektoren sind immer flach, auch wenn man c() verschachtelt:
Verschachtelte Vektoren mit c() kombinieren
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:
Alle Elemente einzeln aufgeführt
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

  • Vektoren haben eine bestimmte Länge und Struktur, die mit length() und str() ermittelt werden können:
Anzahl der Elemente und Struktur abfragen
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 …

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. Implizite Datentyp-Umwandlung (‘coercion’)

  2. Rechnen mit Einzelwerten und Vektoren (‘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 'double' wird zu 'character'
str(c("a", 1))
 chr [1:2] "a" "1"

1. ‘Coercion’ | 2

Warum das in echten Daten wichtig ist

  • Ein einziger nicht-numerischer Eintrag (z.B. “k.A.” oder “<0.1”) macht aus einer ganzen Messreihe einen ‘character’-Vektor - Rechnen ist dann nicht mehr möglich.
  • Das ist einer der häufigsten Fehler beim Einlesen von Tabellen!
Gewichte aus einer Tabelle
gewicht <- c(12.5, 13.1, "k.A.", 11.8)
str(gewicht)
 chr [1:4] "12.5" "13.1" "k.A." "11.8"
Umwandeln in Zahlen
as.numeric(gewicht)
Warning: NAs introduced by coercion
[1] 12.5 13.1   NA 11.8

Achtung

→ Was sich nicht umwandeln lässt, wird zu NA - und R gibt eine Warnung aus. Warnungen also immer lesen!

1. ‘Coercion’ | 3

Nutzen beim Rechnen

  • Wenn logische Elemente zu Zahlen umgewandelt werden, wird jedes TRUE zu einer 1 und FALSE zu 0.
  • Dies kann bei Berechnungen mit sum() und mean() sehr nützlich sein:
TRUE/FALSE zählen und Anteile berechnen
x <- c(FALSE, FALSE, TRUE)
as.numeric(x)
[1] 0 0 1
sum(x)  # Anzahl aller TRUEs
[1] 1
mean(x) # Anteil aller TRUEs
[1] 0.3333333

2. Recycling-Regel

  • Bei Operationen mit einem Vektor und einem Einzelwert wird der Einzelwert auf die Länge des Vektors verlängert (‘recycelt’):
Vektor + Einzelwert: 100 wird zu jedem Element addiert
1:10 + 100
 [1] 101 102 103 104 105 106 107 108 109 110

Achtung bei Vektoren unterschiedlicher Länge

R recycelt auch längere Vektoren - das ist aber fast immer ein Versehen. R warnt nur, wenn die längere Länge kein Vielfaches der kürzeren ist:

Vektor + kürzerer Vektor: 1:3 wird wiederholt
1:10 + 1:3
Warning in 1:10 + 1:3: longer object length is not a multiple of shorter object
length
 [1]  2  4  6  5  7  9  8 10 12 11

3. Vektorelemente benennen

  • Die Elemente eines Vektors können Namen erhalten – entweder beim Erstellen mit der Funktion c():
Namen beim Erstellen vergeben
x <- c(a = 1, b = 2, c = 4)
x
a b c 
1 2 4 
  • Mit names() lassen sich die Namen abfragen – und auch nachträglich vergeben:
Namen abfragen und zuweisen
names(x)
[1] "a" "b" "c"
y <- c(1, 5, 3)
names(y) <- c("a", "b", "c")
y
a b c 
1 5 3 

Dasselbe Prinzip begegnet Ihnen später wieder: names() zeigt z.B. auch die Spaltennamen einer Tabelle an.

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 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 Elemente AUSSER das 2.
[1] "eins" "drei" "vier" "fünf"
Zahlenvektor als Index
x[c(5, 1, 3)]  # Auswahl >1 Elemente
[1] "fünf" "eins" "drei"
x[-c(5, 1, 3)] # Alle AUSSER 5, 1 und 3
[1] "zwei" "vier"
x[1:3]  # Zusammenhängende Elemente
[1] "eins" "zwei" "drei"

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:7
x[y <= 3]
[1] 17  6  1

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 ist - und mit sum() lässt sich anschließend die Anzahl aller NAs ermitteln.
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
Ausschluss aller NAs
x[!is.na(x)]  # Alle Elemente, bei denen 'is.na(x)' NICHT TRUE ergibt
[1] 10  3  5  8  1

NAs beim Rechnen | na.rm = TRUE

  • Enthält ein Vektor ein einziges NA, ist auch das Ergebnis von sum(), mean(), max() etc. NA - denn der fehlende Wert könnte alles sein.
  • Mit dem Argument na.rm = TRUE (‘NA remove’) werden NAs bei der Berechnung ignoriert:
Ohne na.rm
x <- c(10, 3, NA, 5, 8, 1, NA)
mean(x)
[1] NA
Mit na.rm
mean(x, na.rm = TRUE)
[1] 5.4
sum(x, na.rm = TRUE)
[1] 27

Prüfen Sie trotzdem immer erst, wie viele NAs es gibt (sum(is.na(x))) - 2 fehlende von 100 Werten sind etwas anderes als 80 von 100!

Your turn …

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 die Zahl 1 standardmäßig als ‘double’ gespeichert wird, wird FALSE ebenfalls zum Typ ‘double’ umgewandelt.

Quiz 7 | NA-Handling

Ohne na.rm = TRUE würde mean(x) wegen des fehlenden Werts NA zurückgeben. Mit dem Argument wird das NA ignoriert und der Mittelwert aus den 3 vorhandenen Werten berechnet: (12 + 7 + 9) / 3.

x <- c(12, NA, 7, 9)
mean(x, na.rm = TRUE)
[1] 9.333333

Quiz 8 | Indexierung

Ein Vektor x enthält 20 verschiedene Elemente.

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
%in% a %in% b a ist ENTHALTEN IN b

Vergleichsoperatoren | Beispiele

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

Der %in%-Operator

  • Prüft für jedes Element des linken Vektors, ob es irgendwo im rechten Vektor vorkommt.
  • Ideal, um nach mehreren Kategorien zu filtern (statt vieler == mit | verknüpft):
Abfrage
arten <- c("Hering", "Kabeljau",
  "Sprotte", "Hering", "Scholle")

arten %in% c("Hering", "Sprotte")
[1]  TRUE FALSE  TRUE  TRUE FALSE
Filtern
arten[arten %in% c("Hering", "Sprotte")]
[1] "Hering"  "Sprotte" "Hering" 
# Gegenteil: alle ANDEREN Arten
arten[!arten %in% c("Hering", "Sprotte")]
[1] "Kabeljau" "Scholle" 

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 # = a[1] + b, a[2] + b, a[3] + b, a[4] + b
[1] 11 12 13 14
a * b # = a[1] * b, a[2] * b, ...
[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

Übungen

Zu bearbeitende swirl-Lektionen

Kurs DSB-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

Abschlussquiz

1 | Zuweisungen

Das Objekt n in der letzten Operation wurde vorher nicht definiert. Daher muss sich die vorherige Zuweisung auf dieses Objekt beziehen. Auch y wurde vorher nicht definiert, daher kann es sich beim ‘Kleiner’-Zeichen 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 sie umgewandelt werden kann. Dagegen kann eine Zahl einfach in eine Zeichenkette umgewandelt werden.

3 | ‘Coercion’ in echten Daten

‘<0.5’ ist keine Zahl und kann daher nicht umgewandelt werden - dieses Element wird zu NA, alle anderen werden korrekt umgewandelt. R gibt dabei eine Warnung aus (‘NAs introduced by coercion’). Solche Einträge (z.B. Werte unter der Nachweisgrenze) sind in Messdaten häufig und müssen bewusst behandelt werden.

temp <- c('12.1', '13.4', '<0.5', '11.9')
as.numeric(temp)
Warning: NAs introduced by coercion
[1] 12.1 13.4   NA 11.9

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

11 | Filtern mit %in%

%in% prüft für jedes Element in arten, ob es in c('Kabeljau', 'Scholle') enthalten ist, und gibt einen logischen Vektor zurück. Mit == würde R die beiden Vektoren dagegen elementweise (und mit Recycling!) vergleichen - das liefert hier ein falsches Ergebnis.

arten <- c('Hering', 'Kabeljau', 'Sprotte', 'Scholle', 'Hering')
arten %in% c('Kabeljau', 'Scholle')
[1] FALSE  TRUE FALSE  TRUE FALSE
arten[arten %in% c('Kabeljau', 'Scholle')]
[1] "Kabeljau" "Scholle" 
# Zum Vergleich - falsch:
arten[arten == c('Kabeljau', 'Scholle')]
Warning in arten == c("Kabeljau", "Scholle"): longer object length is not a
multiple of shorter object length
[1] "Scholle"

12 | 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. Anschließend wird der Wert in mean_x vom 1. Wert in x abgezogen, dann vom 2. Wert, etc.

Das Ergebnis ist ein Vektor der gleichen Länge wie x mit den Differenzen, die anschließend 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 ist lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.