StartR






“You shouldn’t feel ashamed about your code -
if it solves the problem, it’s perfect just the way it is.
But also, it could always be better.” Hadley Wickham

Erste Schritte in R

R ist eine freie Programmiersprache für statistische Anwendungen.

Diese Einführung in R ist interaktiv. Das bedeutet, dass Sie nach jedem Abschnitt Ihr neues Wissen in kleinen Übungen anwenden können. Diese Übungen sind direkt in die Seite eingebettet. Sie müssen zunächst nichts installieren und können R in Ihrem Browser lernen.

Am unteren Bildschirmrand finden Sie Schaltflächen mit der Aufschrift “Continue” oder “Next Topic”. Mit diesen Schaltflächen gelangen Sie jeweils zur nächsten Übung oder zum nächsten Abschnitt.

Auf der linken Seite sehen Sie ein Menü, über das Sie zu verschiedenen Themenbereichen navigieren können. Gehen Sie Schritt für Schritt vor. Benutzen Sie das Menü nur, um schnell zu vorherigen Themenbereichen zu gelangen.

Später werden wir uns anschauen, wie Sie R auf Ihrem Computer installieren können.

Bei Fragen, Anregungen oder technischen Problemen, wenden Sie sich bitte direkt an: fabian.class@uni-potsdam.de

Drücken Sie jetzt auf “Continue”.

So funktioniert’s:

Im Rahmen der Übungen werden Sie R-Code selbst schreiben und anschließend ausführen. Den Code werden Sie in dafür speziell vorgesehene Felder schreiben. Folgend sehen Sie ein solches Code-Feld, in das Sie Ihren Code schreiben werden.

Um den Code auszuführen, können Sie

  1. auf die Schaltfläche “Run Code” drücken oder

  2. gleichzeitig die Strg-Taste und die Entertaste () drücken. (Der Mauszeiger muss sich hierfür im Code-Feld befinden.)

Wenn der ausgeführte Code zu einer Ausgabe führt, sehen wir diese Ausgabe direkt unter dem Code-Feld.

Probieren Sie es aus, indem Sie auf “Run Code” klicken.

# Einführungsbeispiel
print("Hello, world!")

Sollten Sie einmal mehr Zeilen für Ihren Code benötigen, als in dem Code-Feld angezeigt werden, dann können Sie weitere Zeilen durch Drücken der Entertaste () hinzufügen.
Hierbei muss sich der Mauszeiger ebenfalls im Code-Feld befinden.

Wenn Sie bei einer Aufgabe einen Fehler machen, sodass R Ihren Code nicht interpretieren kann, erhalten Sie eine Fehlermeldung.

Probieren Sie es aus, indem Sie den Code ausführen. Klicken Sie dazu auf die grüne Schaltfläche “Run Code”.
Keine Sorge, Sie müssen jetzt noch nicht verstehen, was diese Fehlermeldung bedeutet.

Drücken Sie nach Erscheinen der Fehlermeldung auf “Continue”.

print(Hello, world!)

Manche der Code-Felder haben eine zusätzliche Schaltfläche mit der Bezeichnung “Hints” oder “Solution”.

Wenn Sie auf diese Schaltflächen klicken, erhalten Sie Hinweise oder die Lösung für die Aufgabe.
Hinweise und Lösungen werden in einer separaten Box angezeigt.
Wenn es für eine Aufgabe mehr als einen Hinweis gibt, erhalten Sie den nächsten Hinweis durch einen Klick auf die Schaltfläche “Next Hint”.

Die folgende Code-Zeile ist identisch mit jener aus der vorherigen Übung, die einen Fehler verursacht hat.

Nutzen Sie den Hinweis, um den Code zu korrigieren.

print(Hello, world!)
# Wenn Sie sich mit der Funktion print() Text ausgeben lassen möchten, 
# dann müssen vor und hinter dem Text Anführungszeichen stehen:

print("Hier steht der Text.")
# Die Lösung ist:

print("Hello, world!")

Grundlagen

Wenn wir mit R arbeiten, unterscheiden wir zwischen dem Skript (Englisch: script) und der R-Konsole (Englisch: console). Das Skript ist wie eine Art Notizblock. Hier schreiben Sie auf, was Sie machen möchten, z. B. welche Berechnungen Sie durchführen wollen. Die Konsole können Sie sich wie einen Taschenrechner vorstellen.

Die Notizen, die wir auf unseren Notizblock geschrieben haben, können wir zur Berechnung an die Konsole schicken. In der Konsole wird unsere Anweisung dann ausgeführt und gegebenenfalls das Ergebnis angezeigt. Das ist nichts anderes als das, was auf unserem Notizblock steht, in einen Taschenrechner einzugeben.

Der Vorteil des Notizblocks ist, dass wir auch morgen oder in einem Jahr noch ganz genau nachvollziehen können, was wir gemacht haben und wie wir es wiederholen können.

Wo wir gerade bei Taschenrechnern sind. Eine der grundlegendsten Anwendungsmöglichkeiten von R ist, es als Taschenrechner zu nutzen.

Geben Sie in das Code-Feld zwei plus zwei ein, so wie Sie das auch bei einem Taschenrechner machen würden.
Sie benötigen hierfür nicht die print() Funktion, die Sie ihm vorherigen Beispiel gesehen haben.
Das, was Sie derzeit noch in das Code-Feld schreiben, werden wir später in einem Skript speichern.

Führen Sie dann den Code aus.

Das, was Sie nach dem Ausführen des Codes unter der Code-Box sehen, entspricht der Ausgabe in der R-Konsole.

# Lösung

2 + 2

Arithmetische Operatoren

Um R als Taschenrechner zu verwenden, nutzen wir die folgenden arithmetischen Operatoren:

  • Addition: +
  • Subtraktion: -
  • Multiplikation: *
  • Division: /
  • Potenzierung: ^
  • Modulo: %% Modulo berechnet den Rest bei einer Division.

Probieren Sie es aus. Das Ergebnis jeder Rechnung wird in einer eigenen Zeile ausgegeben.

# Addition
15 + 27

# Multiplikation
7 * 8

# Division
# Denken Sie an "Punkt- vor Strichrechnung"
4 + 4 / 2

(4 + 4) / 2

# Modulo
18 %% 4

Berechnen Sie den Rest der Divison \(515 \div 43\).

# Lösung:

515 %% 43

Eine kleine Übung zu Potenzen. Schreiben Sie \(2 \times 2 \times 2\) als Potenz.

# Schreiben Sie folgende Berechnung als Potenz
2 * 2 * 2

# Lösung:
# Lösung:

2^3

Interessantes zu Potenzen:

# Was passiert, wenn die Potenz Null ist?
3^0

# Und wenn die Potenz negativ ist?
3^-1

Zur Erinnerung, für negative Potenzen gilt:

\[ a^{-b} = \frac{1}{a^b}\]

\[ 3^{-1} = \frac{1}{3^1} = 0.333333\]

Leerzeichen in R

R ignoriert überflüssige Leerzeichen. Die folgenden drei Zeilen Code führen alle zum gleichen Ergebnis. Es gibt Fälle, in denen R mehrfache Leerzeichen nicht als überflüssig betrachtet (hierzu später mehr).

Führen Sie den folgenden Code-Block aus, um sich zu vergewissern, dass alle Berechnungen zu dem gleichen Ergebnis führen.

2 + 2
2+2
2                 +             2

Um die Lesbarkeit unseres Codes zu verbessern, sollten wir jedoch vor und hinter jeden mathematischen Operator der vier Grundrechenarten (+, -, *, /) ein Leerzeichen setzen.

# So nicht:
2                 +             2

# Besser:
2 + 2

# Oder auch:
2 * 3
2 / 4

Kommentare

Wir haben bereits gesehen, dass wir zusätzliche Anmerkungen in unser Skript schreiben können. Diese Anmerkungen werden Kommentare genannt.

Kommentare werden in R durch die Raute # eingeleitet. Alles, was in einer Zeile hinter der Raute folgt, wird von R als Kommentar betrachtet und daher nicht als Befehl interpretiert.

Setzen Sie in der nächsten Übung mit der Raute Kommentare, sodass in der Ausgabe ausschließlich die Zahl 1992 angezeigt wird. Verändern Sie nicht die Zahlen oder Rechenoperatoren. Es gibt mehr als eine Möglichkeit, diese Aufgabe zu lösen.

Fun Fact: Im Jahr 1992 wurde R basierend auf der Programmiersprache S neu entwickelt.

1992 - 1000 + 36 / 6  * 3.75 + 328.5 * 3

(1111 + 0.5) * 4 - 4892 / 2

1000 * 0.5 + 1 + 498 * 3 - 3


1991 + 1500 * 0.75 - 1070
# 1. Lösungsmöglichkeit:
#1992 - 1000 + 36 / 6  * 3.75 + 328.5 * 3

#(1111 + 0.5) * 4 - 4892 / 2

1000 * 0.5 + 1 + 498 * 3 - 3


#1991 + 1500 * 0.75 - 1070
# 2. Lösungsmöglichkeit:
1992 #- 1000 + 36 / 6  * 3.75 + 328.5 * 3

#(1111 + 0.5) * 4 - 4892 / 2

#1000 * 0.5 + 1 + 498 * 3 - 3


#1991 + 1500 * 0.75 - 1070

Beachten Sie, dass wir bei Dezimalzahlen, z. B. 3.75 oder 0.33, einen Punkt . als Dezimaltrennzeichen nutzen (kein Komma).

Variablenzuweisung

In vielen Fällen wollen wir nicht nur einfach Berechnungen durchführen, sondern wir möchten mit dem Ergebnis weiterrechnen. Hierbei hilft uns das Konzept der Variablenzuweisung.

Variablenzuweisung bedeutet, dass wir in einer Variablen einen Wert speichern. Diese Variable können wir zum Beipsiel a nennen. Anders ausgedrückt, wir weisen dieser Variable einen bestimmten Wert zu.
Hierzu nutzen wir in R den Zuweisungsoperator <-.

Der Zuweisungsoperator <- weist der Variable, die links des Operators steht, den Wert zu, der rechts des Operators steht. Direkt vor und hinter dem Zuweisungsoperator sollte ein Leerzeichen stehen.

Schauen Sie sich das erste Beispiel an und probieren Sie es dann selbst aus.

Wenn Sie alles richtig machen, sehen Sie keine Ausgabe unter dem Code-Feld.

# Variable a wird der Wert 5 zugewiesen
a <- 5

# Weisen Sie der Variable b den Wert 2046 zu.
# Weisen Sie der Variable b den Wert 2046 zu.
b <- 2046

Info: In R kann auch das Gleichheitszeichen = als Zuweisungsoperator genutzt werden. Warum wir das nicht machen, klären wir später, wenn wir über Funktionen sprechen.

Ausgabe

In der vorherigen Übung haben wir gesehen, dass die Zuweisung eines Wertes an eine Variable nicht dazu führt, dass der Wert ausgegeben wird.

Der Wert einer Variable wird nur dann ausgegeben, wenn wir R explizit dazu anweisen. Hierzu müssen wir nur den Variablennamen an die Konsole schicken.

Probieren Sie es aus.
# Variablenzuweisung
e <- 3^-2

# Ausgabe des Wertes von e
e

Variablennamen

Bisher haben wir einzelne Kleinbuchstaben (a, b und e) als Variablennamen genutzt. Variablennamen können jedoch auch aus mehreren Zeichen bestehen.

Hierfür gibt es in R klare Vorgaben.
Ein Name kann aus folgenden unterschiedlichen Zeichen bestehen:

  1. Klein- und Großbuchstaben
  2. Ziffern (0-9)
  3. Unterstrichen _
  4. Punkten .

Der Name darf nicht mit einer Ziffer oder einem _ beginnen.

Darüber hinaus gibt es reservierte Wörter, z. B. TRUE, FALSE, if, NA, for, die nicht als Namen verwendet werden können.
Mit ?Reserved können wir uns die Liste der reservierten Wörter anzeigen lassen.

Führen Sie den folgenden Code aus.
# Reservierte Wörter
?Reserved

Info: Variablen, wie etwa a, b oder e, werden in R oft auch als Objekte bezeichnet.

Interessantes zu Variablenbenennung

Zwei verbreitete Möglichkeiten, Variablen zu benennen, werden als camelCase und snake_case bezeichnet.

  • camelCase: Wenn Variablennamen aus mehreren Wörtern (oder einer Kombination von Abkürzungen und Wörtern) bestehen, werden die Wörter direkt miteinander verbunden. Dabei wird der erste Buchstabe jedes einzelnen Wortes großgeschrieben, die restlichen Buchstaben klein. Manchmal wird der aller erste Buchstabe des Variablennamens auch kleingeschrieben.

Angenommen wir würden eine Variable für das durchschnittliche Alter (Englisch: mean/average age) erstellen wollen, dann wäre MeanAge oder auch meanAge ein typischer camelCase Variablenname. Weitere Beispiele sind hhIncome (Englisch: household income) oder BritColony (Englisch: British colony).

  • snake_case: Bei der snake_case-Benennung werden die verschiedenen Wörter (oder Abkürzungen) durch einen Unterstrich _ miteinander verbunden. Das obige Beispiel würde bei einer snake_case-Benennung mean_age geschrieben. Weitere Beispiele sind avg_income, hh_income und brit_colony.

Die Ergebnisse eines Ein Eye-Tracking-Experiments legen nahe, dass Variablennamen, die dem snake_case-Stil folgen, schneller erkannt werden.

Sowohl bei camelCase als auch bei snake_case handelt es sich um sprechende Variablennamen. Das bedeutet, dass wir von der Benennung einer Variablen auf deren Funktion oder (thematischen) Inhalt schließen können. Während MeanAge oder hh_income Beispiele für sprechende Variablennamen sind, ist var_42 ein nicht-sprechender Variablenname.

Überprüfen wir unser neues Wissen gleich einmal.

a ist nicht A!

Wenn Sie mit Variablen arbeiten, müssen Sie bei der Bezeichnung sehr genau sein. a (Kleinbuchstabe) ist eine andere Variable als A (Großbuchstabe). Bei dem Passwort für Ihr E-Mail-Konto macht es ebenfalls einen Unterschied, ob Sie “a” oder “A” eingeben.

Im Englischen sagt man in diesem Zusammenhang, dass R “case sensitive” ist, also einen Unterschied zwischen Klein- und Großbuchstaben macht.

Korrigieren Sie den Code in der fünften Zeile

# Variablenzuweisung
income_jan <- 850 
income_feb <- 1075

income_Jan + income_Feb
# Variablenzuweisung
income_jan <- 850 
income_feb <- 1075

# Ersetzen Sie die Groß- durch Kleinbuchstaben
income_jan + income_feb

Wie Sie gerade gesehen haben, können wir nicht nur einzelne Zahlen einer Variable zuweisen, sondern auch das Ergebnis einer Berechnung.

Außerdem können wir in diesen Berechnungen ebenfalls Variablen nutzen, wenn diesen zuvor ein Wert zugewiesen wurde.

Schauen Sie sich den folgenden Code-Block an und überlegen Sie, bevor Sie den Code ausführen, was R ausgibt.
Führen Sie dann den Code aus und Schauen sich die Ausgabe an.

# Variable a
a <- 20 / 5

# Variable b
b <- 6 * 6

# Variable c
c <- a + b

c - 10

Angenommen wir möchten für eine Studentin der Politikwissenschaft die Durchschnittsnote Ihres Erstfaches berechnen. Ihr Erstfach besteht aus den drei Bereichen Politische Theorie, Vergleich politischer Systeme und Internationale Beziehungen (IR: International relations). Alle drei Bereiche gehen gleichwertig in die Durchschnittsnote ein.

Ändern Sie den folgenden Code, sodass die Durchschnittsnote berechnet und anschließend ausgegeben wird.

# Zuweisung der drei Noten zu Variablen
# Die Note der Studentin in Internationale Beziehungen ist drei 
grade_theo <- 2
grade_comp <- "eins"
grade_ir <- 

# Berechnung der Durchschnittsnote und
# Zuweisung des Ergebnisses an die Variable
# avg_grade (average grade)
avg_grade <- (grade_theo + grade_comp + GRADE_IR) / 3
avg_grade
# Zunächst muss das Wort "eins" durch eine Zahl ersetzt werden.
# Bei einem Taschenrechner könnten wir auch nicht das Wort "eins"
# eingeben, um einen Mittelwert zu berechnen.
# Wir werden später hierauf noch genauer eingehen.
grade_comp <- 1
# Dann muss die Note für Internationale Beziehungen ergänzt werden.
grade_ir <- 3
# Zum Schluss müssen wir noch den Variablennamen anpassen.
# R unterscheidet zwischen Groß- und Kleinbuchstaben.
avg_grade <- (grade_theo + grade_comp + grade_ir) / 3

Machen wir das Ganze ein bisschen komplizierter.

Sie erinnern sich vielleicht noch an die Stichprobenvarianz aus der Einführungsvorlesung Statistik.

\[ S^2 = \frac{1}{n-1} \sum_{i=1}^n (X_i - \overline{X})^2\]

\(X\) ist die Variable, für die wir die Stichprobenvarianz ermitteln wollen.

\(X_i\) ist der Wert der Variable \(X\) der i-ten Beobachtung.

\(n\) ist die Größe der Stichprobe (Stichprobenumfang).

\(\overline{X}\) ist der Mittelwert der Variable \(X\).

Angenommen wir haben eine Stichprobe von 5 Kindern und möchten die Stichprobenvarianz für die Körpergröße der Kinder “per Hand” berechnen.

Die Kinder sind 126, 128, 133, 134, und 136 Zentimeter groß. Das sind die \(X_i\).

Um die Summe der quadrierten Abweichungen zu berechnen, könnten wir wie folgt vorgehen.

# Mittelwert der Körpergröße der 5 Kinder
(126 + 128 + 133 + 134 + 136) / 5
## [1] 131.4
# Summe der quadrierten Abweichungen
(126 - 131.4)^2 + (128 - 131.4)^2 + 
  (133 - 131.4)^2 + (134 - 131.4)^2 + 
  (136 - 131.4)^2
## [1] 71.2
# Stichprobenvarianz
71.2 / (5-1)
## [1] 17.8

Wenn Sie denken, dass das ganz schön umständlich ist, dann haben Sie recht.
Vervollständigen Sie den folgenden Code-Block, sodass R am Ende die Summe der quadrierten Abweichungen ausgibt. Versuchen Sie dabei, die Zahlen für die Körpergrößen so wenig wie möglich zu nutzen. Falls nötig, können Sie auch weitere Variablen erstellen.

kid_1 <-
kid_2 <-
kid_3 <-
kid_4 <-
kid_5 <-  
  
sum_of_squares <-
sum_of_squares
# Zuweisung der Körpergrößen an Variablen
kid_1 <- 126
kid_2 <- 128
kid_3 <- 133
kid_4 <- 134
kid_5 <- 136 
# Stichprobenumfang
n <- 5
# Durchschnittliche Körpergröße (Mittelwert)
mean_height <- (kid_1 + kid_2 + kid_3 + kid_4 + kid_5) / n
# Summe der quadrierten Abweichungen
sum_of_squares <- (kid_1 - mean_height)^2 + 
                  (kid_2 - mean_height)^2 + 
                  (kid_3 - mean_height)^2 + 
                  (kid_4 - mean_height)^2 + 
                  (kid_5 - mean_height)^2
# Lösung auf einen Blick
kid_1 <- 126
kid_2 <- 128
kid_3 <- 133
kid_4 <- 134
kid_5 <- 136

n <- 5
mean_height <- (kid_1 + kid_2 + kid_3 + kid_4 + kid_5) / n

sum_of_squares <- (kid_1 - mean_height)^2 + 
                  (kid_2 - mean_height)^2 + 
                  (kid_3 - mean_height)^2 + 
                  (kid_4 - mean_height)^2 + 
                  (kid_5 - mean_height)^2

sum_of_squares / (n-1)

Wenn Sie an keiner Stelle Zwischenergebnisse als echte Zahlen ausschreiben möchten, kann Ihre Lösung im Optimalfall wie folgt aussehen.

Der Vorteil ist, dass sich der Code bei Veränderungen der Körpergrößen sehr leicht anpassen lässt.

Führen Sie den Code aus.
kid_1 <- 126
kid_2 <- 128
kid_3 <- 133
kid_4 <- 134
kid_5 <- 136

n <- 5

mean_height <- (kid_1 + kid_2 + kid_3 + kid_4 + kid_5) / n

sum_of_squares <- (kid_1 - mean_height)^2 + 
                  (kid_2 - mean_height)^2 + 
                  (kid_3 - mean_height)^2 + 
                  (kid_4 - mean_height)^2 + 
                  (kid_5 - mean_height)^2

sum_of_squares / (n-1)

Sie sehen, wir erhalten das gleiche Ergebnis wie zuvor.

Beachten Sie, dass wir bei der Berechnung der Variable sum_of_squares einfach Zeilenumbrüche einfügen können (Zeile 11-15). Da wir die Zeilen mit einem + beenden, weiß R, dass wir mit unserer Eingabe noch nicht fertig sind, und macht in der nächsten Zeile weiter.

Wenn sich ein Befehl, wie hier die Berechnung, über mehrere Zeilen erstreckt, wird der Code ab der zweiten Zeile normalerweise eingerückt. Das dient der Lesbarkeit des Codes, da man so schnell sehen kann, dass es sich um einen einzigen langen Befehl handelt.

Datentypen

In R gibt es unterschiedliche Datentypen. Zu den wichtigsten Datentypen gehören:

  1. double: Dezimalzahlen, wie z. B. 4.5 oder -0.173.

  2. integer: Ganze Zahlen, z. B. …, -2, -1, 0, 1, 2, … .
    Die Typen double und integer werden auch als numeric bezeichnet.

  3. logical: Die logischen Werte TRUE (wahr) und FALSE (falsch), die auch als Boolesche Werte bezeichnet werden.

  4. character: Zeichenfolgen (oft auch strings genannt), wie z. B. “abc” oder “Hello, world!”. Wenn mir mit einer Zeichenfolge arbeiten, muss diese in Anführungszeichen eingeschlossen sein.

Verändern Sie den folgenden Code-Block entsprechend den Angaben in den Kommentaren.
Führen Sie anschließend den Code aus.
# Ändern Sie my_double zu 63.75
my_double <- 1024
my_double

# Ändern Sie my_character zu "Hello, world!"
my_character <- "Das ist eine Zeichenfolge!"
my_character

# Ändern Sie my_logical zu TRUE
my_logical <- FALSE
my_logical
# Ändern Sie my_double zu 63.75
my_double <- 63.75
my_double

# Ändern Sie my_character zu "Hello, world!"
my_character <- "Hello, world!"
my_character

# Ändern Sie my_logical zu TRUE
my_logical <- TRUE
my_logical

Anmerkung: Die Unterscheidung von double und integer ist eigentlich etwas komplizierter. Beim Datentyp double handelt es sich um sogenannte Gleitkommazahlen. Für uns reicht jedoch die oben genannte Unterscheidung. Weitere Infos…

logical und Vergleichsoperatoren

Was sind eigentlich Variablen vom Typ logical und wozu brauchen wir sie?

Manchmal wollen wir Befehle nur ausführen, wenn eine bestimmte Bedingung (Englisch: condition) erfüllt ist. Möglicherweise interessieren wir uns für das durchschnittliche Einkommen jener, die die Bedingung erfüllen, jünger als 30 Jahre zu sein.
Mit folgenden Vergleichsoperatoren prüfen wir, ob eine Bedingung erfüllt ist.

Vergleichsoperatoren:

  1. ==: Gleichheit

  2. <: Kleiner als…

  3. >: Größer als…

  4. <=: Kleiner oder gleich…

  5. >=: Größer oder gleich…

  6. !=: Ungleichheit

Das Ergebnis einer solchen Überprüfung ist dann der Wert TRUE oder FALSE.
Diese Bedingungen werden auch logische Ausdrücke genannt.

Probieren wir es aus.

# Ist 5 gleich 6?
5 == 6

# Ist 7 kleiner als 9?
7 < 9

# Ist 15 größer als 15.001?
15 > 15.001

Wir können das Resultat einer solchen Überprüfung auch direkt einer Variable zuweisen.

Was gibt R in diesem Fall aus?

# Ist 4 ungleich -4?
# Zuweisung des Wertes an X.
x <- 4 != -4
x

Wir können logische Werte auch direkt miteinander vergleichen.

Schauen Sie sich den folgenden Code-Block an und überlegen Sie, bevor Sie den Code ausführen, was R ausgibt.
Schauen Sie sich dann die Ausgabe an.

# Ist TRUE gleich FALSE?
TRUE == FALSE

# Ist TRUE gleich TRUE?
TRUE == TRUE

FALSE == FALSE

TRUE != FALSE

Nutzen Sie die Vergleichsoperatoren, um zu überprüfen, ob a kleiner oder gleich b ist.

a <- 42
b <- 36

# Ist a kleiner oder gleich b?
a
a <- 42
b <- 36

# Ist a kleiner oder gleich b?
a <= b

Nutzen Sie die Vergleichsoperatoren, um zu überprüfen, ob c größer oder gleich 7 ist.

c <- 7

# Ist größer oder gleich 7?
c
c >= 7

Wir hatten zuvor gesehen, dass R überflüssige Leerzeichen ignoriert. Bei Variablen des Typs character ist das nicht der Fall.

Überzeugen Sie sich davon.

my_char_1 <- "Hello,      world!"
my_char_2 <- "     Hello,       world!"


my_char_1
my_char_2

Um sicherzugehen, sollten wir das noch einmal explizit prüfen.

my_char_1 <- "Hello,      world!"
my_char_2 <- "     Hello,       world!"

# Prüfen Sie, ob my_char_1 gleich my_char_2 ist.
my_char_1
my_char_1 <- "Hello,      world!"
my_char_2 <- "     Hello,       world!"

# Prüfen Sie, ob my_char_1 gleich my_char_2 ist.
my_char_1 == my_char_2

Boolesche Operatoren

Wir können auch mehr als eine Bedingung gleichzeitig prüfen. Hierzu nutzen wir die Booleschen Operatoren:

  1. &: UND-Operator

  2. |: ODER-Operator.

  3. !: NICHT-Operator

Mit den beiden ersten Operatoren (& und |) können wir Bedingungen (logische Ausdrücke) miteinander verknüpfen.

Das Ergebnis einer solchen Verknüpfung ist ebenfalls vom Typ logical.

# 1. UND-Verknüpfung
TRUE & TRUE

# 2. UND-Verknüpfung
TRUE & FALSE

Folgende Tabelle zeigt die möglichen UND-Verknüpfungen von FALSE und TRUE und das dazugehörige Ergebnis.

& FALSE TRUE
FALSE FALSE FALSE
TRUE FALSE TRUE

Die erste Spalte der Tabelle zeigt, welchen Wert (wahr oder falsch) der erste Ausdruck annimmt.
Die erste Zeile der Tabelle zeigt, welchen Wert (wahr oder falsch) der zweite Ausdruck annimmt.

Wenn etwa der erste Ausdruck FALSE ist (d. h., wir schauen nur noch auf die zweite Zeile) und der zweite Ausdruck TRUE, dann liefert die Verknüpfung der beiden Ausdrücke mit dem UND-Operator den Wert FALSE. Das ist die Zelle in der zweiten Zeile und dritten Spalte.

Nur wenn alle Ausdrücke einer UND-Verknüpfung wahr (TRUE) sind, ist auch das Resultat wahr.

Beispiel: UND-Operator

Schauen wir uns den UND-Operator anhand eines Beispiels an.

Die folgende Tabelle zeigt die Anzahl der Bundestagabgeordneten pro Partei unterschieden nach Geschlecht.
Die Daten stammen vom Deutschen Bundestag (Quelle: Kürschner Volkshandbuch; Stand: Juli 2019). Vier fraktionslose Abgeordnete wurden nicht in die Tabelle aufgenommen.

CDU/CSU SPD AfD FDP Die Linke B90/Grüne
Frauen 51 65 10 18 37 39
Männer 195 87 81 62 32 28

Angenommen wir möchten ausschließlich die weiblichen Abgeordneten der CDU/CSU auswählen. Dies entspricht der folgenden Verknüpfung zweier Ausdrücke:

Geschlecht == “weiblich” & Partei == “CDU/CSU”


Anders ausgedrückt, wir möchten nur jene Abgeordneten auswählen, die sowohl weiblich sind als auch der CDU/CSU angehören. Das bedeutet, beide Ausdrücke müssen wahr sein, damit das Ergebnis wahr ist. Der UND-Operator sorgt dafür, dass nur die 51 weiblichen Bundestagsabgeordneten der CDU/CSU ausgewählt werden.

Sie können natürlich gerne die CDU/CSU durch jede andere der aufgeführten Parteien ersetzen und Ihr eigenes Beispiel erstellen.

|: ODER-Operator

Das Zeichen für den ODER-Operator | wird auch “Pipe” genannt. Es befindet sich in er Regel links neben der Y-Taste bei einem deutschen Windows-Tastaturlayout. Sie erhalten das Zeichen, wenn Sie gleichzeitig AltGr und < auf Ihrer Tastatur drücken. Bei Apple-Computern nutzen Sie die Tastenkombination alt und 7 für die Pipe.

# 1. ODER-Verknüpfung
TRUE | FALSE

# 2. ODER-Verknüpfung
TRUE | TRUE

Folgende Tabelle zeigt die möglichen ODER-Verknüpfungen von FALSE und TRUE und das dazugehörige Ergebnis.
Wenn mindestens ein Ausdruck der ODER-Verknüpfung wahr ist, ist auch das Resultat wahr.

| FALSE TRUE
FALSE FALSE TRUE
TRUE TRUE TRUE

Beispiel: ODER-Operator

Schauen wir uns noch einmal die Daten der Bundestagsabgeordneten an.

Wenn wir die Anzahl der Abgeordneten der Großen Koalition (CDU/CSU und SPD) ermitteln wollen, entspricht das der folgenden ODER-Verknüpfung zweier Aussagen:

Partei == “CDU/CSU” | Partei == “SPD”


CDU/CSU SPD AfD FDP Die Linke B90/Grüne
Frauen 51 65 10 18 37 39
Männer 195 87 81 62 32 28

Ungeachtet des Geschlechts erfüllen alle Abgeordnete in den Spalten “CDU/CSU” (51 + 195 = 246) und “SPD” (65 + 87 = 152) diese Bedingung. Insgesamt ist die Bedingung also für 398 Abgeordnete wahr.

In diesem Beispiel gibt es keine Abgeordnete und keinen Abgeordneten, für die/den beide Ausdrücke gleichzeitig wahr sind. Wenn jedoch alle Ausdrücke einer ODER-Verknüpfung wahr sind, dann ist auch das Ergebnis wahr.

46 >= 43 & 72 <= 96 

17 <= 13 | 2.65 >= 3.75

Unterschiedliche Datentypen

Daten unterschiedlicher Typen sind in der Regel nicht miteinander kombinierbar.

Probieren Sie es aus.

a <- 4 
b <- "fünf"

a + b

logicals bilden hier jedoch eine Ausnahme. Da FALSE und TRUE von R auch als 0 und 1 behandelt werden, können wir Folgendes machen.

Führen Sie den Code aus.
5 + TRUE

FALSE + 1

Das wird uns später noch helfen.

Wenn wir uns nicht sicher sind, welchen Datentyp eine Variable hat, können wir einfach R fragen.

x <- 9.66
typeof(x)

y <- "Was bin ich?"
typeof(y)

typeof(FALSE)

Schauen Sie sich die folgende Variablenzuweisung an.

a <- "4"

Wie sieht es bei diesem Beispiel aus?

b <- "TRUE"

Datenstrukturen

Sie haben bereits gelernt, wie Sie Werte unterschiedlichen Datentyps (double, integer, logical, character) einer Variable zuweisen.

Meist wollen wir jedoch nicht nur einen Wert speichern, sondern mehrere Werte.

Hierfür gibt es in R unterschiedliche Datenstrukturen. Zu den wichtigsten gehören:

  1. Vektoren

  2. Matrizen

  3. Data frames

  4. Listen

Vektoren

Bisher haben wir recht umständlich einzelne Werte in unterschiedlichen Variablen gespeichert. In Vektoren können wir mehrere Werte des gleichen Datentyps speichern.

Um einen Vektor zu erstellen, nutzen wir die combine-Funktion c(). Hierzu schreiben wir die Werte, die wir speichern wollen, durch Kommata getrennt in die Klammern. Schauen Sie sich die ersten beiden Beispiele an.

Erstellen Sie dann einen Booleschen Vektor und lassen diesen von R ausgeben.

numeric_vector <- c(64, 128, 512, -1)
numeric_vector

character_vector <- c("CDU", "SPD", "B90-Gruene", "FDP", "Die Linke", "AFD")
character_vector

# Erstellen Sie einen Booleschen Vektor mit den Werten 
# FALSE, FALSE und TRUE
character_boolean
character_boolean <- c(FALSE, FALSE, TRUE)
character_boolean

Was passiert, wenn wir zwei unterschiedliche Datentypen in einem Vektor kombinieren?

Nutzen Sie die Funktion typeof(), die Sie bereits kennen, um den Datentyp der drei Vektoren herauszufinden.

# character und numeric
test_vector_1 <- c(2, "Hallo?", 728)

# character und logical
test_vector_2 <- c("Metropolis-Hastings", TRUE, FALSE)

# numeric und logical 
test_vector_3 <- c(6.33, TRUE, FALSE)
# Setzen Sie den Namen des Vektors, für den Sie
# den Datentyp ermitteln wollen, z. B. test_vector_1,
# zwischen die Klammern von typeof() und
# führen Sie den Code aus.
typeof(test_vector_1)
typeof(test_vector_2)
typeof(test_vector_3)

Schauen wir uns die Vektoren genauer an. Führen Sie dazu einfach den Code aus.

# character und numeric
test_vector_1 <- c(2, "Hallo?", 728)

# character und logical
test_vector_2 <- c("Metropolis-Hastings", TRUE, FALSE)

# numeric und logical 
test_vector_3 <- c(6.33, TRUE, FALSE)


test_vector_1
test_vector_2
test_vector_3

Da Vektoren nur Werte des gleichen Datentyps enthalten können, erzwingt R einen einheitlichen Datentyp, wenn wir versuchen, Werte unterschiedlichen Datentyps in einem Vektor zu kombinieren.

Wenn Zeichenfolgen mit logischen oder numerischen Werten kombiniert werden, erzwingt R den Datentyp character und behandelt zum Beispiel 1 nicht als Zahl, sondern als Zeichen “1”. TRUE wird äquivalent als “TRUE” gespeichert.

Wenn wir versuchen, numerische zusammen mit logischen Werten in einem Vektor zu speichern, erzwingt R den Datentyp numeric.

Da bei test_vector_3 Werte des Types logical und double miteinander kombiniert werden, ist test_vector_3 vom Typ double. TRUE wird in diesem Fall zu der Zahl 1.00 und FALSE zu 0.00. Die Nachkommastellen deuten darauf hin, dass es sich um den Datentyp double handelt.

c(TRUE, FALSE, 1, 0, FALSE, TRUE, 0, "0", 1, 1)

Wir können uns merken, wenn Werte mit unterschiedlichem Datentypen in einem Vektor zusammengefasst werden, dann hat der Datentyp…

  • character Vorrang vor numeric und logical
  • numeric Vorrang vor logical

1. character

2. numeric

3. logical

Angenommen Sie möchten Ihr Telefonverhalten mit Ihren besten (Statistik-) Freunden Florence Nightingale und Pierre-Simon Laplace analysieren.

Mit Florence haben Sie in den letzten sechs Wochen häufig telefoniert, um nach Ratschlägen für die Visualisierung von Daten zu fragen. Mit Pierre-Simon haben Sie hauptsächlich über Wahrscheinlichkeitsrechnung und Bayes-Theorem gesprochen.

Folgende Tabelle zeigt, wie viele Minuten Sie in den vergangenen sechs Wochen jeweils mit den beiden telefoniert haben.

Florence Pierre-Simon
Woche 1 44 94
Woche 2 75 86
Woche 3 83 34
Woche 4 100 70
Woche 5 26 16
Woche 6 65 56

Weisen Sie dem Vektor call_time_pier die Anrufzeiten (in Minuten) für Pierre-Simon Laplace aus der obigen Tabelle zu. Achten Sie dabei auf die Reihenfolge. Die Anrufdauer für die erste Woche soll an erster Stelle im Vektor stehen. Die Anrufdauer für die sechste Woche soll an letzter Stelle stehen.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)
call_time_flo

# Anrufdauer pro Woche für Pierre-Simon Laplace
call_time_pier <-
call_time_pier
call_time_pier <- c(94, 86, 34, 70, 16, 56)

Damit wir nicht verwechseln, ob das erste Element des Vektors für die erste oder die sechste Woche steht, können wir die Vektoren benennen.

Hierzu nutzen wir die Funktion names(). Führen Sie den folgenden Code-Block aus, um zu sehen, was die Funktion macht.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)

# Ausgabe nicht-benannter Vektor
call_time_flo

# Benennung der Elemente des Vektors call_time_flo
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Ausgabe benannter Vektor
call_time_flo

Benennen Sie nun die Elemente des Vektors call_time_pier, so wie für den Vektor call_time_flo. Überprüfen Sie Ihren Code, indem Sie sich den Vektor call_time_pier ausgeben lassen.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)

# Benennung der Elemente des Vektors call_time_flo
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Anrufdauer pro Woche für Pierre-Simon Laplace
call_time_pier <- c(94, 86, 34, 70, 16, 56)

# Benennung der Elemente des Vektors call_time_pier
names(call_time_pier) <-
names(call_time_pier) <- c("Woche 1", "Woche 2", "Woche 3", 
                           "Woche 4", "Woche 5", "Woche 6")
call_time_pier

Wir können den Code aus dem vorherigen Beispiel noch kürzer schreiben.
Kürzerer Code ist meist besser, da er übersichtlicher und somit weniger fehleranfällig ist. Wir können die Bezeichnungen “Woche 1”, “Woche 2”, … in einem eigenen Vektor speichern und diesen Vektor dann zur Benennung nutzen.

Lassen Sie sich zur Überprüfung die beiden Vektoren vom Typ numeric ausgeben.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)

# Anrufdauer pro Woche für Pierre-Simon Laplace
call_time_pier <- c(94, 86, 34, 70, 16, 56)

# Erstellen eines Vektors mit der Benennung (Namen)
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Woche 6")

# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_flo) <- 
names(call_time_pier) <-  
# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_flo) <- weeks_vector 
names(call_time_pier) <- weeks_vector

call_time_flo
call_time_pier

Was machen wir eigentlich, wenn wir uns einmal vertippt haben und das korrigieren möchten?
Wir können unseren Fehler einfach korrigieren und den Wert erneut zuweisen.
Hierfür benötigen wir keine andere Funktion. Das gilt auch für das Überschreiben von Matrizen, data frames und Listen.

Der folgende Code-Block wurde bereits ausgeführt. Wie Sie sehen, haben sich ein paar Fehler eingeschlichen.

Korrigieren Sie folgende Fehler:

  1. Entfernen Sie das Minuszeichen aus dem Vektor call_time_pier.
  2. Ändern Sie die Gesprächsdauer für die sechste Woche von 5600 auf 56 Minuten.
  3. Korrigieren Sie die Benennung “Wche 60”.

Führen Sie den Code nach der Korrektur erneut aus.

# Entfernen Sie das Minuszeichen und 
# korrigieren Sie das letzte Element
call_time_pier <- c(-94, 86, 34, 70, 16, 5600)

# Korrigieren Sie das letzte Element
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Wche 60")

# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_pier) <- weeks_vector

call_time_pier
Woche 1 Woche 2 Woche 3 Woche 4 Woche 5 Wche 60 
    -94      86      34      70      16    5600 

Wichtig: Sie erhalten keine Warnung von R, dass Sie versuchen, einen bereits existierenden Vektor zu überschreiben.
R geht nämlich davon aus, dass Sie wissen, was Sie machen!

Sie sollten sich daher immer davon überzeugen, dass Ihr Code auch wirklich das macht, was Sie möchten!

# Korrigierte Anrufzeiten
call_time_pier <- c(94, 86, 34, 70, 16, 56)

# Korrigierte Benennung
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Woche 6")

# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_pier) <- weeks_vector

call_time_pier

Rechnen mit Vektoren

Wir können mit Vektoren auch rechnen.

Schauen Sie sich den folgenden Code-Block an und überlegen Sie, wie die Ausgabe aussehen könnte.

Führen Sie dann den Code aus.
a <- c(1, 3, 2)
b <- c(2, 4, 8)

a + b

Wenn wir zwei Vektoren addieren, führt R die Berechnung “Element für Element” aus. Das bedeutet, R addiert…

  • das erste Element des Vektors a zu dem ersten Element des Vektors b,
  • das zweite Element des Vektors a zu dem zweiten Element des Vektors b,
  • das dritte Element des Vektors a zu dem dritten Element des Vektors b,
  • usw.

Wir erhalten als Ergebnis einer solchen Berechnung einen Vektor, der genau so viele Zahlen enthält wie Vektor a (oder b). Man spricht in diesem Zusammenhang auch von der Länge eines Vektors. Vektor a und b haben die Länge 3.

Die folgenden drei Berechnungen sind äquivalent.

c(1 + 2, 3 + 4, 2 + 8)
## [1]  3  7 10
c(1, 3, 2) + c(2, 4, 8)
## [1]  3  7 10
a <- c(1, 3, 2)
b <- c(2, 4, 8)
a + b
## [1]  3  7 10

Die Element-für-Element-Berechnung gilt nicht nur bei der Addition von Vektoren, sondern für alle vier Grundrechenarten (+, -, *, /).

a <- c(1, 3, 2)
b <- c(2, 4, 8)

a + b
## [1]  3  7 10
a - b
## [1] -1 -1 -6
a * b
## [1]  2 12 16
a / b
## [1] 0.50 0.75 0.25

Nutzen Sie nun Ihre Kenntnisse über die Addition von Vektoren und berechnen Sie die Gesamtgesprächsdauer (mit Florence und Pierre-Simon) pro Woche. Sie sollten als Ergebnis für jede der sechs Wochen eine Zahl erhalten.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)

# Anrufdauer pro Woche für Pierre-Simon Laplace
call_time_pier <- c(94, 86, 34, 70, 16, 56)

# Erstellen eines Vektors mit der Benennung (Namen)
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Woche 6")

# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_flo) <- weeks_vector
names(call_time_pier) <- weeks_vector

# Gesamtgesprächsdauer
total_ctime <-
total_ctime
total_ctime <- call_time_flo + call_time_pier
total_ctime

Oft möchten wir den Mittelwert einer uns interessierenden Variable ermitteln, zum Beispiel

  • das durchschnittliche Einkommen der Teilnehmer_innen einer Umfrage,
  • die Durchschnittsnote bei einer Statistikklausur oder
  • die durchschnittliche Anzahl an Bewerbungen, die Absolvent_innen der Universität Potsdam schreiben, bevor sie ihre erste Arbeitsstelle nach dem Studium beginnen.

Mit der Funktion mean() können wir in R den Mittelwert für einen Vektor berechnen.

# Mittelwert eines Vektors
mean( c(3, 6, 9) )
## [1] 6

Nutzen Sie die Funktion mean(), um die durchschnittliche Gesprächsdauer mit Florence und Pierre-Simon zu ermitteln.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)

# Anrufdauer pro Woche für Pierre-Simon Laplace
call_time_pier <- c(94, 86, 34, 70, 16, 56)

# Erstellen eines Vektors mit der Benennung (Namen)
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Woche 6")

# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_flo) <- weeks_vector
names(call_time_pier) <- weeks_vector

# Mittelwert: Florence
mean()

# Mittelwert: Pierre-Simon
# Mittelwert: Florence
mean(call_time_flo)

# Mittelwert: Pierre-Simon
mean(call_time_pier)

Als Nächstes interessieren wir uns dafür, wie lange Sie insgesamt in den letzten sechs Wochen jeweils mit Florence Nightingale und Pierre-Simon Laplace telefoniert haben.

Hierfür nutzen wir die Funktion sum(), die die Summe der Werte eines Vektors berechnet.

Vervollständigen Sie den Code-Block und lassen Sie die Vektoren total_flo und total_pier ausgeben.

# Anrufdauer pro Woche für Florence Nightingale
call_time_flo <- c(44, 75, 83, 100, 26, 65)

# Anrufdauer pro Woche für Pierre-Simon Laplace
call_time_pier <- c(94, 86, 34, 70, 16, 56)

# Erstellen eines Vektors mit der Benennung (Namen)
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Woche 6")

# Zuweisung der Namen zu call_time_flo und call_time_pier
names(call_time_flo) <- weeks_vector
names(call_time_pier) <- weeks_vector

# Gesamtgesprächsdauer für Florence und Pierre-Simon
total_flo <- sum(call_time_flo)
total_pier <-
# Gesamtgesprächsdauer für Florence und Pierre-Simon
total_flo <- sum(call_time_flo)
total_pier <- sum(call_time_pier)

# Ausgabe 
total_flo
total_pier

Angenommen Sie sind an den absoluten Zahlen gar nicht interessiert, sondern wollen nur wissen, ob Sie länger mit Florence telefoniert haben als mit Pierre-Simon?

Das können Sie mit den Vergleichsoperatoren (==, <, >, <=, >=, !=) herausfinden, die wir bereits behandelt haben.

Überprüfen Sie, ob die gesamte Gesprächszeit mit Florence länger war als jene mit Pierre-Simon.

# Anrufzeiten der letzten sechs Wochen
call_time_flo <- c(44, 75, 83, 100, 26, 65)
call_time_pier <- c(94, 86, 34, 70, 16, 56)
weeks_vector <- c("Woche 1", "Woche 2", "Woche 3", 
                  "Woche 4", "Woche 5", "Woche 6")
names(call_time_flo) <- weeks_vector
names(call_time_pier) <- weeks_vector

# Gesamtgesprächsdauer für Florence und Pierre-Simon
total_flo <- sum(call_time_flo)
total_pier <- sum(call_time_pier)

# Überprüfen Sie, ob Sie länger mit Florence 
# als mit Pierre-Simon telefoniert haben
# Vergleichen Sie, ob Sie länger mit Florence telefoniert haben
total_flo > total_pier

Indizierung von Vektoren

Sie hatten in den letzten sechs Wochen scheinbar mehr Fragen zur Visualisierung von Daten (Nightingale) als zur Wahrscheinlichkeitsrechnung (Laplace). Aber wie sieht es über diese sechs Wochen hinweg aus? Haben Sie mit Florence in Woche 1 länger telefoniert als in Woche 6?

Um das herauszufinden, müssen wir die einzelnen Werte aus dem Vektor auswählen und dann miteinander vergleichen.

Zum Auswählen von Elementen aus einem Vektor (oder später aus einer Matrix, Liste oder data frame) nutzen wir die eckigen Klammern []. Man nennt dies auch Indizierung.

Wir schreiben die eckigen Klammern ohne Leerzeichen direkt hinter den Vektor. Zwischen die Klammern schreiben wir die Position des Elements im Vektor, das wir auswählen möchten.

Indizierung beginnt in R mit der 1. Wenn wir das erste Element eines Vektors auswählen wollen, schreiben wir also eine 1 in die eckigen Klammern. Wenn wir das dritte Element auswählen wollen, schreiben wir eine 3 in die Klammern.

Wählen Sie den Wert für die 6. Woche aus und weisen ihn einer neuen Variable flo_week6 zu. Lassen Sie R danach die Variable ausgeben.

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Auswahl 6. Woche und Zuweisung zu flo_week6
flo_week6 <- call_time_flo[6]
flo_week6

Wählen Sie nun, das erste Element des Vektors call_time_flo aus und weisen es flo_week1 zu.

Überprüfen Sie dann, ob flo_week1 größer ist als flo_week6.

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Auswahl 6. Woche und Zuweisung zu flo_week6
flo_week6 <- call_time_flo[6]
# Auswahl 1. Woche und Zuweisung zu flo_week1
flo_week1 <- call_time_flo[1]

flo_week1 > flo_week6

Wir können nicht nur ein Element auswählen, sondern auch mehrere Elemente auf einmal.

Dazu müssen wir in den eckigen Klammern nur die Indizes (die Positionen) jener Elemente angeben, die wir auswählen möchten.
Allerdings müssen wir bei der Auswahl mehrerer Elemente die Indizes als Vektor angeben.

Hierfür nutzen wir die Funktion c().

pol_party <- c("CDU", "SPD", "B90-Gruene", "FDP", "Die Linke", "AFD")

# Ausgabe Vektor pol_party
pol_party
## [1] "CDU"        "SPD"        "B90-Gruene" "FDP"        "Die Linke" 
## [6] "AFD"
# Auswahl des 1., 2. und 3. Elements
pol_party[ c(1, 2, 3) ]
## [1] "CDU"        "SPD"        "B90-Gruene"

Wählen Sie die Elemente “CDU”, “B90-Gruene” und “Die Linke” aus.

pol_party <- c("CDU", "SPD", "B90-Gruene", "FDP", "Die Linke", "AFD")

# Auswahl "CDU", "B90-Gruene", "Die Linke"
# Auswahl "CDU", "B90-Gruene", "Die Linke"
pol_party[c(1, 3, 5)]

Wenn alle Elemente, die wir auswählen wollen, in dem Vektor direkt aufeinanderfolgen, können wir auch eine andere Schreibweise verwenden.

pol_party <- c("CDU", "SPD", "B90-Gruene", "FDP", "Die Linke", "AFD")

# Auswahl des 1., 2. und 3. Elements
pol_party[1:3]
## [1] "CDU"        "SPD"        "B90-Gruene"

: wird auch als Doppelpunkt-Operator bezeichnet und bedeutet “von-bis”. Der Doppelpunkt-Operator erzeugt einen Vektor mit einer fortlaufenden Sequenz. Das bedeutet, wir zählen von der Zahl links des Operators fortlaufend eins hoch (oder runter) bis wir die Zahl rechts des Operators erreicht haben.

Folgende Beispiele verdeutlichen, was der Doppelpunkt-Operator macht.

# Forlaufende Sequenz von 1 bis 10
1:10
##  [1]  1  2  3  4  5  6  7  8  9 10
# Fortlaufende Sequenz von 23 bis 27
23:27
## [1] 23 24 25 26 27
# Fortlaufende Sequenz von 89 bis 81
89:81
## [1] 89 88 87 86 85 84 83 82 81
# Fortlaufende Sequenz von -5 bis 5
-5:5
##  [1] -5 -4 -3 -2 -1  0  1  2  3  4  5

Nutzen Sie den Doppelpunkt-Operator, um die Elemente “SPD”, “B90-Gruene”, “FDP”, und “Die Linke” auszuwählen.
pol_party <- c("CDU", "SPD", "B90-Gruene", "FDP", "Die Linke", "AFD")

# Auswahl "SPD", "B90-Gruene", "FDP", "Die Linke"
# Auswahl "SPD", "B90-Gruene", "FDP", "Die Linke"
pol_party[2:5]

Dass der Doppelpunkt-Operator auch wirklich einen Vektor erstellt, können wir mit der Funktion is.vector() überprüfen.

Vervollständigen Sie den folgenden Code, um zu prüfen, ob alle drei Sequenzen Vektoren sind. (Führen Sie den Code dann aus.)

# Forlaufende Sequenz von 1 bis 10
is.vector(1:10)

# Fortlaufende Sequenz von 23 bis 27
23:27

# Fortlaufende Sequenz von 89 bis 81
89:81
# Forlaufende Sequenz von 1 bis 10
is.vector(1:10)

# Fortlaufende Sequenz von 23 bis 27
is.vector(23:27)

# Fortlaufende Sequenz von 89 bis 81
is.vector(89:81)

Wenn wir einen benannten Vektor haben, gibt es noch eine weitere Möglichkeit, Elemente auszuwählen.

Wir können die Namen der auszuwählenden Elemente als Vektor zwischen den eckigen Klammern angeben.

Schauen Sie sich das erste Beispiel an.

Nutzen Sie dann die Benennung des Vektors, um Woche 3 und Woche 5 auszuwählen.

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Auswahl 6. Woche
call_time_flo["Woche 6"]

# Wählen Sie Woche 3 und 5 aus
# Denken Sie daran, dass zwischen den
# eckigen Klammern ein Vektor stehen muss.
# Nutzen Sie die Funktion c(),
# um den Vektor zur Indizierung zu erstellen.
call_time_flo[c("Woche 3", "Woche 5")]

Wir haben bisher folgende Möglichkeiten zur Indizierung kennengelernt:

  1. Auswahl eines einzelnen Elements anhand des Index

  2. Auswahl mehrerer Elemente mit dem Index und c()

  3. Auswahl mehrerer Elemente mit Hilfe des Doppelpunkt-Operators :

  4. Auswahl eines einzelnen Elements anhand der Benennung

  5. Auswahl mehrerer Elemente anhand der Benennung und c()

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Auswahl anhand des Index
call_time_flo[3]
## Woche 3 
##      83
# Auswahl anhand des Index mit c()
call_time_flo[c(1, 4, 5)]
## Woche 1 Woche 4 Woche 5 
##      44     100      26
# Auswahl mit :
call_time_flo[4:6]
## Woche 4 Woche 5 Woche 6 
##     100      26      65
# Auswahl anhand Benennung
call_time_flo["Woche 5"]
## Woche 5 
##      26
# # Auswahl mit Benennung und c()
call_time_flo[c("Woche 1", "Woche 4", "Woche 6")]
## Woche 1 Woche 4 Woche 6 
##      44     100      65

Nutzen Sie nun Ihre Kenntnisse über die Indizierung von Vektoren, um herauszufinden, ob Sie mit Florence in den ersten drei Wochen länger telefoniert haben als in den letzten drei Wochen.

Erstellen Sie zunächst zwei Vektoren mit der gesamten Gesprächsdauer für die Wochen 1-3 sowie die Wochen 4-6.
Hierbei könnte die Funktion sum() hilfreich sein.

Überprüfen Sie dann, ob die Gesprächsdauer der ersten drei Wochen länger war als die der letzten drei Wochen.

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# Vektoren für Wochen 1-3 und 4-6 
flo_start <- sum()
flo_end <-
  
# Vergleich der beiden Vektoren
# Für die Indizierung macht es Sinn,
# mit ":" zu arbeiten.
call_time_flo[1:3]
call_time_flo[4:6]
# Da wir an der Gesamtdauer interessiert sind,
# berechnen wir als nächstes die Summe.
flo_start <- sum(call_time_flo[1:3])
flo_end <- sum(call_time_flo[4:6])
# Vektoren für Wochen 1-3 und 4-6 
flo_start <- sum(call_time_flo[1:3])
flo_end <- sum(call_time_flo[4:6])

# Vergleich der beiden Vektoren
flo_start > flo_end

Auswahl durch Vergleich

Manchmal möchten wir nur jene Elemente auswählen, die eine spezielle Bedingung erfüllen. In diesen Fällen kennen wir die Indizes der uns interessierenden Elemente nicht von Beginn an.

Hier helfen uns die Vergleichsoperatoren wieder weiter. Bisher haben wir nur einzelne Werte miteinander verglichen. Wir können die Vergleichsoperatoren aber auch für Vektoren nutzen.

c(3, 15, 9, 37) > 10
## [1] FALSE  TRUE FALSE  TRUE

Das Resultat dieses Vergleichs ist ein logischer Vektor, der für jedes Element des ursprünglichen (numerischen) Vektors angibt, ob die Bedingung erfüllt ist oder nicht.

Diesen logischen Vektor können wir zur Indizierung des ursprünglichen Vektors nutzen.

c(3, 15, 9, 37) > 10
## [1] FALSE  TRUE FALSE  TRUE
c(3, 15, 9, 37)[ c(3, 15, 9, 37) > 10 ]
## [1] 15 37

Es werden also nur die Elemente ausgewählt, die die Bedingung erfüllen.

Verändern Sie den folgenden Code-Block so, dass nur jene Elemente ausgewählt werden, die kleiner oder gleich 9 sind.

# Auswahl: kleiner oder gleich 9
c(3, 15, 9, 37)[ c(3, 15, 9, 37) > 10 ]
c(3, 15, 9, 37)[ c(3, 15, 9, 37) <= 9 ]

Natürlich können die Bedingungen auch komplizierter sein, zum Beispiel…

c(3, 15, 9, 37) > 10 & c(3, 15, 9, 37) < 16
## [1] FALSE  TRUE FALSE FALSE

Schauen Sie sich die beiden Ausdrücke zuerst getrennt voneinander an c(3, 15, 9, 37) > 10 und c(3, 15, 9, 37) < 16. Überlegen Sie wie die zwei logischen Vektoren aussehen, die die beiden Ausdrücke zurückgeben.

Versuchen Sie dann, Element für Elemente die beiden Ausdrücke mit dem UND-Operator miteinander zu verknüpfen. Was ist das Ergebnis, wenn Sie das erste Element des ersten logischen Vektors mit dem ersten Element des zweiten logischen Vektors mit dem UND-Operator verknüpfen?
Schauen Sie sich dann das jeweils zweite Element der beiden logischen Vektoren an, dann das dritte Element der beiden Vektoren usw.

Als Erinnerung: Nur wenn alle Ausdrücke einer UND-Verknüpfung wahr (TRUE) sind, ist auch das Resultat wahr.

c(3, 15, 9, 37)[ c(3, 15, 9, 37) > 10 & c(3, 15, 9, 37) < 16 ]
## [1] 15

Überprüfen Sie, in welchen Wochen Sie länger als 70 Minuten mit Florence telefoniert haben.
(Hierzu müssen Sie keinen neuen Vektor erstellen.)

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# In welchen Wochen lag die Dauer über 70 Min.?
call_time_flo > 70

Wir können den logischen Vektor, den wir als Resultat des Vergleichs erhalten, auch zunächst speichern und dann zur Indizierung nutzen.

Vervollständigen Sie den folgenden Code-Block, sodass nur jene Elemente des Vektors call_time_flo ausgewählt werden, die die Bedingung erfüllen.

call_time_flo <- c(44, 75, 83, 100, 26, 65)
names(call_time_flo) <- c("Woche 1", "Woche 2", "Woche 3", 
                          "Woche 4", "Woche 5", "Woche 6")

# In welchen Wochen lag die Dauer über 70 Min.?
selection_vector <- 
  
# Ausgabe von selection_vector
selection_vector
  
# Nutzen Sie selection_vector zur Indizierung
long_calls <- call_time_flo[]
long_calls  
# In welchen Wochen lag die Dauer über 70 Min.?
selection_vector <- call_time_flo > 70
  
# Ausgabe von selection_vector
selection_vector
  
# Nutzen Sie selection_vector zur Indizierung
long_calls <- call_time_flo[selection_vector]
long_calls  

Ändern von Vektoren

Wir haben bereits gesehen, dass wir einen Vektor ganz einfach überschreiben können. Wenn wir jedoch nur wenige oder gar ein einzelnes Element ändern möchten, ist es sehr umständlich, wenn wir den gesamten Vektor überschreiben.

Folgendes Beispiel verdeutlicht dies.

Angenommen wir haben 50 Studierende der Uni Potsdam nach ihrem monatlichen Einkommen gefragt und die Ergebnisse in dem Vektor student_income gespeichert.

student_income
##  [1] -900  980  650  550 1180 1100  620 1180  750  910  860  820 1150  670
## [15] 1110  620  710 1050  820  950  610 1080  870 1040 1200  620  670  560
## [29] 1060 1290 1290 1250  640  640 1010 1050  950 1000  630  560  950  720
## [43] 1300  990 1090  970  670  710  660  770

Es wäre sehr umständlich, wenn wir alle 50 Werte in einem Vektor notieren müssten, nur um das erste Element des Vektors zu korrigieren, bei dem uns bei der Dateneingabe ein Fehler unterlaufen ist.

Wir können Indizierung nutzen, um ausschließlich das erste Element zu überschreiben.

Vervollständigen Sie den Code, um dem ersten Element den richtigen Wert von 900 zuzuweisen.
Der Vektor student_income wurde für Sie bereits erstellt. Sie können also direkt mit dem Vektor arbeiten.

student_income <- c(-900, 980, 650, 550, 1180, 1100, 620, 1180, 750, 910, 860, 820, 1150, 670, 
                    1110, 620, 710, 1050, 820, 950, 610, 1080, 870, 1040, 1200, 620, 670, 560, 
                    1060, 1290, 1290, 1250, 640, 640, 1010, 1050, 950, 1000, 630, 560, 950, 720, 
                    1300, 990, 1090, 970, 670, 710, 660, 770)
# student_income wurde bereits erstellt

# Korrigieren Sie das erste Element des Vektors
student_income[] <- 900
student_income
# Setzen Sie einfach den Index
# des Elementes, das Sie ersetzen möchten,
# in die eckigen Klammern ein.
# Korrigieren Sie das erste Element des Vektors
student_income[1] <- 900
student_income

Angenommen wir hätten nicht nur bei dem ersten, sondern auch beim letzten Element einen Fehler bei der Dateneingabe gemacht.
(Der Vektor heißt nun student_income2.)

student_income2
##  [1] -900  980  650  550 1180 1100  620 1180  750  910  860  820 1150  670
## [15] 1110  620  710 1050  820  950  610 1080  870 1040 1200  620  670  560
## [29] 1060 1290 1290 1250  640  640 1010 1050  950 1000  630  560  950  720
## [43] 1300  990 1090  970  670  710  660 -770
student_income2 <- c(-900, 980, 650, 550, 1180, 1100, 620, 1180, 750, 910, 860, 820, 1150, 670, 
                    1110, 620, 710, 1050, 820, 950, 610, 1080, 870, 1040, 1200, 620, 670, 560, 
                    1060, 1290, 1290, 1250, 640, 640, 1010, 1050, 950, 1000, 630, 560, 950, 720, 
                    1300, 990, 1090, 970, 670, 710, 660, -770)

Vervollständigen Sie den Code, sodass dem ersten Element 900 und dem letzten Element 770 zugewiesen werden.

# student_income2 wurde bereits erstellt

# Korrigieren Sie das erste Element des Vektors
student_income2[] <- c()
student_income2
# Da Sie nun zwei Werte ersetzen sollen,
# müssen Sie sowohl für die Indizes als auch
# für die zu ersetzenden Werte explizit einen 
# Vektor an R übergeben.
# Nutzen Sie sowohl für die
# Indizes als auch für die zu 
# ersetzenden Werte die Funktion c().
# Korrigieren Sie das erste Element des Vektors
student_income2[c(1, 50)] <- c(900, 770)
student_income2

Schwieriger gestaltet sich die Korrektur, wenn wir den Index des zu ersetzenden Elements nicht kennen.

Angenommen wir wüssten nur, dass wir für eine der Befragten fälschlicherweise -1130 Euro, anstatt 1130 Euro eingegeben haben.

student_income3
##  [1]   900   980   650   550  1180  1100   620  1180   750   910   860
## [12]   820  1150   670  1110   620   710  1050   820   950   610 -1130
## [23]   870  1040  1200   620   670   560  1060  1290  1290  1250   640
## [34]   640  1010  1050   950  1000   630   560   950   720  1300   990
## [45]  1090   970   670   710   660   770

Nutzen Sie Ihre Kenntnisse über die Indizierung von Elementen anhand von Bedingungen, um die falsche Eingabe zu korrigieren.

Ersetzen Sie -1130 durch 1130.

student_income3 <- c(900, 980, 650, 550, 1180, 1100, 620, 1180, 750, 910, 860, 820, 1150, 670, 
                    1110, 620, 710, 1050, 820, 950, 610, 1080, 870, 1040, 1200, 620, 670, 560, 
                    1060, 1290, 1290, 1250, 640, 640, 1010, 1050, 950, 1000, 630, 560, 950, 720, 
                    1300, 990, 1090, 970, 670, 710, 660, 770)

student_income3[22] <- -1130
# student_income3 wurde bereits erstellt

# Ersetzen Sie -1130 durch 1130
student_income3[student_income3 ] <- 
student_income3
# Sie müssen zunächst die Bedingung festlegen.
# Die Bedingung schreiben Sie zwischen die eckigen Klammern
# auf der linken Seite des Zuweisungsoperators.
# Die Bedingung ist, dass das Element
# gleich -1130 sein muss.
# Korrigieren Sie das Element mit -1150
student_income3[student_income3 == -1130 ] <- 1130 
student_income3

Matrizen

Eine Matrix ist im Grunde eine rechteckige Tabelle mit Daten (Elementen), die den gleichen Datentyp haben. Ähnlich wie bei Vektoren können wir Elemente unterschiedlichen Datentyps nicht in einer Matrix speichern. R erzwingt auch hier einen einheitlichen Datentyp.

Eine Matrix hat eine bestimmte Anzahl von Zeilen (Englisch: rows) und Spalten (Englisch: columns) und wird daher als zweidimensional bezeichnet. Um eine Matrix, wie die folgende in R zu erstellen, nutzen wir die Funktion matrix().

##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16

Exkurs: Funktionen

Wir haben bereits mit Funktionen, wie etwa c(), sum() oder mean(), gearbeitet. Wenn wir eine Funktion nutzen, sprechen wir auch davon, dass wir die Funktion aufrufen.

Die Werte, die wir an die Funktion übergeben, d. h., zwischen die Klammern schreiben, heißen Argumente. Bisher haben wir meist nur einen Vektor an Funktionen übergeben. Funktionen können aber auch mehrere Argumente haben.

Wenn Sie mit Funktionen arbeiten, sollten Sie drei Dinge wissen:

  1. Wenn Sie nur den Funktionsnamen, ohne Klammern, ausführen, gibt R den Code aus, der in dieser Funktion gespeichert ist. Das ist der Code, den R ausführt, wenn Sie die Funktion aufrufen. Derzeit sagt uns dieser Code noch nicht viel. Wenn Sie beginnen, Funktionen selbst zu schreiben, ist es jedoch sehr hilfreich, sich bereits bestehende Funktionen anzuschauen und von diesen zu lernen.
sum
## function (..., na.rm = FALSE)  .Primitive("sum")

  1. Um eine Funktion auszuführen, müssen wir runde Klammern () hinter den Funktionsnamen setzen und ggf. Argumente an die Funktion übergeben.
sum(c(1, 2, 3, 4))
## [1] 10

  1. Wenn wir ein ? vor den Funktionsnamen setzen und den Code ausführen, öffnet sich die Hilfeseite für diese Funktion.

Probieren Sie es aus und schauen sich die Hilfeseite für die Funktion sum an.

# Hilfeseite für die Funktion sum
?sum
  1. Unter Usage sehen Sie die komplette Funktion mit allen Argumenten.
    Die Funktion sum hat zwei Argumente:

    • Der Vektor mit Zahlen, den wir der Funktion übergeben müssen.

    • Das Argument na.rm.

    Das Argument na.rm legt fest, wie die Funktion mit fehlenden Werten (Englisch: missing values) umgehen soll. Fehlende Werte entstehen zum Beispiel, wenn bei einer Umfrage eine Befragte auf eine Frage keine Antwort gibt.

    Argumenten wird in der Regel mit einem Gleichheitszeichen = ein Wert zugewiesen. Wenn wir beim Aufruf der Funktion einem oder mehreren Argumenten keinen Wert zuweisen, dann verwendet R den Wert für das Argument, den wir unter Usage sehen. Diesen Wert nennen wir auch Standardwert. Für das Argument na.rm der Funktion sum ist FALSE der Standardwert.

    Nicht alle Argumente haben einen Standardwert. Das erste Argument der Funktion sum (der Vektor, für den die Summe berechnet werden soll) ist ein Beispiel hierfür.

  2. Unter Arguments finden wir eine genauere Beschreibung der einzelnen Argumente einer Funktion.

  3. Darüber hinaus sind die Beispiele im Abschnitt Examples sehr hilfreich.

Erstellen einer Matrix

Schauen Sie sich zunächst nur den Abschnitt Usage auf der Hilfeseite zu matrix() an.
# Hilfeseite für die Funktion matrix()
?matrix

Die Funktion matrix() hat die Argumente data, nrow, ncol, byrow und dimnames.

  • data legt fest, mit welchen Werten die Matrix befüllt werden soll.

  • nrow legt fest, wie viele Zeilen die Matrix haben soll.

  • byrow legt fest, ob die Matrix zeilenweise mit den Werten des übergebenen Vektors befüllt werden soll oder nicht. Zeilenweise bedeutet, dass zunächst die erste Zeile von der ersten Zelle beginnend befüllt wird, dann die zweite Zeile usw. Wenn Sie byrow gleich FALSE setzen, wird zuerst die erste Spalte, dann die zweite, dritte usw. befüllt.

Vervollständigen Sie die folgende Code-Zeile, sodass

  1. eine Matrix mit 3 Zeilen erstellt wird,

  2. die zeilenweise mit Zahlen gefüllt wird.

# Erstelle Matrix

matrix(1:9, byrow = FALSE, nrow = )
# Setzen Sie 
# nrow = 3
# Ändern Sie 
# byrow = TRUE
# Erstelle Matrix

matrix(1:9, byrow = TRUE, nrow = 3)

Wenn Sie alles richtig gemacht haben, sollte Ihre Matrix wie folgende aussehen:

##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Ändern Sie den Wert für byrow zu FALSE und schauen Sie sich die Ausgabe an.

# Erstelle Matrix
matrix(1:9, byrow = TRUE, nrow = 3)
# Erstelle Matrix
matrix(1:9, byrow = FALSE, nrow = 3)

Drei Punkte gibt es anzumerken:

  1. Da FALSE der Standardwert für byrow ist, könnten wir auch das gesamte Argument hier aus unserem Code entfernen.

  2. Nicht jedes Argument muss benannt sein. In unserem Beispiel haben wir nur den Vektor mit Zahlen angegeben, ohne data = wie es auf er Hilfeseite angegeben ist.

  3. Wenn die Argumente benannt sind, müssen Sie nicht in der gleichen Reihenfolge an die Funktion übergeben werden, wie es auf der Hilfeseite aufgeführt ist. Auf der Hilfeseite für die Funktion matrix() sehen wir, dass das Argument nrow vor byrow steht.

Reihenfolge der Argumente

Wenn wir den Namen eines Argumentes nutzen, um einen Wert an eine Funktion zu übergeben, dann spielt die Reihenfolge der Argumente keine Rolle.
Wenn wir jedoch nur einen Wert, ohne den Argumentnamen, an eine Funktion übergeben, dann findet die Zuweisung über die Position statt. Wir müssen dann die Reihenfolge der Argumente beachten.

Wir können diese beiden Möglichkeiten auch kombinieren. Bei der Erstellung der Matrix haben wir die Daten (data) über die Position übergeben, während wir nrow und byrow explizit benannt haben. Normalerweise wird nur das erste Argument über die Position übergeben, die restlichen werden benannt.

Erste Analysen

Das Bundesinnenministerium veröffentlicht regelmäßig Zahlen zu Politisch motivierter Kriminalität (PMK). Bis 2016 wurden Straftaten in den drei Phänomenbereichen PMK -rechts-, PMK -links- und Politisch motivierte Ausländerkriminalität (PMAK) erfasst.

Für die Phänomenbereiche haben wir bereits drei Vektoren für das Jahr 2016 erstellt. Die erste Zahl gibt Auskunft über die Zahl politisch motivierter Gewalttaten (insbesondere Körperverletzungen und Tötungsdelikte). Die zweite Zahl bezieht sich auf die restlichen Straftaten (z. B. Propagandadelikte) im jeweiligen Phänomenbereich.

  1. Kombinieren Sie die drei Vektoren pmk_rechts, pmk_links, pmak mithilfe der Funktion c(), um den Vektor pmk_all zu erstellen.

  2. Erstellen Sie mit dem neuen Vektor pmk_all die Matrix pmk_matrix. Setzen Sie byrow = TRUE und nrow = 3.

pmk_rechts <- c(1698, 21857) 
pmk_links <- c(1702, 7687)
pmak <- c(597, 2775)

# Erstelle pmk_all
pmk_all <- c(pmk_rechts, )

# Erstelle Matrix pmk_matrix
pmk_matrix <- matrix()
pmk_matrix
# Ergänzen Sie die anderen
# beiden Vektoren in der combine-Funktion,
# um pmk_all zu erstellen.
# Erstelle pmk_all
pmk_all <- c(pmk_rechts, pmk_links, pmak)
# Erstelle pmk_matrix
pmk_matrix <- matrix(pmk_all, byrow = TRUE, nrow = 3)
# Erstelle pmk_all
pmk_all <- c(pmk_rechts, pmk_links, pmak)

# Erstelle pmk_matrix
pmk_matrix <- matrix(pmk_all, byrow = TRUE, nrow = 3)

pmk_matrix sollte wie folgt aussehen:

##      [,1]  [,2]
## [1,] 1698 21857
## [2,] 1702  7687
## [3,]  597  2775

Damit wir nicht vergessen, was wir in der Matrix gespeichert haben, können wir Zeilen und Spalten der Matrix benennen. Hierzu nutzen wir die Funktionen rownames() und colnames().

rownames(my_matrix) <- row_names_vector 
colnames(my_matrix) <- column_names_vector

Vervollständigen Sie den folgenden Code-Block:

  1. Benennen Sie die Zeilen der Matrix pmk_matrix mit dem Vektor pmk_category.

  2. Benennen Sie die Spalten der Matrix pmk_matrix mit dem Vektor pmk_crime.

  3. Lassen Sie die Matrix pmk_matrix ausgeben.

pmk_rechts <- c(1698, 21857) 
pmk_links <- c(1702, 7687)
pmak <- c(597, 2775)

# Erstelle pmk_all
pmk_all <- c(pmk_rechts, pmk_links, pmak)

# Erstelle Matrix pmk_matrix
pmk_matrix <- matrix(pmk_all, byrow = TRUE, nrow = 3)

# Vektoren für Benennung
pmk_category <- c("PMK -rechts-", "PMK -links-", "PMAK")
pmk_crime <- c("Gewalttaten", "restliche Straftaten")

# Benennen Sie die Zeilen mit pmk_category

# Benennen Sie die Spalten mit pmk_crime

# Geben Sie pmk_matrix aus
# Benennen Sie die Zeilen mit pmk_category
rownames(pmk_matrix) <- pmk_category
# Benennen Sie die Spalten mit pmk_crime
colnames(pmk_matrix) <- pmk_crime
# Geben Sie pmk_matrix aus
pmk_matrix
# Benennen Sie die Zeilen mit pmk_category
rownames(pmk_matrix) <- pmk_category

# Benennen Sie die Spalten mit pmk_crime
colnames(pmk_matrix) <- pmk_crime

# Geben Sie pmk_matrix aus
pmk_matrix

pmk_matrix sollte jetzt wie folgt aussehen:

##              Gewalttaten restliche Straftaten
## PMK -rechts-        1698                21857
## PMK -links-         1702                 7687
## PMAK                 597                 2775

Als Erstes möchten wir die Gesamtzahl an Straftaten für jeden Phänomenbereich berechnen (d. h. Gewalttaten plus die restlichen Straftaten).

Hierfür können wir die Funktion rowSums() nutzen, die für eine Matrix die Zeilensummen berechnet. Das bedeutet, alle Zahlen einer Zeile werden addiert. Das Resultat ist ein Vektor, der genau so viele Elemente hat wie die Ausgangsmatrix Zeilen.

  1. Berechnen Sie mit rowSums() die Zeilensummen für pmk_matrix und speichern Sie das Ergebnis in pmk_category_total.

  2. Überprüfen Sie dann, ob es sich bei pmk_category_total wirklich um einen Vektor handelt.

# Erstelle pmk_all
pmk_all <- c(1698, 21857, 1702, 7687, 597, 2775)

# Erstelle pmk_matrix mit
# Zeilen- und Spaltennamen
pmk_matrix <- matrix(pmk_all, nrow = 3, byrow = TRUE, 
                     dimnames = list(c("PMK -rechts-", "PMK -links-", "PMAK"),
                                     c("Gewalttaten", "restliche Straftaten")))

# Berechne Zeilensummen
# (für Phänomenbereiche)
pmk_category_total <- 

# Ist pmk_category_total ein Vektor?
is.vector()

# Ausgabe der Original-Matrix
# und des Zeilensummenvektors
pmk_matrix
pmk_category_total
# Übergeben Sie die Matrix pmk_matrix
# an die Funktion rowSums()
pmk_category_total <- rowSums()
# Übergeben Sie die Matrix pmk_matrix
# an die Funktion rowSums()
pmk_category_total <- rowSums(pmk_matrix)
# Ist pmk_category_total ein Vektor?
is.vector(pmk_category_total)

Wenn Sie alles richtig gemacht haben, enthält pmk_category_total die Zahlen 23555, 9389 und 3372.

In der vorherigen Aufgabe haben Sie einen Vektor mit Zeilensummen erstellt und somit neue Daten.
Es macht natürlich Sinn, wenn wir diese neuen Daten zusammen mit der Originalmatrix speichern.

Wir können die Funktion cbind() (column bind) nutzen, um einer Matrix eine oder mehrere Spalten hinzuzufügen.
cbind() führt Matrizen oder Vektoren spaltenweise zusammen.

matrix_1 <- matrix(1:4, nrow = 2, byrow = TRUE)
vector_1 <- 5:6

# Column bind matrix_1 und vector_1
matrix_2 <- cbind(matrix_1, vector_1)
matrix_2
##          vector_1
## [1,] 1 2        5
## [2,] 3 4        6

Beachten Sie, dass die neue Spalte entsprechend dem Vektornamen benannt ist.

Erstellen Sie eine neue Matrix pmk_mat_total, indem Sie pmk_matrix und pmk_category_total zusammenführen. pmk_category_total soll die dritte Spalte der neuen Matrix bilden.

# Erstelle pmk_all
pmk_all <- c(1698, 21857, 1702, 7687, 597, 2775)

# Erstelle pmk_matrix mit
# Zeilen- und Spaltennamen
pmk_matrix <- matrix(pmk_all, nrow = 3, byrow = TRUE, 
                     dimnames = list(c("PMK -rechts-", "PMK -links-", "PMAK"),
                                     c("Gewalttaten", "restliche Straftaten")))

# Berechne Zeilensummen
# (für Phänomenbereiche)
pmk_category_total <- rowSums(pmk_matrix)

# Führen Sie pmk_matrix und pmk_category_total 
# zur Matrix pmk_mat_total zusammen.
pmk_mat_total <- cbind()
pmk_mat_total
# Führen Sie pmk_matrix und pmk_category_total 
# zur Matrix pmk_mat_total zusammen.
pmk_mat_total <- cbind(pmk_matrix, pmk_category_total)

Die Matrix pmk_mat_total sollte wie folgt aussehen.

##              Gewalttaten restliche Straftaten pmk_category_total
## PMK -rechts-        1698                21857              23555
## PMK -links-         1702                 7687               9389
## PMAK                 597                 2775               3372

Äquivalent zu cbind() gibt es die Funktion rbind().

  • rbind() führt Matrizen oder Vektoren zeilenweise zusammen.
matrix_1 <- matrix(1:4, nrow = 2, byrow = TRUE)
vector_1 <- 5:6

# Column bind matrix_1 und vector_1
matrix_2 <- rbind(matrix_1, vector_1)
matrix_2
##          [,1] [,2]
##             1    2
##             3    4
## vector_1    5    6

Während rbind() cbind() ergänzt, übernimmt diese Rolle bei rowSums() die Funktion colSums().

  • colSums() berechnet für eine Matrix die Spaltensummen.
matrix_1 <- matrix(1:4, nrow = 2, byrow = TRUE)
matrix_1
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
colSums(matrix_1)
## [1] 4 6

Vervollständigen Sie den folgenden Code-Block:

  1. Berechnen Sie die Spaltensummen für pmk_mat_total und weisen Sie sie pmk_crime_total zu.

  2. Fügen Sie pmk_crime_total als neue, dritte Zeile zu pmk_mat_total. Erstellen Sie keine neue Matrix, sondern überschreiben Sie pmk_mat_total.

# Erstelle pmk_mat_total
pmk_all <- c(1698, 21857, 1702, 7687, 597, 2775)
pmk_matrix <- matrix(pmk_all, nrow = 3, byrow = TRUE, 
                     dimnames = list(c("PMK -rechts-", "PMK -links-", "PMAK"),
                                     c("Gewalttaten", "restliche Straftaten")))

pmk_category_total <- rowSums(pmk_matrix)
pmk_mat_total <- cbind(pmk_matrix, pmk_category_total)

# Berechne Spaltensummen für pmk_mat_total 
pmk_crime_total <- 

# Füge neue Zeile zu pmk_mat_total hinzu
pmk_mat_total <- rbind()
pmk_mat_total
# Berechne Spaltensummen für pmk_mat_total 
pmk_crime_total <- colSums(pmk_mat_total)
# Achten Sie auf die Reihenfolge
# der an rbind() übergebenen Obejekte.
pmk_mat_total <- rbind()
# Füge neue Zeile zu pmk_mat_total hinzu
pmk_mat_total <- rbind(pmk_mat_total, pmk_crime_total)
# Berechne Spaltensummen für pmk_mat_total 
pmk_crime_total <- colSums(pmk_mat_total)

# Füge neue Zeile zu pmk_mat_total hinzu
pmk_mat_total <- rbind(pmk_mat_total, pmk_crime_total)

Die Matrix pmk_mat_total sollte jetzt wie folgt aussehen.

##                 Gewalttaten restliche Straftaten pmk_category_total
## PMK -rechts-           1698                21857              23555
## PMK -links-            1702                 7687               9389
## PMAK                    597                 2775               3372
## pmk_crime_total        3997                32319              36316

Indizierung von Matrizen

Wie bei der Indizierung von Vektoren können wir zur Indizierung von Matrizen die eckigen Klammern [] nutzen. Allerdings haben wir bei Matrizen zwei Dimensionen, Zeilen und Spalten.

Diese beiden Dimensionen werden innerhalb der eckigen Klammern durch ein Komma getrennt. An erster Stelle steht der Zeilenindex, und an zweiter Stelle der Spaltenindex.

my_matrix[Zeilenindex, Spaltenindex]

Wenn wir zum Beispiel das Element in der ersten Zeile und dritten Spalte auswählen wollen, funktioniert das wie folgt:

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl
my_matrix[1,3]
## [1] 3

Wählen Sie die Zahl 10 aus der Matrix my_matrix aus.

my_matrix <- matrix(c(1:16), byrow = TRUE, nrow = 4)
my_matrix[]
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
my_matrix <- matrix(c(1:16), byrow = TRUE, nrow = 4)
# Auswahl
my_matrix[]
# Auswahl
my_matrix[3, 2]

Wir können auch mehrere Elemente gleichzeitig auswählen. Hierfür nutzen wir Vektoren für den jeweiligen Index.

Wenn wir nur die ersten beiden Zeilen und für diese nur die ersten beiden Spalten auswählen wollen, schreiben wir:

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl
my_matrix[c(1,2), c(1,2)]
##      [,1] [,2]
## [1,]    1    2
## [2,]    4    5

Natürlich können wir hier auch den Doppelpunktoperator nutzen.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix[1:2, 1:2]
##      [,1] [,2]
## [1,]    1    2
## [2,]    4    5

Wählen Sie für die zweite und dritte Zeile die Elemente in den Spalten zwei bis vier aus my_matrix aus.

##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
my_matrix <- matrix(c(1:16), byrow = TRUE, nrow = 4)
# Auswahl
my_matrix[]
# Auswahl
my_matrix[2:3, 2:4]

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##      [,1] [,2] [,3]
## [1,]    6    7    8
## [2,]   10   11   12

Wenn wir die Position für den Zeilen- oder Spaltenindex leer lassen (das Komma darf nicht fehlen) werden alle Zeilen bzw. Spalten ausgewählt.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl erste Spalte (alle Zeilen)
my_matrix[ ,1]
## [1] 1 4 7
my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl zweite Zeile (alle Spalten)
my_matrix[2, ]
## [1] 4 5 6

Wählen Sie für die erste und dritte Zeile alle Spalten aus.

##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
my_matrix <- matrix(c(1:16), byrow = TRUE, nrow = 4)

# Auswahl 1. und 3. Zeile (alle Spalten)
my_matrix[]
# Auswahl 1. und 3. Zeile (alle Spalten)
my_matrix[c(1, 3), ]

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    9   10   11   12

Bei einer Matrix mit Zeilen- und Spaltennamen können wir auch die Namen zur Indizierung nutzen.

Wählen Sie nur die Gewalttaten für PMK - rechts- aus.
(Vergessen Sie die Anführungszeichen nicht!)

# Erstelle pmk_mat_total
pmk_all <- c(1698, 21857, 1702, 7687, 597, 2775)
pmk_matrix <- matrix(pmk_all, nrow = 3, byrow = TRUE, 
                     dimnames = list(c("PMK -rechts-", "PMK -links-", "PMAK"),
                                     c("Gewalttaten", "restliche Straftaten")))
# Auswahl
pmk_matrix[ , ]
             Gewalttaten restliche Straftaten
PMK -rechts-        1698                21857
PMK -links-         1702                 7687
PMAK                 597                 2775
# Setzen den entsprechenden Zeilennamen an erste Position
# und den Spaltennamen an zweite Position.
pmk_matrix["PMK -rechts-" , ]
pmk_matrix["PMK -rechts-" , "Gewalttaten"]

Die Ausgabe sollte die Zahl 1698 zeigen.

Auswahl anhand von Bedingungen

Darüber hinaus können wir auch Bedingungen nutzen, um Matrixelemente auszuwählen.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)

my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Welche Elemente sind größer
# oder gleich 5?
my_matrix >= 5
##       [,1]  [,2]  [,3]
## [1,] FALSE FALSE FALSE
## [2,] FALSE  TRUE  TRUE
## [3,]  TRUE  TRUE  TRUE

Wenn wir die Bedingung in die eckigen Klammern setzen, wählen wir jene Elemente aus, die diese Bedingung erfüllen.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl aller Elemente größer oder gleich 5.
my_matrix[my_matrix >= 5]
## [1] 7 5 8 6 9

Diese Aufgabe ist ein bisschen schwieriger.

Wählen Sie alle Elemente der nachstehenden Matrix aus, die gerade Zahlen sind.

Tipp: Der Modulo-Operator %% ist hier hilfreich.
Modulo berechnet den Rest bei einer Division.

my_matrix
##      [,1] [,2] [,3] [,4]
## [1,]   15   16    3   14
## [2,]   10    2    6    5
## [3,]    4   12    7    1
## [4,]   11   13    8    9
my_matrix %% 2
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    1    0
## [2,]    0    0    0    1
## [3,]    0    0    1    1
## [4,]    1    1    0    1
set.seed(123)
my_matrix <- matrix(sample(1:16, 16), byrow = TRUE, nrow = 4)

# Auswahl: alle geraden Zahlen
my_matrix %% 2
my_matrix[]
# Zunächst müssen wir 
# die Bedingung formulieren.

# Wenn bei der Division durch 2 kein Rest
# bleibt, dann handelt es sich um eine gerade Zahl.
# Wenn bei der Division durch 2 kein Rest
# bleibt, dann handelt es sich um eine gerade Zahl.

# Die gesuchte Bedingung ist also:
my_matrix %% 2 == 0
# Auswahl: alle geraden Zahlen
my_matrix[my_matrix %% 2 == 0]

Auswahl anhand von Bedingungen (Fortgeschritten)

Manchmal möchten wir eine Bedingung nicht auf die gesamte Matrix anwenden, sondern nur auf einen Teil, zum Beispiel auf eine Spalte.

Schauen wir uns zunächst an, wie wir einen Teil einer Matrix mithilfe von logicals auswählen können.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl: 1. und 3. Zeile und 2. und 3. Spalte
my_matrix[c(TRUE, FALSE, TRUE), c(FALSE, TRUE, TRUE)]
##      [,1] [,2]
## [1,]    2    3
## [2,]    8    9

Nutzen Sie logische Werte, um für die dritte und vierte Zeile die erste und zweite Spalte auszuwählen.

my_matrix <- matrix(c(1:16), byrow = TRUE, nrow = 4)

# Auswahl: 3. und 4. Zeile und 1. und 2. Spalte
my_matrix[]
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
# Auswahl: 3. und 4. Zeile und 1. und 2. Spalte
my_matrix[c(FALSE, FALSE, TRUE, TRUE), c(TRUE, TRUE, FALSE, FALSE)]

Manchmal möchten wir alle Zeilen auswählen, die in einer bestimmten Spalte eine Bedingung erfüllen.

Angenommen wir wollen für folgende Matrix alle Zeilen auswählen, die in der zweiten Spalte einen Wert von kleiner oder gleich 5 haben.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)
my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Fangen wir mit der Bedingung an.

Vervollständigen Sie die Bedingung und führen Sie den Code aus.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)

# Bedingung: Spalte 2 kleiner oder gleich 5
my_matrix[ , ] <= 
# Bedingung: Spalte 2 kleiner oder gleich 5
my_matrix[ , 2] <= 5

Wie Sie gesehen haben, gibt uns R einen Vektor mit logischen Werten zurück. Das erste, zweite, dritte, … Element dieses Vektors gibt Auskunft darüber, ob die erste, zweite, dritte Zeile der zweiten Spalte die Bedingung erfüllt.

Vervollständigen Sie mithilfe des Vektors row_selection den folgenden Code-Block, sodass nur jene Zeilen der Matrix ausgewählt werden, die die Bedingung erfüllen. Alle Spalten sollen beibehalten werden.

my_matrix <- matrix(c(1:9), byrow = TRUE, nrow = 3)

# Bedingung: Spalte 2 kleiner oder gleich 5
row_selection <- my_matrix[ , 2] <= 5

# Auswahl der Zeilen
my_matrix[,]
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl der Zeilen
my_matrix[row_selection, ]

Sehr gut!
Sie haben den Abschnitt Matrizen erfolgreich absolviert!



Data frames

Matrizen sind hilfreich, wenn wir Daten haben, die wir nicht in einem einzigen Vektor speichern können. Allerdings müssen die Daten, die wir in einer Matrix speichern, alle den gleichen Datentyp haben (numeric, character oder logical).

Oft haben wir jedoch Daten unterschiedlichen Datentyps, die wir zusammen speichern möchten. In Umfragen haben wir etwa so unterschiedliche Variablen wie:

  • Alter in Jahren, Einkommen, Zahl der im Haushalt lebenden Kinder (numeric)
  • Staatsangehörigkeit, Wohnort, Beruf (character)

Um Daten unterschiedlichen Datentyps in einem rechteckigen Format (Tabelle) zu speichern, nutzen wir data frames.

Erstellen von data frames

Wir können die Funktion data.frame() nutzen, um einen data frame “per Hand” zu erstellen. Alles, was wir dazu machen müssen, ist der Funktion die Vektoren zu übergeben, die wir in dem data frame speichern möchten.

# Erstelle Vektoren
state <- c("BW", "BB", "HH", "NW", "SN")
income <- c(2857, 2647, 1494, 3394, 2612)
var_42 <- c(TRUE, FALSE, TRUE, TRUE, FALSE)
xfce <- c(2, 0, 0, 3, 1)

# Erstelle data frame
my_first_df <- data.frame(state, income, var_42, xfce, stringsAsFactors = FALSE)

# Ausgabe my_first_df
my_first_df
##   state income var_42 xfce
## 1    BW   2857   TRUE    2
## 2    BB   2647  FALSE    0
## 3    HH   1494   TRUE    0
## 4    NW   3394   TRUE    3
## 5    SN   2612  FALSE    1

Mit dem Argument stringsAsFactors = FALSE geben wir an, dass character-Vektoren nicht zu Faktor-Variablen umgewandelt werden sollen. Faktoren sind Variablen, die nur eine begrenzte Anzahl unterschiedlicher Werte annehmen können.

Sie sehen, dass die Spaltennamen des data frames den jeweiligen Vektornamen entsprechen. Die Benennung der dritten und vierten Spalte (var_42 und xfce) macht jedoch wenig Sinn.

Als Nächstes lernen Sie zwei Möglichkeiten kennen, wie wir die Spaltennamen ändern können, ohne die Namen der Original-Vektoren zu ändern.

  1. Wir können die Spalten direkt in der Funktion data.frame() benennen. Im folgenden Beispiel ändern wir den Spaltennamen für vector_1 indem wir den gewünschten Namen und ein Gleichheitszeichen (new_name_1 =) vor vector_1 schreiben.
# Erstelle Vektoren
vector_1 <- c("a", "b", "c")
vector_2 <- c(1, 2, 3)

# Erstelle data frame
df_new <- data.frame(new_name_1 = vector_1, new_name_2 = vector_2, stringsAsFactors = FALSE)

# Ausgabe df_new
df_new
##   new_name_1 new_name_2
## 1          a          1
## 2          b          2
## 3          c          3

  1. Wir können die Funktion names() nutzen, um die Spaltennamen nachträglich zu verändern.
# Erstelle Vektoren
vector_1 <- c("a", "b", "c")
vector_2 <- c(1, 2, 3)

# Erstelle data frame
df_new <- data.frame(vector_1, vector_2, stringsAsFactors = FALSE)

# Ausgabe df_new 
# vor Umbenennung der Spalten
df_new
##   vector_1 vector_2
## 1        a        1
## 2        b        2
## 3        c        3
# Weise neue Spaletnnamen zu
names(df_new) <- c("new_name_1", "new_name_2")

# Ausgabe df_new
# nach Umbenennung der Spalten
df_new
##   new_name_1 new_name_2
## 1          a          1
## 2          b          2
## 3          c          3

Die Vektoren state, income, var_42 und xfce wurden für Sie bereits erstellt. Das bedeutet, Sie können diese Vektoren direkt in Ihrer Übung nutzen.

# Erstelle Vektoren
state <- c("BW", "BB", "HH", "NW", "SN")
income <- c(2857, 2647, 1494, 3394, 2612)
var_42 <- c(TRUE, FALSE, TRUE, TRUE, FALSE)
xfce <- c(2, 0, 0, 3, 1)
state <- c("BW", "BB", "HH", "NW", "SN")
income <- c(2857, 2647, 1494, 3394, 2612)
var_42 <- c(TRUE, FALSE, TRUE, TRUE, FALSE)
xfce <- c(2, 0, 0, 3, 1)

Erstellen Sie den data frame my_first_df, sodass

  1. die Spaltennamen für die Vektoren state und income unverändert bleiben (d. h. state und income)

  2. der Spaltenname für var_42 zu married und jener für xfce zu children geändert wird

Lassen Sie danach den data frame ausgeben.

# Erstelle data frame
my_first_df <- data.frame(state, income, var_42, xfce, stringsAsFactors = FALSE)

# Ausgabe my_first_df
my_first_df

Der von Ihnen erstellte data frame sollte wie der folgende data frame aussehen.

##   state income married children
## 1    BW   2857    TRUE        2
## 2    BB   2647   FALSE        0
## 3    HH   1494    TRUE        0
## 4    NW   3394    TRUE        3
## 5    SN   2612   FALSE        1

SIPRI data frame

Die Arms Transfers Database des Stockholm International Peace Research Instiute (SIPRI) enthält Informationen zu internationalen Transfers konventioneller Waffen.

Drei Vektoren zum Umfang des Exports konventioneller Waffen wurden für Sie bereits angelegt:

  • country: Ländername
  • vector_1: Umfang des Exports in Millionen SIPRI TIV (TIV: trend-indicator value) für das Jahr 2017
  • vector_2: Umfang des Exports in Millionen SIPRI TIV (TIV: trend-indicator value) für das Jahr 2018

Erstellen Sie mit diesen drei Vektoren einen data frame und weisen diesen sipri_data zu.
Berücksichtigen Sie beim Erstellen des data frames die folgenden Vorgaben:

  1. Der Vektor country soll die erste Spalte, vector_1 die zweite und vector_2 die dritte Spalte von sipri_data bilden.
  2. Benennen Sie die Spalten von sipri_data der Reihe nach (d. h. erste, zweite, dritte Spalte) wie folgt: country, exports_17, exports_18

Beachten Sie, dass Ihr Code keine Ausgabe erzeugt.

vector_1 <- c(98, 22, 50, 12, 47, 30, 64, 1227, 10, 0, 3, 98, 20, 4, 0, 58, 2302, 7, 1980, 30, 56, 94, 20, 1254, 
             802, 2, 80, 5, 1132, 4, 153, 7, 3, 15, 56, 0, 5741, 2, 22, 103, 751, 820, 84, 184, 2, 2, 245, 103, 
             293, 1235, 12485)

vector_2 <- c(38, 5, 56, 16, 111, 7, 84, 1040, 0, 1, 0, 64, 27, 0, 2, 68, 1768, 0, 1277, 0, 46, 
             15, 0, 707, 611, 3, 0, 0, 369, 6, 64, 0, 2, 21, 3, 3, 6409, 0, 12, 149, 1083, 1188, 134, 243, 0, 0, 
             364, 113, 224, 741, 10508)

country <- c("Australia", "Austria", "Belarus", "Belgium", "Brazil", "Bulgaria", "Canada", "China", "Colombia",
             "Cote d'Ivoire", "Croatia", "Czechia", "Denmark", "Dominican Republic", "Ecuador", "Finland", 
             "France", "Georgia", "Germany", "Greece", "India", "Indonesia", "Iran", "Israel", "Italy", "Japan", 
             "Jordan", "Kyrgyzstan", "Netherlands", "New Zealand", "Norway", "Oman", "Pakistan", "Poland", "Portugal", 
             "Qatar", "Russia", "Serbia", "Slovakia", "South Africa", "South Korea", "Spain", "Sweden", "Switzerland", 
             "Taiwan", "Thailand", "Turkey", "UAE", "Ukraine", "United Kingdom", "United States")
exports_17 <- c(98, 22, 50, 12, 47, 30, 64, 1227, 10, 0, 3, 98, 20, 4, 0, 58, 2302, 7, 1980, 30, 56, 94, 20, 1254, 
             802, 2, 80, 5, 1132, 4, 153, 7, 3, 15, 56, 0, 5741, 2, 22, 103, 751, 820, 84, 184, 2, 2, 245, 103, 
             293, 1235, 12485)

exports_18 <- c(38, 5, 56, 16, 111, 7, 84, 1040, 0, 1, 0, 64, 27, 0, 2, 68, 1768, 0, 1277, 0, 46, 
             15, 0, 707, 611, 3, 0, 0, 369, 6, 64, 0, 2, 21, 3, 3, 6409, 0, 12, 149, 1083, 1188, 134, 243, 0, 0, 
             364, 113, 224, 741, 10508)

country <- c("Australia", "Austria", "Belarus", "Belgium", "Brazil", "Bulgaria", "Canada", "China", "Colombia",
             "Cote d'Ivoire", "Croatia", "Czechia", "Denmark", "Dominican Republic", "Ecuador", "Finland", 
             "France", "Georgia", "Germany", "Greece", "India", "Indonesia", "Iran", "Israel", "Italy", "Japan", 
             "Jordan", "Kyrgyzstan", "Netherlands", "New Zealand", "Norway", "Oman", "Pakistan", "Poland", "Portugal", 
             "Qatar", "Russia", "Serbia", "Slovakia", "South Africa", "South Korea", "Spain", "Sweden", "Switzerland", 
             "Taiwan", "Thailand", "Turkey", "UAE", "Ukraine", "United Kingdom", "United States")

sipri_data <- data.frame(country, exports_17, exports_18 , stringsAsFactors = FALSE)

rm(list = c("exports_17", "exports_18", "country"))
exports_17 <- c(98, 22, 50, 12, 47, 30, 64, 1227, 10, 0, 3, 98, 20, 4, 0, 58, 2302, 7, 1980, 30, 56, 94, 20, 1254, 
             802, 2, 80, 5, 1132, 4, 153, 7, 3, 15, 56, 0, 5741, 2, 22, 103, 751, 820, 84, 184, 2, 2, 245, 103, 
             293, 1235, 12485)

exports_18 <- c(38, 5, 56, 16, 111, 7, 84, 1040, 0, 1, 0, 64, 27, 0, 2, 68, 1768, 0, 1277, 0, 46, 
             15, 0, 707, 611, 3, 0, 0, 369, 6, 64, 0, 2, 21, 3, 3, 6409, 0, 12, 149, 1083, 1188, 134, 243, 0, 0, 
             364, 113, 224, 741, 10508)

country <- c("Australia", "Austria", "Belarus", "Belgium", "Brazil", "Bulgaria", "Canada", "China", "Colombia",
             "Cote d'Ivoire", "Croatia", "Czechia", "Denmark", "Dominican Republic", "Ecuador", "Finland", 
             "France", "Georgia", "Germany", "Greece", "India", "Indonesia", "Iran", "Israel", "Italy", "Japan", 
             "Jordan", "Kyrgyzstan", "Netherlands", "New Zealand", "Norway", "Oman", "Pakistan", "Poland", "Portugal", 
             "Qatar", "Russia", "Serbia", "Slovakia", "South Africa", "South Korea", "Spain", "Sweden", "Switzerland", 
             "Taiwan", "Thailand", "Turkey", "UAE", "Ukraine", "United Kingdom", "United States")

nato_member <- c(0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0,
          1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1)

sipri_data <- data.frame(country, exports_17, exports_18, nato_member, stringsAsFactors = FALSE)

rm(list = c("exports_17", "exports_18", "country", "nato_member"))
# Bereits erstellte Vektoren:
# country, vector_1, vector_2

sipri_data <- data.frame( , stringsAsFactors = FALSE)
# Bereits erstellte Vektoren:
# country, vector_1, vector_2

sipri_data <- data.frame(country, exports_17 = vector_1, exports_18 = vector_2, stringsAsFactors = FALSE)

Oft haben wir Datensätze mit mehreren hundert oder tausend Beobachtungen (Zeilen). Für diese Datensätze macht es keinen Sinn, den kompletten data frame ausgeben zu lassen. Es gibt jedoch ein paar Funktionen, die uns Auskunft über einen data frame geben.

Mit der Funktion str() (structure) können wir uns die Struktur eines Datensatzes anschauen.

Probieren Sie es aus. Der data frame sipri_data wurde bereits für Sie erstellt. Sie müssen den data frame nur noch an die Funktion übergeben.

# sipri_data wurde bereits erstellt

# Schauen Sie sich die Struktur von
# sipri_data an.
# Schauen Sie sich die Struktur von
# sipri_data an.
str(sipri_data)

Wichtig: R-Anfänger_innen denken oft, dass es sich bei str() um eine string-Funktion handelt. Machen Sie diesen Fehler nicht!

Wie wir der Ausgabe entnehmen können, hat sipri_data 51 Beobachtungen (“51 obs.”) und 3 Variablen.
Darunter erhalten wir für jede der Variablen den Namen, den Datentyp (hier chr und num) und jeweils die Einträge der ersten Zeilen für diese Variablen.

Es gibt noch zwei weitere Funktionen, die häufig genutzt werden, um einen ersten Eindruck eines Datensatzes zu erhalten.

  • head() gibt den ersten Teil des Datensatzes aus.

  • tail() gibt den letzten Teil des Datensatzes aus.

Übergeben Sie den data frame sipri_data wie bei str() an die beiden Funktionen.
# sipri_data wurde bereits erstellt


# Schauen Sie sich den ersten Teil
# von sipri_data an.
head()

# Schauen Sie sich den letzten Teil
# von sipri_data an.
# Schauen Sie sich den ersten Teil
# von sipri_data an.
head(sipri_data)
# Schauen Sie sich den letzten Teil
# von sipri_data an.
tail(sipri_data)

Während head() standardmäßig die ersten sechs Zeilen des Datensatzes anzeigt, zeigt tail() die letzten sechs Zeilen. Die Zahlen links neben den Ländernamen sind die jeweiligen Zeilennummern.

Da Sie mittlerweile schon geübte R-Nutzer_innen sind, schauen Sie sich zunächst die Hilfeseite zu head() oder tail() an. Beiden Funktionen haben die gleiche Hilfeseite.

Passen Sie dann den Code aus der vorherigen Aufgabe so an, dass die ersten bzw. letzten 10 Zeilen des Datensatzes ausgegeben werden.

# sipri_data wurde bereits erstellt

# Hilfeseite aufrufen


# Ausgabe: erste 10 Zeilen mit head()


# Ausgabe: letzte 10 Zeilen mit tail()
# Um die Hilfeseite aufzurufen,
# geben Sie ein Fragenzeichen gefolgt 
# von dem Funktionsnamen ein (ohne Klammern).
# Hilfeseite aufrufen
?head
# Das Argument n kontrolliert,
# wie viele Zeilen ausgegeben werden.
# Ausgabe: erste 10 Zeilen mit head()
head(sipri_data, n = 10)
# Ausgabe: letzte 10 Zeilen mit tail()
tail(sipri_data, n = 10)

Indizierung von data frames

Bei der Auswahl von Elementen eines data frames können wir wie bei einer Matrix vorgehen und die eckigen Klammern [] nutzen. Denken Sie daran, an erster Stelle in den eckigen Klammern steht der Zeilenindex. Der Spaltenindex steht an zweiter Stelle. Zwischen Zeilen- und Spaltenindex steht ein Komma.

Wenn wir etwa nur die erste und dritte Spalte auswählen möchten, können wir das wie folgt machen.

sipri_subset <- sipri_data[ , c(1,3)]
head(sipri_subset)
##     country exports_18
## 1 Australia         38
## 2   Austria          5
## 3   Belarus         56
## 4   Belgium         16
## 5    Brazil        111
## 6  Bulgaria          7

Natürlich gilt das auch für die Indizierung der Zeilen. Im folgenden Beispiel werden die ersten zwölf Zeilen (1:12) und die erste und dritte Spalte ausgewählt.

sipri_data[1:12, c(1,3)]
##          country exports_18
## 1      Australia         38
## 2        Austria          5
## 3        Belarus         56
## 4        Belgium         16
## 5         Brazil        111
## 6       Bulgaria          7
## 7         Canada         84
## 8          China       1040
## 9       Colombia          0
## 10 Cote d'Ivoire          1
## 11       Croatia          0
## 12       Czechia         64

Auswahl mit Spaltennamen

Wie bei Matrizen können wir auch bei data frames Spalten anhand deren Benennung auswählen. Bei data frames sind die Variablennamen die Spaltennamen, die wir mit der Funktion names()anzeigen lassen können.

names(sipri_data)
## [1] "country"    "exports_17" "exports_18"

Nutzen Sie nur die Variablennamen, um die Variablen country und exports_17 auszuwählen. Weisen Sie diese beiden Spalten sipri_subset zu und lassen Sie mit der Funktion head() die ersten zehn Zeilen von sipri_subset ausgeben.

# sipri_data wurde bereits erstellt

# Auswahl 1. und 2. Spalte

# Ausgabe erste 10 Zeilen von sipri_subset
# Auswahl 1. und 2. Spalte
sipri_subset <- sipri_data[ , c("country", "exports_17")]
# Ausgabe erste 10 Zeilen von sipri_subset
head(sipri_subset, n = 10)
# Auswahl 1. und 2. Spalte
sipri_subset <- sipri_data[ , c("country", "exports_17")]

# Ausgabe erste 10 Zeilen von sipri_subset
head(sipri_subset, n = 10)

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##          country exports_17
## 1      Australia         98
## 2        Austria         22
## 3        Belarus         50
## 4        Belgium         12
## 5         Brazil         47
## 6       Bulgaria         30
## 7         Canada         64
## 8          China       1227
## 9       Colombia         10
## 10 Cote d'Ivoire          0

Wie wir bereits von Matrizen wissen, sind folgende Befehle äquivalent.

sipri_data[, 1]
sipri_data[, "country"]

Wir können das auch überprüfen:

sipri_data[, 1] == sipri_data[, "country"]
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [15] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [29] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [43] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Oder kompakter:

all(sipri_data[, 1] == sipri_data[, "country"])
## [1] TRUE

Die Funktion all() überprüft, ob alle Elemente, die an die Funktion übergeben werden, den Wert TRUE haben. Wenn ein einziges Element den Wert FALSE hat, gibt die Funktion den Wert FALSE zurück.

Für data frames gibt es allerdings noch eine weitere Möglichkeit, Spalten auszuwählen.

Auswahl mit $

Bei der Ausgabe von str() haben wir gesehen, dass die Zeilen mit den Variableninformationen mit einem $ beginnen.

str(sipri_data)
## 'data.frame':    51 obs. of  3 variables:
##  $ country   : chr  "Australia" "Austria" "Belarus" "Belgium" ...
##  $ exports_17: num  98 22 50 12 47 ...
##  $ exports_18: num  38 5 56 16 111 7 84 1040 0 1 ...

Um eine bestimmte Variable aus einem data frame auszuwählen, können wir $Variablenname direkt hinter den Namen des Datensatzes schreiben. Ersetzen Sie dafür Variablenname einfach durch den Namen jener Variable, die Sie auswählen möchten.

Das sieht dann wie folgt aus:

my_df <- data.frame(x = c(4, 7, 9),
                    y = c(TRUE, FALSE, FALSE),
                    z = c("green", "red", "blue"), stringsAsFactors = FALSE)

my_df$x
## [1] 4 7 9

Nutzen Sie das $-Zeichen, um die Spalte country aus sipri_dataauszuwählen.

# sipri_data wurde bereits erstellt

# Auswahl der Variable country
# Setzen Sie $country direkt
# hinter den Namen des Datensatzes.
# Auswahl der Variable country
sipri_data$country

Wenn wir eine Variable (Spalte) auswählen, ist das dann überhaupt noch ein data frame?

Prüfen Sie es einfach. Nutzen Sie hierzu die Variable sipri_data$country und die Funktion is.data.frame().

# sipri_data wurde bereits erstellt

# Ist sipri_data$country ein data frame?  
# Setzen Sie die ausgewählte Variable
# zwischen die Klammern.
# Ist sipri_data$country ein data frame?
is.data.frame(sipri_data$country)

Überzeugen Sie sich mit der Funktion is.vector() davon, dass sipri_data$country ein Vektor ist.

# sipri_data wurde bereits erstellt

# Ist sipri_data$country ein Vektor?  
# Ist sipri_data$country ein Vektor?  
is.vector(sipri_data$country)

Diesen Vektor können wir dann für Vergleiche nutzen, wie zum Beispiel:

my_df <- data.frame(x = c(4, 7, 9),
                    y = c(TRUE, FALSE, FALSE),
                    z = c("green", "red", "blue"), stringsAsFactors = FALSE)

# Ist my_df$x größer als 6?
my_df$x > 6
## [1] FALSE  TRUE  TRUE

Diesen Vektor mit logischen Werten können wir wiederum nutzen, um Zeilen zu filtern (d. h. auszuwählen). Etwas Ähnliches haben wir bereits bei Matrizen gemacht.

my_df <- data.frame(x = c(4, 7, 9),
                    y = c(TRUE, FALSE, FALSE),
                    z = c("green", "red", "blue"), stringsAsFactors = FALSE)


row_selection <- my_df$x > 6


my_df[row_selection, ]
##   x     y    z
## 2 7 FALSE  red
## 3 9 FALSE blue

Deutsche Waffenexporte

Nutzen Sie die $-Schreibweise zusammen mit einer Bedingung, um alle Spalten ausschließlich für “Germany” anzeigen zu lassen.

# sipri_data wurde bereits erstellt

# Deutsche Waffenexporte 2017 und 2018
# Formulieren Sie zunächst die Bedingung.
# sipri_data$country soll gleich "Germany" sein.
# Denken Sie an den Unterschied zwischen = und ==.
# Die Bedingung ist:
sipri_data$country == "Germany"
# Ihre Bedingung müssen Sie jetzt
# an die richtige Stelle setzen, 
# um die Zeilen zu filtern.
sipri_data$country == "Germany"
# Nutzen Sie zum auswählen der Zeilen die
# eckigen Klammern. Denken Sie daran,
# der erste Index ist der Zeilenindex 
# und der zweite der Spaltenindex.
sipri_data[sipri_data$country == "Germany", ]

Wie Sie der Ausgabe entnehmen können, betrug der Wert der deutschen Waffenexporte 2017 insgesamt 1980 (TIV) und 2018 1277 (TIV).

Um ein bisschen Übung zu bekommen, wählen Sie alle Zeilen aus, die bei exports_17 einen Wert aufweisen, der größer als 1500 ist.
(Zur Erinnerung: Inhaltlich sind die Zahlen “TIV: trend-indicator value” in Millionen.)

# sipri_data wurde bereits erstellt

# Exporteure mit mehr als 1500 TIV in 2017
# Legen Sie zunächst wieder die Bedingung fest.
# sipri_data$exports_17 soll größer als 1500 sein.
# Die Bedingung ist:
sipri_data$exports_17 > 1500
# Jetzt müssen Sie diese Bedingung an der
# richtigen Stelle einsetzen, um die
# Zeilen zu filtern.
sipri_data[sipri_data$exports_17 > 1500, ]

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##          country exports_17 exports_18
## 17        France       2302       1768
## 19       Germany       1980       1277
## 37        Russia       5741       6409
## 51 United States      12485      10508

Machen wir das Ganze noch ein bisschen komplizierter.

Wählen Sie alle Zeilen aus, die sowohl bei exports_17 als auch exports_18 einen Wert aufweisen, der größer als 1500 ist.
Sie benötigen für diese Übung nicht nur Vergleichsoperatoren, sondern auch Boolesche Operatoren (&, |, !).

# sipri_data wurde bereits erstellt

# Exporteure mit mehr als 1500 TIV in 2017 UND in 2018
# Als Erstes müssen wir die beiden Bedingungen festlegen.
sipri_data$exports_17 > 1500
sipri_data$exports_18 > 1500
# Da beide Bedingungen gleichzeitig erfüllt sein sollen,
# müssen wir sie durch ein logisches UND (&) verknüpfen.
# Wenn Sie sich nicht sicher sind, was der Code macht,
# dan probieren Sie es aus.
sipri_data$exports_17 > 1500 & sipri_data$exports_18 > 1500
# Als letzen Schritt müssen wir die gesamte Bedingung
# an der richtigen Stelle einfügen, 
# um die Zeilen zu filtern.
sipri_data[sipri_data$exports_17 > 1500 & sipri_data$exports_18 > 1500, ]

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##          country exports_17 exports_18
## 17        France       2302       1768
## 37        Russia       5741       6409
## 51 United States      12485      10508

Sortieren

Wenn wir Daten aufbereiten, explorativ analysieren und neue Variablen erstellen, möchten wir unseren Datensatz oft nach einer oder mehreren Variablen sortieren.

Eine Möglichkeit, einen data frame in R zu sortieren, ist mithilfe der Funktion order(). Bevor wir order() nutzen, um einen ganzen Datensatz zu sortieren, schauen wir uns die Funktionsweise bei einem einfachen Vektor an.

x <- c(25, 10, 15, 20)

order(x)
## [1] 2 3 4 1

Die Ausgabe, die order()erzeugt, erscheint zunächst verwirrend. Die nachfolgende Grafik veranschaulicht die Funktionsweise von order().

R nimmt die Elemente des ursprünglichen Vektors und bringt sie entsprechend den Werten (an diesen Positionen) in eine aufsteigende Rangfolge.
Element 2 des ursprünglichen Vektors hat den Wert 10. Da 10 die kleinste der vier Zahlen ist, wird dieses Element auf die erste Position im sortierten Vektor gesetzt.
Wir können die Ausgabe der Funktion order() wie folgt lesen:

Setze Element 2 des ursprünglichen Vektors auf die 1. Position (1. Element) des sortierten Vektors zu.
Setze Element 3 des ursprünglichen Vektors auf die 2. Position (2. Element) des sortierten Vektors zu.
Setze Element 4 des ursprünglichen Vektors auf die 3. Position (3. Element) des sortierten Vektors zu.

Den Vektor, den order() zurückgibt, können wir nutzen, um den ursprünglichen Vektor zu sortieren.

# Erstelle Vektor
x <- c(25, 10, 15, 20)

# Erstelle Vektor mit Sortierung
new_order <- order(x)

# Ausgabe des sortierten Vektors
x[new_order]
## [1] 10 15 20 25

Natürlich können wir den ursprünglichen Vektor auch mit der neuen Sortierung überschreiben.

# Erstelle Vektor
x <- c(25, 10, 15, 20)

# Erstelle Vektor mit Sortierung
new_order <- order(x)

# Zuweisung des sortierten Vektors
x <- x[new_order]

# Ausgabe des sortierten Vektors
x
## [1] 10 15 20 25

Top Ten der Exporteure

Jetzt sind Sie an der Reihe.

  1. Sortieren Sie den Datensatz sipri_data aufsteigend nach exports_17.

  2. Überschreiben Sie den ursprünglichen Datensatz mit der neuen Sortierung.

  3. Lassen Sie die letzten 10 Zeilen des Datensatzes ausgeben.

Tipp: Denken Sie daran, dass wir die Zeilen neu sortieren möchten, nicht die Spalten.

# sipri_data wurde bereits erstellt

# Erstelle Vektor mit Sortierung
<- order(sipri_data$)

# Überschreibe sipri_data mit sortierter Version

# Ausgabe der letzten 10 Zeilen
# Erstellen Sie zunächst den Vektor mit der Sortierung.
# Wählen Sie hierzu einen Vektornamen aus, dem Sie
# den neuen Vektor mit der Sortierung zuweisen.

# Ergänzen Sie auch den Variablennamen in der order-Funktion
# hinter dem $-Zeichen.
# Erstelle Vektor mit Sortierung
new_order <- order(sipri_data$exports_17)
# Da wir die Zeilen neu sortieren möchten,
# muss der Vektor mit der neuen Sortierung
# an die Stelle des Zeilenindex gesetzt werden.
# Datensatz neu sortieren
sipri_data[new_order, ]
# Überschreibe sipri_data mit sortierter Version
sipri_data <- sipri_data[new_order, ]
# Um die letzen 10 Zeilen
# ausgeben zu lassen, können wir
# die Funktion tail() nutzen.
# Um die letzen 10 Zeilen
# ausgeben zu lassen, können wir
# die Funktion tail() nutzen.
# Ausgabe der letzten 10 Zeilen
tail(sipri_data, n = 10)
# Erstelle Vektor mit Sortierung
new_order <- order(sipri_data$exports_17)

# Überschreibe sipri_data mit sortierter Version
sipri_data <- sipri_data[new_order, ]

# Ausgabe der letzten 10 Zeilen
tail(sipri_data, n = 10)

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##           country exports_17 exports_18
## 25          Italy        802        611
## 42          Spain        820       1188
## 29    Netherlands       1132        369
## 8           China       1227       1040
## 50 United Kingdom       1235        741
## 24         Israel       1254        707
## 19        Germany       1980       1277
## 17         France       2302       1768
## 37         Russia       5741       6409
## 51  United States      12485      10508

Wir können order() auch nutzen, um den Datensatz absteigend zu sortieren, sodass die größten Werte oben stehen.

Schauen Sie sich zunächst die Hilfeseite zu order() an.
Passen Sie den folgenden Code-Block dann so an, dass der data frame basierend auf der Spalte exports_17 absteigend sortiert wird.
Lassen Sie abschließend die ersten zehn Zeilen des data frames ausgeben.

# sipri_data wurde bereits erstellt

# Hilfeseite für order
?order

# Erstelle Vektor mit Sortierung
#new_order <- order(sipri_data$exports_17,  )

# Überschreibe sipri_data mit sortierter Version
#sipri_data <- sipri_data[new_order, ]

# Ausgabe der ersten 10 Zeilen
#(sipri_data, n = 10)
# Mit dem Argument "decreasing" können
# Sie kontrollieren, ob die Sortierung
# auf- oder absteigend erfolgen soll.
# Erstelle Vektor mit Sortierung
new_order <- order(sipri_data$exports_17,  decreasing = TRUE)
# Ausgabe der ersten 10 Zeilen
head(sipri_data, n = 10)
# Erstelle Vektor mit Sortierung
new_order <- order(sipri_data$exports_17,  decreasing = TRUE)

# Überschreibe sipri_data mit sortierter Version
sipri_data <- sipri_data[new_order, ]

# Ausgabe der ersten 10 Zeilen
head(sipri_data, n = 10)

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##           country exports_17 exports_18
## 51  United States      12485      10508
## 37         Russia       5741       6409
## 17         France       2302       1768
## 19        Germany       1980       1277
## 24         Israel       1254        707
## 50 United Kingdom       1235        741
## 8           China       1227       1040
## 29    Netherlands       1132        369
## 42          Spain        820       1188
## 25          Italy        802        611

Kleine Auswertung

Um einen ersten Eindruck von unseren Daten zu erhalten, können wir uns mit der Funktion summary() einige deskriptive Statistiken für eine Variable anschauen.

Nutzen Sie summary(), um sich für die Variablen exports_17 und exports_18 deskriptive Statistiken anzeigen zu lassen.

# sipri_data wurde bereits erstellt

# Deskriptive Statistiken
# für exports_17 und exports_18
# Denken Sie daran, die Variablen mit dem
# $-Zeichen aus dem data frame auszuwählen.  
# Deskriptive Statistiken
# für exports_17 und exports_18
summary(sipri_data$exports_17)
summary(sipri_data$exports_18)

Für numerische Variablen gibt summary() den kleinsten (Min.) und größten (Max.) Wert, das untere (1st Qu.) und obere (3rd Qu.) Quartil sowie den Mittelwert und den Median aus.

Ohne an dieser Stelle in eine detaillierte Interpretation der deskriptiven Statistiken zu gehen, sehen wir für beide Jahre ein sehr interessantes Beispiel für reale Daten, bei denen der Mittelwert extrem vom Median abweicht.

Erstellen neuer Variablen

Mit dem $-Zeichen können wir nicht nur Variablen aus einem data frame auswählen, sondern auch ganz einfach neue Variablen erstellen.

Schauen wir uns noch einmal den data frame an, mit dem wir angefangen haben.

# Erstelle Vektoren
state <- c("BW", "BB", "HH", "NW", "SN")
income <- c(2857, 2647, 1494, 3394, 2612)
married <- c(TRUE, FALSE, TRUE, TRUE, FALSE)
kids <- c(2, 0, 0, 3, 1)

# Erstelle data frame
my_first_df <- data.frame(state, income, married, kids, stringsAsFactors = FALSE)

# Ausgabe my_first_df
my_first_df
##   state income married kids
## 1    BW   2857    TRUE    2
## 2    BB   2647   FALSE    0
## 3    HH   1494    TRUE    0
## 4    NW   3394    TRUE    3
## 5    SN   2612   FALSE    1

Um diesem Datensatz eine neue Variable hinzuzufügen, setzen wir den Namen der neuen Variable mit einem $-Zeichen hinter den Namen des data frames und weisen den gewünschten Wert(e) zu.

# my_first_df wurde bereits erstellt

# Erstelle neue Variable happiness
my_first_df$happiness <- c(8, 4, 7, 10, 6)
my_first_df
##   state income married kids happiness
## 1    BW   2857    TRUE    2         8
## 2    BB   2647   FALSE    0         4
## 3    HH   1494    TRUE    0         7
## 4    NW   3394    TRUE    3        10
## 5    SN   2612   FALSE    1         6

Erstellen Sie für den SIPRI-Datensatz eine neue Variable total_exports, die die Summe von exports_17 und exports_18 ist.

Lassen Sie sich dann die ersten 10 Zeilen des Datensatzes ausgeben.
Info: Sie arbeiten hier mit dem ursprünglichen sipri_data data frame, der alphabetisch nach Ländernamen sortiert ist.

# sipri_data wurde bereits erstellt

# Erstelle total_exports 
# (Summe von exports_17 und exports_18)

# Ausgabe ersten 10 Zeilen
# Erstelle total_exports 
# (Summe von exports_17 und exports_18)
# Sie müssen die beiden Spalten nur addieren.
sipri_data$total_exports <-
# Erstelle total_exports 
# (Summe von exports_17 und exports_18)
sipri_data$total_exports <- sipri_data$exports_17 + sipri_data$exports_18
# Ausgabe ersten 10 Zeilen
head(sipri_data, n = 10)
# Erstelle total_exports 
# (Summe von exports_17 und exports_18)
sipri_data$total_exports <- sipri_data$exports_17 + sipri_data$exports_18

# Ausgabe ersten 10 Zeilen
head(sipri_data, n = 10)

Ihre Ausgabe sollte der folgenden Ausgabe entsprechen.

##          country exports_17 exports_18 total_exports
## 1      Australia         98         38           136
## 2        Austria         22          5            27
## 3        Belarus         50         56           106
## 4        Belgium         12         16            28
## 5         Brazil         47        111           158
## 6       Bulgaria         30          7            37
## 7         Canada         64         84           148
## 8          China       1227       1040          2267
## 9       Colombia         10          0            10
## 10 Cote d'Ivoire          0          1             1

Ersetzen mit Bedingung

Wie wir Zeilen aus einem data frame auswählen, die eine bestimmte Bedingung erfüllen, haben wir bereits gesehen.

Einer Beobachtung für eine Variable einen neuen Wert zuzuweisen, wenn die Beobachtung eine bestimmte Bedingung erfüllt, ist fast genau so einfach.

Angenommen wir möchten bei folgendem Datensatz die Variable happiness für die Beobachtung mit der id “1583” von 10 auf 9 verändern.

##     id state income married kids happiness
## 1  619    BW   2857    TRUE    2         8
## 2  307    BB   2647   FALSE    0         4
## 3  244    HH   1494    TRUE    0         7
## 4 1583    NW   3394    TRUE    3        10
## 5 1315    SN   2612   FALSE    1         6

Die folgende Code-Zeile nimmt diese Veränderung vor.

Warum brauchen wir aber in den eckigen Klammern dieses Mal kein Komma?
Schauen wir uns schrittweise an, was der Befehl macht.

my_first_df$happiness[my_first_df$id == "1583"] <- 9 
##     id state income married kids happiness
## 1  619    BW   2857    TRUE    2         8
## 2  307    BB   2647   FALSE    0         4
## 3  244    HH   1494    TRUE    0         7
## 4 1583    NW   3394    TRUE    3         9
## 5 1315    SN   2612   FALSE    1         6

Folgender Befehl gibt uns die Variable happiness als Vektor aus.

# Ausgabe von happiness
my_first_df$happiness

is.vector(my_first_df$happiness)
## [1]  8  4  7 10  6
## [1] TRUE

Da es sich bei my_first_df$happiness um einen Vektor handelt, der nur eine Dimension hat und somit keinen Zeilen- und Spaltenindex, benötigen wir in den eckigen Klammern [] auch kein Komma hinter der Bedingung.

Wir nutzen die Variable my_first_df$id für die Bedingung. “1583” steht hier in Anführungszeichen, da die Variable als character und nicht als numeric codiert ist.

my_first_df$id == "1583"
## [1] FALSE FALSE FALSE  TRUE FALSE

Wie wir sehen, ist die Bedingung nur für die vierte Beobachtung wahr (TRUE).

Wenn wir jetzt den Vektor mit logischen Werten, der das Resultat des Vergleichs ist, für die Indizierung von my_first_df$happiness nutzen, erhalten wir:

my_first_df$happiness[my_first_df$id == "1583"]
## [1] 10

Das ist genau jenes Element, das wir ersetzen möchten.

Wir müssen diesem Element jetzt nur noch den neuen Wert zuweisen (<-).

my_first_df$happiness[my_first_df$id == "1583"] <- 9

# Ausgabe
my_first_df
##     id state income married kids happiness
## 1  619    BW   2857    TRUE    2         8
## 2  307    BB   2647   FALSE    0         4
## 3  244    HH   1494    TRUE    0         7
## 4 1583    NW   3394    TRUE    3         9
## 5 1315    SN   2612   FALSE    1         6

China, NATO-Mitgliedsstaat?

Dem SIPRI-Datensatz wurde die numerische Variable nato_member hinzugefügt. Die Variable nimmt den Wert 1 an, wenn das entsprechende Land Mitglied der NATO ist und 0 andernfalls.

Allerdings ist bei der Codierung der Variable ein Fehler unterlaufen. China weist bei der Variable nato_member eine 1 auf, obwohl es kein NATO-Mitgliedsstaat ist.

Korrigieren Sie diesen Fehler, indem Sie den Wert bei dieser Variable für China auf 0 setzen.
Überprüfen Sie abschließend Ihre Korrektur, indem Sie die ersten zehn Zeilen des Datensatzes ausgeben lassen.

# sipri_data mit nato_member wurde bereits erstellt

# Überzeugen Sie sich davon, dass nato_member
# für China falsch codeirt ist.
head(sipri_data, n = 10)

# Korrigiere Variable nato_member für China


# Check
head( , n = 10)
# Legen Sie zunächst die Bedingung fest.
# Legen Sie zunächst die Bedingung fest.
sipri_data$country == "China"
# Als nächstes bereiten wir die Indizierung, 
# der Variablen vor, die wir ändern möchten.
sipri_data$nato_member[]
# Um das zu korrigierende Element auszuwählen,
# setzen wir die Bedingung einfach in die eckigen
# Klammern ein.
sipri_data$nato_member[sipri_data$country == "China"]
# Jetzt müssen wir nur noch den
# richtigen Wert zuweisen.
sipri_data$nato_member[sipri_data$country == "China"] <- 0
# Korrigiere Variable nato_member für China
sipri_data$nato_member[sipri_data$country == "China"] <- 0

# Check
head(sipri_data, n = 10)

Listen

data(swiss)
swiss <- swiss

Bisher haben wir Vektoren, Matrizen und data frames kennengelernt:

  1. Vektoren:
    • Können numeric, character oder logical Werte enthalten
    • Alle Elemente eines Vektors müssen den gleichen Datentyp haben
    • Haben eine Dimension
  2. Matrizen:
    • Können numeric, character oder logical Werte enthalten
    • Alle Elemente einer Matrix müssen den gleichen Datentyp haben
    • Haben zwei Dimensionen (Zeilen und Spalten)
  3. Data frames:
    • Können numeric, character oder logical Werte enthalten
    • Unterschiedliche Spalten müssen nicht alle den gleichen Datentyp haben
    • Alle Elemente in einer Spalte müssen den gleichen Datentyp haben
    • Haben zwei Dimensionen (Zeilen und Spalten)

Matrizen und data frames sind rechteckig. Das bedeutet, jede Zeile hat die gleiche Anzahl an Spalten und jede Spalte hat die gleiche Anzahl an Zeilen.

Was sind Listen?

Eine Liste ist, wie ein data frame, eine Zusammenstellung von Variablen. Allerdings gelten für eine Liste nicht die gleichen Beschränkungen wie für einen data frame.

  • Listen müssen nicht rechteckig sein. Das bedeutet, Listen müssen keine Tabellen sein.
  • Die Variablen einer Liste müssen in keiner bestimmten Beziehung zueinanderstehen.
  • In einer Liste können Objekte mit unterschiedlichen Datenstrukturen (Vektoren, Matrizen, data frames und sogar andere Listen) gespeichert werden.

Um zu verstehen, was eine Liste ist, erstellen wir am besten eine. Hierfür nutzen wir die Funktion list().

# Erstelle Liste
my_list <- list("Merkel",
                c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))

Lassen Sie sich my_list ausgeben.

# Erstelle Liste
my_list <- list("Merkel",
                c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))
# Ausgabe von my_list
# Ausgabe von my_list
my_list

my_list enthällt drei Variablen, wie wir anhand der Zahlen in den doppelten, eckigen Klammern [[ ]] sehen können.

  • Die erste Variable ist ein character-Vektor mit einem Element (“Merkel”).
  • Die zweite Variable ist ebenfalls ein character-Vektor jedoch mit mehreren Elementen.
  • Die dritte Variable ist ein data frame mit drei Zeilen und zwei Spalten.

Benannte Listen

Wie bei data frames können wir auch die Komponenten einer Liste benennen.

my_list <- list(name_1 = component_1,
                name_2 = component_2)

Das ist äquivalent zu:

my_list <- list(component_1,
                component_2)

names(my_list) <- c("name_1", "name_2")

Benennen Sie die Komponenten von my_list der Reihenfolge nach Kanzlerin, Kabinett, Parteien und lassen Sie sich die Liste dann ausgeben.

# Benennen Sie die Komponenten der Liste
my_list <- list("Merkel",
                c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))

# Ausgabe von my_list
# Setzen Sie den Namen zusammen mit einem
# Gleichheitszeichen vor die jeweilige Komponente.
# Benennen Sie die Komponenten der Liste
my_list <- list(Kanzlerin = "Merkel",
                c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))
# Benennen Sie die Komponenten der Liste
my_list <- list(Kanzlerin = "Merkel",
                Kabinett = c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))
# Benennen Sie die Komponenten der Liste
my_list <- list(Kanzlerin = "Merkel",
                Kabinett = c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                Parteien = data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))

# Ausgabe von my_list
my_list

Lassen Sie sich jetzt die Struktur von my_list ausgeben. Falls Sie sich nicht mehr an die Funktion erinnern, schauen Sie sich den Hinweis (Hint) an.

# Erstelle my_list
my_list <- list(Kanzlerin = "Merkel",
                Kabinett = c("Merkel", "Scholz", "Seehofer", "Maas", 
                  "Altmaier", "Barley", "Heil", "von der Leyen", 
                  "Kloeckner", "Giffey", "Spahn", "Scheuer", 
                  "Schulze", "Karliczek", "Mueller", "Braun"),
                Parteien = data.frame(party = c("CDU", "CSU", "SPD"),
                           minister = c(7, 3, 6)))

# Struktur von my_list
# Struktur von my_list
str(my_list)

Warum sind Listen wichtig?

Viele Funktionen in R geben ihre Ergebnisse in Form einer Liste zurück. Das liegt vor allem daran, dass in Listen Objekte mit unterschiedlichen Datenstrukturen (Vektoren, Matrizen, data frames) gespeichert werden können.

Die Ergebnisse unterschiedlicher Regressionsmodelle (z. B. lineare Modelle, GLMs, GAMs) werden in Listen gespeichert.

Für ein Beispiel nutzen wir den in R verfügbaren Datensatz swiss. Der Datensatz enthält sozioökonomische Variablen zu 47 französisch-sprachigen Schweitzer Bezirken um das Jahr 1888. Wir nutzen nachstehende Variablen:

  • Fertility: Geburtenhäufigkeit (skaliert auf 0 bis 100)
  • Agriculture: Anteil von Männern, die in der Landwirtschaft beschäftigt sind (in Prozent)
  • Catholic: Anteil Katholiken (in Prozent)

Als Regressand (abhängige Variable) nutzen wir Fertility und als Regressoren (unabhängige Variablen) Agriculture und Catholic.

Mit der Funktion lm() können wir in R eine OLS-Regressionsanalyse durchführen (OLS: Ordinary Least Squares). lm steht dabei für linear model. Der Code für die Regressionsanalyse ist in der Code-Box bereits vollständig gegeben. Sie müssen folglich in dieser Zeile keine Änderungen mehr vornehmen.

  1. Lassen Sie sich my_model ausgeben.

  2. Überprüfen Sie mit der Funktion is.list(), ob my_model eine Liste ist.

# Regression
my_model <- lm(Fertility ~ Agriculture + Catholic, data = swiss)

# Ausgabe von my_model

# Ist my_model eine Liste?
# Ausgabe my_model
# Schreiben Sie einfach "my_model"
# und führen den Code dann aus.
# Ausgabe my_model
my_model
# Ausgabe my_model
my_model

# Ist my_model eine Liste?
is.list(my_model)

Wie Sie sehen, gibt is.list(my_model) den Wert TRUE zurück. Das bedeutet, my_model ist eine Liste. Allerdings sieht die Ausgabe für my_model nicht wie die vorherigen Ausgaben einer Liste aus. Dies liegt daran, dass es sich bei my_model um eine besondere Liste handelt. Das ist jedoch für uns hier nicht von Interesse.

Lassen Sie sich die Struktur von my_model ausgeben.

# Regression
my_model <- lm(Fertility ~ Agriculture + Catholic, data = swiss)

# Struktur von my_model
# Struktur von my_model
str(my_model)

Die Struktur von my_model ist sehr komplex. Sie müssen die Ausgabe an dieser Stelle nicht bis ins letzte Detail verstehen. Wenn Sie mehr mit linearen Modellen arbeiten, ist es jedoch von Vorteil zu wissen, dass die Modellergebnisse in einer Liste gespeichert werden und wie die Struktur dieser Liste aussieht.

Mehr als nur Vektoren, Matrizen und data frames…

Die Elemente einer Liste können nicht nur Vektoren, Matrizen oder data frames sein, sondern auch andere Listen.

Schauen Sie sich das folgende Beispiel an.

# Erstelle Liste
my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

Lassen Sie die Liste my_list ausgeben.

# Erstelle Liste
my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Ausgabe von my_list
# Ausgabe von my_list
my_list

In der Ausgabe sehen wir hinter $list_in_my_list wieder die doppelten, eckigen Klammern [[ ]]. Das zeigt uns, dass list_in_my_list auch eine Liste ist.

Indizierung von Listen

Die Auswahl von Komponenten und einzelnen Elementen aus einer Liste ist ein bisschen komplizierter als bei Vektoren, Matrizen oder data frames.

Um eine Komponente auszuwählen, nutzen wir zwei Paar eckige Klammern [[ ]]. Den Index der Komponente, die wir auswählen möchten, schreiben wir zwischen die inneren eckigen Klammern.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Auswahl 1. Komponente von my_list
my_list[[1]]
## [1] "This"      "is"        "a"         "character" "vector."

Wählen Sie die Matrix my_matrix aus der Liste aus.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Auswahl my_matrix aus my_list
my_list[[ ]]
# Die Matrix my_matrix ist die 
# zweite Komponente der Liste my_list.
# Auswahl my_matrix aus my_list
my_list[[2]]

Warum nutzen wir nicht [] ?

Warum nutzen wir für die Indizierung von Listen eigentlich [[ ]] und nicht []?

Probieren wir es doch einfach aus. Führen Sie den Code aus.

Sehen Sie den Unterschied?

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Auswahl my_vector mit []
my_list[1]

# Auswahl my_vector mit [[]]
my_list[[1]]

Offensichtlich sind die beiden Ausgaben unterschiedlich. Bei der ersten Ausgabe steht “$my_vector” in der ersten Zeile, bei der zweiten nicht. Aber was bedeutet das?

Die Auswahl mit [] liefert immer eine Liste. Mit [[]] können wir die jeweilige Komponente aus der Liste “herausziehen”.

Überprüfen Sie mit der Funktion is.list(), ob die jeweilige Auswahl mit [] oder [[]] eine Liste zurückgibt.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Überprüfe Auswahl my_vector mit []
is....(my_list[1])

# Überprüfe Auswahl my_vector mit [[]]
(my_list[[1]])
# Nutzen Sie für beiden Auswahlmöglichkeiten [] und [[]] die Funktion is.list().
# Überprüfe Auswahl my_vector mit []
is.list(my_list[1])
# Überprüfe Auswahl my_vector mit []
is.list(my_list[1])

# Überprüfe Auswahl my_vector mit [[]]
is.list(my_list[[1]])

Alternative Auswahl von Komponenten

Wenn wir eine benannte Liste haben, können wir auch die beiden folgenden Möglichkeiten nutzen, um Komponenten aus einer Liste zu extrahieren.

# Auswahl mit $component_name
my_list$component_name

# Auswahl mit [["component_name"]]
my_list[["component_name"]]

Beide Auswahlmöglichkeiten sind äquivalent zur Auswahl mit den doppelten, eckigen Klammern [[ ]] und dem Index.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Auswahl mit $component_name
my_list$my_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# Auswahl mit [["component_name"]]
my_list[["my_matrix"]]
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Auswahl von Elementen aus Komponenten einer Liste

Oft möchten wir nicht nur Komponenten aus Listen, sondern auch (einzelne) Elemente dieser Komponenten auswählen.

Mit dem folgenden Befehl wählen wir das zweite Element der ersten Komponente der Liste my_list aus.

my_list[[1]][2]
## [1] "is"

Jetzt sind Sie an der Reihe. Wählen Sie die gesamte zweite Spalte der Matrix my_matrix aus.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Auswahl 2. Spalte von my_matrix
# Vergessen Sie nicht, dass Sie bei
# der Indizierung der Spalte aus einer
# Matrix auswählen. Wenn Sie aus einer Matrix
# auswählen, müssen Zeilen- und Spaltenindex beachten.
# Auswahl 2. Spalte von my_matrix
my_list[[2]][,2]

Wie wir gesehen haben, können Listen auch andere Listen enthalten. In unserem Beispiel enthält my_list eine weitere Liste, list_in_my_list.

Wählen Sie die Zeichenfolge “xyz” aus list_in_my_list in my_list aus. Stellen Sie sicher, dass Ihre Auswahl keine Liste zurückgibt.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", TRUE)
                )

# Auswahl "xyz" aus list_in_my_list

# Übeprüfe, ob die Auswahl eine Liste zurückgibt
# Denken Sie daran, dass es sich bei
# list_in_my_list ebenfalls um eine Liste handelt
# und daher wie eine Liste indiziert werden muss.
# Auswahl "xyz" aus list_in_my_list
my_list[[4]][[2]]
# Übeprüfe, ob die Auswahl eine Liste zurückgibt
is.list(my_list[[4]][[2]])

Zugegeben, das Indizieren von Listen ist nicht ganz einfach. Folgendes Bild aus einem Tweet von Hadley Wickham (einer der wichtigsten R-Entwickler) veranschaulicht das Indizieren von Listen.

Wir können uns eine Liste x auch als einen Behälter vorstellen. In diesem Beispiel enthält der Behälter mehrere Päckchen Pfeffer (Komponenten). Wenn wir x[1] ausführen, dann wählen wir nur eines der Päckchen aus. Allerdings befindet es sich immer noch in dem Behälter. Wenn wir x[[1]] ausführen, holen wir das einzelne Päckchen aus dem Behälter heraus.

Wenn das Päckchen selbst eine Liste (ein Behälter) ist, dann müssen wir x[[1]][[1]] ausführen, um an den Pfeffer zu kommen.

Zum Schluss eine schwierige Aufgabe.

Wählen Sie die Zeichenfolge “Bitte auswaehlen!” aus list_in_my_list in my_list aus. Stellen Sie sicher, dass Ihre Auswahl keine Liste zurückgibt.

my_list <- list(my_vector = c("This", "is", "a", "character", "vector."),
                my_matrix = matrix(1:9, nrow = 3, byrow = TRUE),
                my_df = data.frame(var1 = c("obs_1", "obs_2", "obs_3", "obs_4"),
                                   var2 = c(8,3, 5, 7),
                                   var3 = c(TRUE, FALSE, FALSE, TRUE)
                                   ),
                list_in_my_list = list(1, "xyz", 
                                       list(2, 
                                            list(3, "Bitte auswaehlen!")
                                            )
                                       )
                )

# Auswahl "Bitte auswaehlen!" aus list_in_my_list

# Übeprüfe, ob die Auswahl eine Liste zurückgibt
# Im vorherigen Beispiel haben wir gesehen,
# dass wir list_in_my_list wie folgt auswählen.
my_list[[4]]
# list_in_my_list ist eine Liste weshalb wir auch
# hier die doppelten eckigen Klammern nutzen müssen.
# An erster Stelle von list_in_my_list haben wir die 
# Zahl 1, an zweiter die Zeichenfolge "xyz" und 
# an dritter Stelle eine weitere genestete Liste.
# Irgendwo in dieser Liste befindet sich die Zeichenfolge,
# an der wir interessiert sind. Also:
my_list[[4]][[3]]
# Die nächste Liste hat an der ersten Position die Zahl 2
# und dann der zweiten wieder eine Liste.
# Wir wollen wiederum die Liste auswählen.
my_list[[4]][[3]][[2]]
# Puh, das ist die letzte Liste.
# Diese Liste hat an erster Position die Zahl 3
# und an zweiter die Zeichenfolge, 
# die wir auswählen möchten.
my_list[[4]][[3]][[2]][[2]]

# Übeprüfe, ob die Auswahl eine Liste zurückgibt
is.list(my_list[[4]][[3]][[2]][[2]])

Puuuh…endlich geschafft…Listen in Listen in Listen…



Schleifen

Der Code, den Sie in den vorherigen Aufgaben geschrieben haben, folgte bisher immer dem gleichen Muster.

Die Befehle wurden von R der Reihe nach abgearbeitet. Dies ist in Abbildung 1 dargestellt. Zunächst wird der erste Befehl, dann der zweite, der dritte usw. bis zum letzten Befehl ausgeführt.

Schleifen (Englisch: loops) sind eine Möglichkeit, von dieser Struktur abzuweichen. Eine Schleife ist ein Code-Block, d. h. eine Abfolge von Befehlen, der immer wieder ausgeführt wird, bis ein Stoppkriterium erfüllt ist. In Abbildung 2 sehen Sie die Struktur eines R-Skripts mit einer Schleife. Die Befehle innerhalb der Schleife (nach Schleifenanfang) werden solange wiederholt, bis das Erreichen des Stoppkriteriums dazu führt, dass die Schleife beendet wird. Anschließend werden die Befehle, die nach der Schleife folgen, ausgeführt.

Abbildung 1

Abbildung 2



Schleifentypen

Es gibt zwei Typen von Schleifen:

  1. for-Schleife: Die for-Schleife wird genutzt, wenn zu Beginn der Schleife bereits feststeht, wie oft die Schleife durchlaufen wird.
  2. while-Schleife: Die while-Schleife wird genutzt, wenn zu Beginn der Schleife nicht feststeht, wie oft die Schleife durchlaufen wird.

Die for-Schleife

Der folgende Code-Block zeigt die Struktur einer for-Schleife in R.

for (variable in vector){
  # Führe einen Befehl aus
  # Führe den nächsten Befehl aus
}

Im obigen Beispiel wird variable auch als Laufvariable bezeichnet. Oft wird für diese Laufvariable der Buchstabe i genutzt. Es können jedoch auch alle anderen Klein- und Großbuchstaben von A-Z als Laufvariable genutzt werden. Der Vektor vector kann sowohl vom Typ numeric, character als auch logical sein.

Die Anzahl der Elemente in vector, d. h. die Länge des Vektors, gibt vor, wie oft die Schleife durchlaufen wird. Wenn vector etwa fünf Elemente hat, wird die Schleife fünf Mal durchlaufen, bei zehn Elementen wären es zehn Mal usw.

Beim ersten Durchlauf der Schleife nimmt variable den Wert des ersten Elementes von vector an, beim zweiten Durchlauf den Wert des zweiten Elements, beim dritten Durchlauf den des dritten Elements usw. bis zum letzten Element von vector.

Schauen wir uns an, was eine for-Schleife macht.

Die print()-Funktion haben wir ganz zu Beginn der App schon gesehen. Wenn wir bisher Objekte haben ausgeben lassen, hat R im Hintergrund dazu immer die Funktion print() aufgerufen. Wenn wir innerhalb einer Schleife etwas ausgeben lassen möchten, müssen wir die print()-Funktion explizit aufrufen.

Probieren Sie aus, was die Schleife macht!

for (i in 1:10){
  # Ausgabe der Zahlen von 1 bis 10
  print(i)
}

Die Schleife gibt Schritt für Schritt die Elemente des Vektors (hier 1:10) aus. Im ersten Durchlauf nimmt i den Wert 1 an, im zweiten 2, im dritten 3 usw. Beim letzten Durchlauf nimmt i den Wert 10 an. Nachdem die Schleife für das letzte Element des Vektors 1:10 durchlaufen wurde, wird die Schleife beendet und die weiteren Befehle (nach der Schleife) regulär abgearbeitet.

Der Vorteil der for-Schleife ist, dass wir den Befehl nicht für jedes Element des Vektors separat schreiben müssen. Wenn wir die gleiche Ausgabe ohne Schleife erzeugen wollten, müssten wir (mit unseren bisherigen R-Kenntnissen) es zum Beispiel so machen:

my_vec <- 1:10
print(my_vec[1])
print(my_vec[2])
print(my_vec[3])
...
print(my_vec[10])

Diese Wiederholungen sind sehr fehleranfällig. Möglicherweise unterläuft uns ein Tippfehler oder wir vergessen ein Element des Vektors. Darüber hinaus nimmt diese Variante unnötig viel Platz in Anspruch und bedeutet einen hohen Schreibaufwand. Dies führt auch dazu, dass unser Skript für andere Personen schwieriger zu lesen ist.

Stellen Sie sich vor, wir würden den gleichen Befehl oder den gleichen Code-Block für 20, 50, 100 oder sogar 1000 Elemente eines Vektors, einer Liste, Matrix oder data frames ausführen wollen.

Das einleitende Beispiel diente nur zur Veranschaulichung der Funktionsweise einer for-Schleife. So gut wie immer, ist der Code innerhalb der Schleife deutlich komplexer und besteht nicht nur aus einem Befehl. Steigern wir uns also ein bisschen.

Passen Sie folgenden Code-Block so an, dass i_square das Quadrat der Zahl in i zugewiesen wird. (Das Quadrat einer Zahl ist das gleiche wie eine Zahl mit sich selbst zu multiplizieren.)

Die Funktion cat() fügt die verschiedenen Teile zusammen und gibt sie aus.
for (i in 1:10){
  
  # Quadriere i
  i_square <- i
  
  # Textausgabe: i und i_square
  cat("Das Quadrat von ", i, " ist ", i_square, ".\n", sep = "")
}
# Sie müssen ausschließlich Zeile 4 anpassen.
# Sie müssen ausschließlich Zeile 4 anpassen.
# Multiplizieren Sie hier einfach i mit sich selbst.
# Sie müssen ausschließlich Zeile 4 anpassen.
# Multiplizieren Sie hier einfach i mit sich selbst.
# Hierfür gibt es zwei Möglichkeiten:
# 1. Möglichkeit
i*i

# 2. Möglichkeit
i^2
# Sie müssen ausschließlich Zeile 4 anpassen.
# Multiplizieren Sie hier einfach i mit sich selbst.
for (i in 1:10){
  
  # Quadriere i
  i_square <- i^2
  
  # Textausgabe: i und i_square
  cat("Das Quadrat von ", i, " ist ", i_square, ".\n", sep = "")
}

Sehr gut!

Wie bereits erwähnt, kann vector auch vom Typ character sein.

for (variable in vector){
  # Führe einen Befehl aus
  # Führe den nächsten Befehl aus
}

Probieren wir es aus. Ersetzen Sie vector durch philosophers und führen Sie den Code aus.
nchar() ermittelt die Zahl der Zeichen eines strings (Zeichenfolge).

philosophers <- c("Arendt", "Weber", "Foucault", "Rawls", 
                  "Nussbaum", "Mouffe", "Luhmann")

for (one_name in vector){
  
  # Zähle Buchstaben
  num_char <- nchar(one_name)
  # Ausgabe
  cat(one_name, " hat ", num_char, " Buchstaben.\n", sep = "")
}
# Sie müssen ausschließlich Zeile 4 anpassen.
# Ersetzen Sie in Zeile 4 vector durch philosophers.
# Ersetzen Sie in Zeile 4 vector durch philosophers
philosophers <- c("Arendt", "Weber", "Foucault", "Rawls", 
                  "Nussbaum", "Mouffe", "Luhmann")

for (one_name in philosophers){
  
  # Zähle Buchstaben
  num_char <- nchar(one_name)
  # Ausgabe
  cat(one_name, " hat ", num_char, " Buchstaben.\n", sep = "")
}

Bisher haben wir nur mit einem Vektor gearbeitet. Wir können jedoch innerhalb der Schleife auch mit mehreren Vektoren arbeiten.

Passen Sie den Code an den Stellen mit .... so an, dass für jedes Land die dazugehörige Hauptstadt ausgegeben wird.

countries <- c("Belgien",  "Daenemark", "Deutschland", "Estland", "Finnland", 
               "Island", "Lettland", "Norwegen", "Schweden")
capitals <- c("Bruessel", "Kopenhagen", "Berlin", "Tallinn", "Helsinki", 
              "Reykjavik", "Riga", "Oslo", "Stockholm")


for (i in 1:....){
  # Auswahl des Landes und der Hauptstadt
  one_country <- countries[....]
  one_capital <- capitals[....]
  
  # Ausgabe
  cat(one_capital, " ist die Hauptstadt von ", one_country, ".\n", sep = "")
}
# Als Erstes müssen Sie den Vektor festlegen,
# über den die Schleife laufen soll.
# Hierzu müssen Sie zunächst herausfinden,
# wie lang der Vektor countries oder capitals ist.
# Um die Länge von countries oder capitals herauszufinden,
# können Sie entweder die Elemente eines der Vektoren zählen
# oder Sie nutzen die Funktion length().
length(countries)
# Um die Länge von countries oder capitals herauszufinden,
# können Sie entweder die Elemente eines der Vektoren zählen
# oder Sie nutzen die Funktion length().
for (i in 1:length(countries)){
  # Auswahl des Landes und der Hauptstadt
  one_country <- countries[....]
  one_capital <- capitals[....]
  
  # Ausgabe
  cat(one_capital, " ist die Hauptstadt von ", one_country, ".\n", sep = "")
}
# Jetzt müssen Sie nur noch die Laufvariable nutzen,
# um die Vektoren countries und capitals zu indizieren.
# Jetzt müssen Sie nur noch die Laufvariable nutzen,
# um die Vektoren countries und capitals zu indizieren.
for (i in 1:length(countries)){
  # Auswahl des Landes und der Hauptstadt
  one_country <- countries[i]
  one_capital <- capitals[i]
  
  # Ausgabe
  cat(one_capital, " ist die Hauptstadt von ", one_country, ".\n", sep = "")
}
countries <- c("Belgien",  "Daenemark", "Deutschland", "Estland", "Finnland", 
               "Island", "Lettland", "Norwegen", "Schweden")
capitals <- c("Bruessel", "Kopenhagen", "Berlin", "Tallinn", "Helsinki", 
              "Reykjavik", "Riga", "Oslo", "Stockholm")

for (i in 1:length(countries)){
  # Auswahl des Landes und der Hauptstadt
  one_country <- countries[i]
  one_capital <- capitals[i]
  
  # Ausgabe
  cat(one_capital, " ist die Hauptstadt von ", one_country, ".\n", sep = "")
}

Wir können die Laufvariable nicht nur nutzen, um Vektoren zu indizieren, sondern auch Matrizen, Listen und data frames.

Probieren wir es gleich mit Listen aus. Im folgenden Beispiel sind countries und capitals keine Vektoren, sondern Listen.

Passen Sie den Code erneut so an, dass jedes Land mit der dazugehörigen Hauptstadt ausgegeben wird.
Nehmen Sie ausschließlich Änderungen an den Stellen mit .... vor.

Denken Sie daran, was Sie über das Indizieren von Listen gelernt haben. Erinnern Sie sich an das Bild von Hadley Wickham mit den Pfefferpäckchen in dem Behälter.

countries <- list("Belgien",  "Daenemark", "Deutschland", "Estland", "Finnland", 
               "Island", "Lettland", "Norwegen", "Schweden")
capitals <- list("Bruessel", "Kopenhagen", "Berlin", "Tallinn", "Helsinki", 
              "Reykjavik", "Riga", "Oslo", "Stockholm")


for (i in 1:....){
  # Auswahl des Landes und der Hauptstadt
  # one_country und one_capital sollen keine Listen sein
  one_country <- countries[....]
  one_capital <- capitals[....]
  
  # Ausgabe
  cat(one_country, " ist die Hauptstadt von ", one_capital, ".\n", sep = "")
}
# Zunächst müssen Sie wieder festlegen, 
# wie oft die Schleife durchlaufen werden soll.
# Hierzu müssen Sie die Länge einer der Listen bestimmen.
# Sie können die Elemente der Listen zählen
# oder Sie nutzen wieder length().
# Sie können die Elemente der Listen zählen
# oder Sie nutzen wieder length().
# Sie können die Elemente der Listen zählen
# oder Sie nutzen wieder length().
for (i in 1:length(countries)){
  # Auswahl des Landes und der Hauptstadt
  # one_country und one_capital sollen keine Listen sein
  one_country <- countries[....]
  one_capital <- capitals[....]
  
  # Ausgabe
  cat(one_country, " ist die Hauptstadt von ", one_capital, ".\n", sep = "")
}
# Beim nächsten Schritt müssen Sie aufpassen,
# dass Sie beim Auswählen der Listenelemente
# keine Liste extrahieren.
# Nutzen Sie deshalb die doppelten, eckigen Klammern "[[ ]]"
# zum Indizieren.
# Nutzen Sie deshalb die doppelten, eckigen Klammern "[[ ]]"
# zum Indizieren.
for (i in 1:length(countries)){
  # Auswahl des Landes und der Hauptstadt
  # one_country und one_capital sollen keine Listen sein
  one_country <- countries[[i]]
  one_capital <- capitals[[i]]
  
  # Ausgabe
  cat(one_country, " ist die Hauptstadt von ", one_capital, ".\n", sep = "")
}
countries <- list("Belgien",  "Daenemark", "Deutschland", "Estland", "Finnland", 
               "Island", "Lettland", "Norwegen", "Schweden")
capitals <- list("Bruessel", "Kopenhagen", "Berlin", "Tallinn", "Helsinki", 
              "Reykjavik", "Riga", "Oslo", "Stockholm")

# Nutzen Sie die doppelten, eckigen Klammern "[[ ]]"
# zum Indizieren.
for (i in 1:length(countries)){
  # Auswahl des Landes und der Hauptstadt
  # one_country und one_capital sollen keine Listen sein
  one_country <- countries[[i]]
  one_capital <- capitals[[i]]
  
  # Ausgabe
  cat(one_country, " ist die Hauptstadt von ", one_capital, ".\n", sep = "")
}

Oh, da ist uns wohl ein Fehler unterlaufen… one_country und one_capital müssen die Positionen in der Funktion cat() tauschen, damit die Ausgabe richtig ist. Bei einer Schleife müssen wir jetzt zum Glück lediglich eine Zeile Code korrigieren. Hätten wir keine Schleife genutzt und die Befehle für jedes Land separat geschrieben, dann müssten wir jetzt deutlich mehr korrigieren.

Korrigieren Sie den obigen Code, indem Sie one_country und one_capital in der cat() Funktion tauschen. Führen Sie den Code dann erneut aus.

press_freedom <- press_freedom
press_freedom_orig <- press_freedom %>%
  mutate_at(vars(y2019:y2013), list(~as.character(.))) %>%
   mutate_at(vars(y2019:y2013), list(~stringr::str_replace_all(., "\\.", ",")))

Reporter ohne Grenzen ist eine internationale NGO, die jährlich den Press Freedom Index, einen Index zur Lage der Pressefreiheit in 180 Ländern, veröffentlicht. Der Datensatz press_freedom mit dem Press Freedom Index der Jahre 2013 bis 2019 wurde bereits für Sie geladen. Der Index reicht von 0 (optimal) bis 100 (schlechtestmöglich). Der verwendete Datensatz wurde automatisch von Wikipedia ausgelesen.

Schauen Sie sich mit head() die ersten zehn Zeilen des Datensatzes press_freedom an.

# press_freedom wurde bereits erstellt

# Ausgabe der ersten 10 Zeilen
head( , n)
# Ausgabe der ersten 10 Zeilen
head(press_freedom, n = 10)

Vervollständigen Sie die Schleife, sodass für jedes Jahr, das Land mit dem besten und dem schlechtesten Wert ausgegeben wird. Die Schleife soll nur über die Variable (Spalten) mit dem Press Freedom Index laufen.

min() und max() liefern das Minimum und Maximum der übergebenen Werte (hier Spalten eines data frames). which() gibt die Position jener Elemente zurück, die die Bedingung innerhalb der Klammern erfüllen. Wenn zum Beispiel das vierte Element eines Vektors einen Wert hat, der gleich dem kleinsten Wert des gesamten Vektors ist, dann gibt which() die Zahl 4 zurück.

for (k in ....:8){
  # Finde Minimum und Maximum der Spalte(n)
  lowest_value <- min(press_freedom[,....], na.rm = TRUE)
  highest_value <- max(press_freedom[,....], na.rm = TRUE)
  
  # Ermittle Positionen                     
  best <- which(press_freedom[ ,....] == lowest_value)
  worst <- which(press_freedom[ ,....] == highest_value)
  
  best_country <- press_freedom$country[best]
  worst_country <- press_freedom$country[worst]
  
  cat("Jahr: ", names(press_freedom)[....], "\n", sep = "")
  cat("Bester Wert: ", best_country, "\n", sep = "")
  cat("Schlechtester Wert: ", worst_country, "\n\n", sep = "")
}
# Zuerst müssen Sie festlegen, 
# wie oft die Schleife durchlaufen werden soll.
# Hierzu müssen Sie den Zahlenvektor anpassen.
# Der Endwert ist bereits gegeben.
# Überlegen Sie, was der Startwert sein muss.
# Die Spalten 2 bis 8 enthalten den 
# Press Freedom Index für die verschiedenen Jahre.
# Deshalb sollte der Startwert 
# des Vektors auf 2 gesetzt werden.
for (k in 2:8){
  
}
# Als Nächstes müssen Sie mit der
# Laufvariable an den richtigen Stellen
# den Datensatz indizieren.
# Achten Sie auf die Bezeichnung der Laufvariable!
for (k in 2:8){
  # Finde Minimum und Maximum der Spalte(n)
  lowest_value <- min(press_freedom[,k], na.rm = TRUE)
  highest_value <- max(press_freedom[,k], na.rm = TRUE)
  
  # Ermittle Positionen                    
  best <- which(press_freedom[ ,k] == lowest_value)
  worst <- which(press_freedom[ ,k] == highest_value)
  
  best_country <- press_freedom$country[best]
  worst_country <- press_freedom$country[worst]
  
  cat("Jahr: ", names(press_freedom)[k], "\n", sep = "")
  cat("Bester Wert: ", best_country, "\n", sep = "")
  cat("Schlechtester Wert: ", worst_country, "\n\n", sep = "")
}

Beim Original-Datensatz von Wikipedia sind die Spalten für den Press Freedom Index als Zeichenfolge (character) gespeichert. Darüber hinaus wurde als Dezimaltrennzeichen das Komma und nicht der Punkt verwendet, was für Statistikanwendungen eher unüblich ist.

Der Datensatz press_freedom_orig wurde für Sie bereits geladen. Verschaffen Sie sich mit str() einen Überblick über den Datensatz.

# Structure
str(press_freedom_orig)

Vervollständigen Sie den folgenden Code-Block, sodass die Kommata in den Spalten 2 bis 8 durch Punkte ersetzt werden und die Variablen als numerische Variablen gespeichert werden. Vor der Schleife legen wir eine Kopie (press_freedom_num) des Original-Datensatzes an, mit der wir weiterarbeiten.

Die Funktion sub() sucht in einem character-Vektor nach einem Muster (Englisch: pattern) von Zeichen und ersetzt diese Zeichenfolge mit etwas anderem (Englisch: replacement).

# Erstelle Kopie des Datensatzes 
press_freedom_num <- press_freedom_orig

# Schleife
.... (.... 2:8){
  # Ersetze Kommata durch Punkte
  press_freedom_num[, ] <- sub(pattern = ",", replacement = ".", press_freedom_num[, ])
  # Ändere Datentyp zu numerisch
  press_freedom_num[, ] <- as.numeric(press_freedom_num[, ])
}
# Überprüfung nach Schleife
str(press_freedom_num)
# Als Erstes müssen Sie den Code
# für die Schleife vervollständigen.
# Die Bezeichnung der Laufvariable
# können Sie selbst festlegen.
# Schleife
for (i in 2:8){
  
}
# Als Nächstes müssen Sie die
# Laufvariable an den richtigen 
# Stellen einfügen, um die entsprechenden 
# Variablen (Spalten) auszuwählen.
# Schleife
for (i in 2:8){
  # Ersetze Kommata durch Punkte
  press_freedom_num[, i] <- sub(pattern = ",", replacement = ".", press_freedom_num[, i])
  # Ändere Datentyp zu numerisch
  press_freedom_num[, i] <- as.numeric(press_freedom_num[, i])
}
# Erstelle Kopie des Datensatzes 
press_freedom_num <- press_freedom_orig

# Schleife
for (i in 2:8){
  # Ersetze Kommata durch Punkte
  press_freedom_num[, i] <- sub(pattern = ",", replacement = ".", press_freedom_num[, i])
  # Ändere Datentyp zu numerisch
  press_freedom_num[, i] <- as.numeric(press_freedom_num[, i])
}

# Überprüfung nach Schleife
str(press_freedom_num)

set.seed(123)
A <- matrix(sample(1:30, 20), nrow = 4)

Sie haben schon viel über for-Schleifen gelernt! Schauen wir uns daher zum Abschluss eine schwierigere Aufgabe an. Eine der grundlegenden Operationen der Matrixalgebra ist das Transponieren einer Matrix. Bei der Transponierung einer Matrix werden die Zeilen und Spalten vertauscht. Gegeben ist die folgende Matrix \(\mathbf{A}\).

set.seed(123)
A <- matrix(sample(1:30, 20), nrow = 4)
A
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   15   10    5    9    7
## [2,]   19   18   20   27   30
## [3,]   14   22   28    8   25
## [4,]    3   11   24   26   17

Vervollständigen Sie den Code, sodass das Element \(a_{ij}\) der Matrix \(\mathbf{A}\) (\(a_{ij} \in \mathbf{A}\)) zu Element \(a_{ji}\) der Matrix \(\mathbf{A^T}\) wird. Das hochgestellte \(T\) steht für Transponierte. In anderen Worten, das Element in der ersten Zeile und dritten Spalte der Matrix \(\mathbf{A}\), also \(a_{13}\), soll in \(\mathbf{A^T}\) an der Position in der dritten Zeile und ersten Spalte, d. h. \(a_{31}\), stehen. Es ist üblich, das Subskript \(i\) für die Zeilen und \(j\) für die Spalten zu verwenden.

Die Matrix \(\mathbf{A}\) wurde für Sie bereits erstellt.
# Erstelle leere Matrix mit 5 Zeilen und 4 Spalten
AT <- matrix(NA, nrow = 5, ncol = 4)

# Schleife über die Zeilen von A
for (i in 1:nrow(A)){
  # Schleife über Spalten von A
  for (j in 1:ncol(A)){
    AT <- 
  }
}

# Ausgabe von AT
AT
# Nutzen Sie die Matrix A, um der 
# Matrix AT die Werte zuzuweisen.
# Sie müssen also beide Matrizen indizieren.
# Matrizen indizieren Sie mit den einfachen
# eckigen Klammern. Die erste Position innerhalb der 
# eckigen Klammern indiziert die Zeilen, die zweite Position
# indiziert die Spalten.
AT[ , ] <- A[ , ]
# Denken Sie daran, dass beim Transponieren
# die Zeilen und Spalten vertauscht werden.
AT[ , ] <- A[i,j]
AT[j,i] <- A[i,j]
# Schleife über die Zeilen von A
for (i in 1:nrow(A)){
  # Schleife über Spalten von A
  for (j in 1:ncol(A)){
    AT[j,i] <- A[i,j]
  }
}
# Erstelle leere Matrix mit 5 Zeilen und 4 Spalten
AT <- matrix(NA, nrow = 5, ncol = 4)

# Schleife über die Zeilen von A
for (i in 1:nrow(A)){
  # Schleife über Spalten von A
  for (j in 1:ncol(A)){
    AT[j,i] <- A[i,j]
  }
}

# Ausgabe von AT
AT

Die von Ihnen erstellte Matrix AT (\(\mathbf{A^T}\)) sollte wie folgende Matrix aussehen.

##      [,1] [,2] [,3] [,4]
## [1,]   15   19   14    3
## [2,]   10   18   22   11
## [3,]    5   20   28   24
## [4,]    9   27    8   26
## [5,]    7   30   25   17

Die while-Schleife

Neben der for-Schleife gibt es noch die while-Schleife. Da die while-Schleife bei unseren Anwendungsfällen eher selten zum Einsatz kommt, behandeln wir sie hier nur der Vollständigkeit halber.

Eingangs hatten wir bereits erwähnt, dass die while-Schleife genutzt wird, wenn zu Beginn der Schleife nicht feststeht, wie oft die Schleife durchlaufen werden soll.

Der folgende Code-Block zeigt die Struktur einer while-Schleife in R.

while ( Bedingung ){
  # Führe einen Befehl aus
  # Führe den nächsten Befehl aus
}

Der Code innerhalb der runden Klammern (Bedingung) muss einen logischen Wert zurückgeben, d. h. entweder TRUE oder FALSE. Solange die Bedingung den Wert TRUE zurückgibt, wird der Code innerhalb der while-Schleife ausgeführt. Wenn diese Bedingung den Wert FALSE zurückgibt, wird die Schleife beendet und die nach der Schleife folgenden Befehle regulär abgearbeitet.

Schauen wir uns ein einfaches Beispiel an.

Im Zuge der folgenden while-Schleife wird x quadriert und das Ergebnis ausgegeben, solange x kleiner als 6 ist. Achtung: Es ist wichtig, dass wir x außerhalb der Schleife den Wert 0 zuweisen. Würden wir dies innerhalb der Schleife tun, dann würde zu Beginn jedes Schleifendurchlaufs der Wert von x auf 0 gesetzt und die Schleife somit nie enden.

Dies ist die größte Gefahr bei while-Schleifen. Wenn Sie einen Fehler machen, wird das Stoppkriterium nie erreicht. Das bedeutet, die Bedingung gibt nie FALSE zurück. In diesem Fall müssten Sie die Schleife manuell beenden.

# Erstelle x
x <- 0

while (x < 6) {
  # Quadriere x
  x_sq <- x^2
  # Ausgabe x_sq
  print(x_sq)
  
  # Erhöhe x um 1
  x <- x + 1
}

Nehmen wir für das nächste Beispiel an, Sie möchten berechnen, wie lukrativ es ist, Geld auf Ihrem Sparkonto anzulegen. Sie legen 10000 Euro an und erhalten pro Jahr 1 Prozent Zinsen. Vervollständigen Sie den Code an den Stellen ...., um herauszufinden, wie lange es dauert, bis Sie das erste Mal mehr als 12000 Euro auf Ihrem Sparkonto haben?

my_savings <- 10000
year <- 0

while (my_savings < 12000) {
  # Berechne my_savings
  my_savings <- my_savings + (.... * 0.01)
  year <- .... + 1
  cat("Nach ", ...., " Jahr(en) haben Sie ", ...., " Euro.\n", sep = "")
}
# Multiplizieren Sie my_savings zunächst mit dem Zinssatz.
# Multiplizieren Sie my_savings zunächst mit dem Zinssatz.
my_savings <- my_savings + (my_savings * 0.01)
# Addieren Sie nach der Berechnung von my_savings 
# eins zu year.
# Addieren Sie nach der Berechnung von my_savings 
# eins zu year.
year <- year + 1
# Abschließend müssen Sie noch die Objekte
# my_savings und year an die richtigen Positionen
# in der Funktion cat() setzen.
# Abschließend müssen Sie noch die Objekte
# my_savings und year an die richtigen Positionen
# in der Funktion cat() setzen.
cat("Nach ", year, " Jahr(en) haben Sie ", my_savings, " Euro.\n", sep = "")
my_savings <- 10000
year <- 0

while (my_savings < 12000) {
  # Berechne my_savings
  my_savings <- my_savings + (my_savings * 0.01)
  year <- year + 1
  cat("Nach ", year, " Jahr(en) haben Sie ", my_savings, " Euro.\n", sep = "")
}

Sehr gut!
Sie haben den Abschnitt Schleifen erfolgreich absolviert!



Pakete

.packages <- function(all.available = FALSE, lib.loc = NULL){
  if (is.null(lib.loc)) 
    lib.loc <- .libPaths()
  if (all.available) {
    ans <- character()
    for (lib in lib.loc[file.exists(lib.loc)]) {
      a <- list.files(lib, all.files = FALSE, full.names = FALSE)
      pfile <- file.path(lib, a, "Meta", "package.rds")
      ans <- c(ans, a[file.exists(pfile)])
    }
    return(gsub('stats', '',unique(ans)))
  }
  s <- search()
  s <- s[substr(s, 9L, 20) != "kableExtra"]
  s <- s[substr(s, 9L, 20) != "learnr"]
  s <- s[substr(s, 9L, 20) != "shiny"]
  s <- s[substr(s, 9L, 20) != "rmarkdown"]
  invisible(.rmpkg(s[substr(s, 1L, 8L) == "package:"]))
}

Einer der größten Vorteile von R ist die enorme Anzahl an Add-on-Paketen – meist nur Pakete (Englisch: packages) genannt. Ein Paket ist vereinfacht gesagt eine Zusammenstellung von Funktionen, Datensätzen und einer dazugehörigen Dokumentation. Es gibt zum Beispiel Pakete für Datenaufbereitung, Web-Scraping, zum Erstellen von Grafiken, für unterschiedliche statistische Modelle und vieles mehr. Es gibt sogar Pakete, die dabei helfen, Pakete zu erstellen. Derzeit gibt es 15282 Pakete beim Comprehensive R Archive Network (CRAN). CRAN ist ein weltweites Netzwerk von Servern, das R-Pakete zum Herunterladen verfügbar macht.

Wenn Sie R später auf Ihrem PC installieren, sind bereits einige Pakete enthalten. Die meisten Pakete müssen Sie aber selbst installieren.

In R installieren Sie ein Paket mit der Funktion install.packages() wie folgt:

install.packages("Paketname")

Der Name des Paketes, das Sie installieren möchten, muss zwischen Anführungszeichen stehen.

Pakete laden

Nachdem Sie ein Paket installiert haben, können Sie es allerdings nicht direkt in R nutzen. Die Installation legt das Paket nur in einem speziellen Ordner auf Ihrem PC ab und macht es für R verfügbar. Um ein Paket und dessen Funktionen in R zu nutzen, müssen Sie das Paket laden.

Zum Laden eines Paketes verwenden wir die Funktion library():

library(Paketname)

# Oder auch:
library("Paketname")

Das Paket ggplot2 zum Erstellen von Grafiken wurde bereits für Sie installiert.

install.packages("ggplot2")


Laden Sie nun das Paket ggplot2 mit der Funktion library().

# Lade ggplot2
# Lade ggplot2
library(ggplot2)

Wenn Sie keine Fehlermeldung erhalten, wurde das Paket geladen.

Wenn ein Paket nicht geladen werden kann, zum Beispiel, weil es nicht installiert wurde oder Sie den Paketnamen falsch geschrieben haben, erhalten Sie eine Fehlermeldung.

Probieren Sie es aus. Versuchen Sie, das Paket ggplot_3 zu laden. Sie sollten eine Fehlermeldung erhalten, da es das Paket ggplot_3 in R nicht gibt.

# Lade ggplot_3
# Lade ggplot_3
library(ggplot_3)

Sie erhalten natürlich auch eine Fehlermeldung, wenn Sie versuchen, ein Paket zu installieren, welches es nicht gibt.

install.packages("ggplot_3")
Warning in install.packages :
   package 'ggplot_3' is not available (for R version 3.6.1)

Wenn Sie sichergehen wollen, dass ein Paket geladen wurde, können Sie sich die Namen aller geladenen Pakete ausgeben lassen.

Führen Sie den Code in der nachstehenden Box aus, um sich alle geladenen Pakete anzeigen zu lassen.

# Zeige geladene Pakete an
(.packages())

Wie Sie sehen, ist das Paket ggplot2 nicht aufgeführt, obwohl wir es zuvor geladen haben.
Dies liegt daran, dass jede Code-Box im Grunde wie eine eigene R-Sitzung (Englisch: session) funktioniert.

Jedes Mal, wenn Sie R starten (oder neu starten), müssen Sie die Pakete, die Sie nutzen möchten, erneut laden.

Ersetzen Sie .... in der folgenden Code-Box so, dass das Paket ggplot2 geladen wird.

# Zeige geladene Pakete an
# (vor dem Laden von ggplot2)
(.packages())

# Lade ggplot2
....

# Zeige geladene Pakete an
# (nach dem Laden von ggplot2)
(.packages())
# Lade ggplot2
library(ggplot2)

Erst in der zweiten Auflistung der geladenen Pakete ist ggplot2 aufgeführt, d. h., nachdem Sie es geladen haben.

Wenn Sie Ihren Code in einem Skript speichern, sollten Sie zu Beginn des Skriptes alle Pakete laden, die Sie zum Arbeiten benötigen. In manchen Fällen kann es aber auch Sinn machen, ein Paket nicht direkt am Anfang des Skripts zu laden.

Wenn Sie das Laden eines Paketes rückgängig machen möchten, nutzen Sie die Funktion detach() wie folgt:

# Detach Paket
detach("package:Paketname", unload = TRUE)

Verändern Sie den folgenden Code an den Stellen mit .... so, dass das Laden des Paketes ggplot2 rückgängig gemacht wird.

# Lade ggplot2
library(....)

# Zeige geladene Pakete an
(.packages())

# Detach ggplot2
detach("package:....", ....)

# Zeige geladene Pakete an
(.packages())
# Sie müssen zuerst den
# Paketnamen ergänzen.
# Detach ggplot2
detach("package:ggplot2", ....)
# Denken Sie daran, 
# das Argument unload zu ergänzen
# Detach ggplot2
detach("package:ggplot2", unload = TRUE)
# Lade ggplot2
library(ggplot2)

# Zeige geladene Pakete an
(.packages())

# Detach ggplot2
detach("package:ggplot2", unload = TRUE)

# Zeige geladene Pakete an
(.packages())

Konflikte

Es kann passieren, dass es in zwei unterschiedlichen Paketen eine Funktion mit demselben Namen gibt, z. B. my_function(). Wenn Sie beide dieser Pakete laden, kommt es zu einem Konflikt. R weiß in diesem Fall nicht, ob Sie my_function() aus dem ersten oder dem zweiten Paket nutzen möchten. Um diesen Konflikt aufzulösen, wird der Funktion aus dem zuletzt geladenen Paket von R Vorrang gegeben.

Das Pakte Hmisc enthält viele nützliche Funktionen zur Analyse von Daten und wurde bereits für Sie installiert.

install.packages("Hmisc")

Laden Sie das Paket Hmisc und schauen Sie sich die Meldungen an. Klicken Sie dann auf Continue.

# Lade Hmisc
# Lade Hmisc
library(Hmisc)

Sie sehen, dass Hmisc zunächst weitere Pakete lädt, u. a. lattice und ggplot2. Darunter wird angezeigt, bei welchen Funktionen es zu Konflikten kommt.

Die Funktion summarize() gibt es sowohl im Paket dplyr als auch in Hmisc. Trotz des selben Namens haben beide Funktionen unterschiedliche Verwendungszwecke und führen nicht den gleichen Code aus.

Die folgenden Meldungen teilen uns mit, dass die Funktion summarize() aus dem Paket Hmisc Vorrang hat. Das bedeutet, wenn Sie jetzt die Funktion summarize() ausführen, greift R auf diese Funktion im Paket Hmisc zu. Gleiches gilt für die Funktion src.

Die Funktionen aus Hmisc erhalten hier Vorrang vor den Funktionen aus dplyr, da wir Hmisc nach dplyr geladen haben. Würden wir zuerst Hmisc und dann dplyr laden, erhielten die Funktionen aus dplyr Vorrang.

Attaching package: 'Hmisc'
The following objects are masked from 'package:dplyr':
 
    src, summarize

Angenommen wir haben Hmisc geladen, möchten aber die summarize()-Funktion aus dem Paket dplyr verwenden. Wir könnten das Laden von Hmisc mit detach() rückgängig machen, es gibt jedoch noch eine andere Möglichkeit.

Wenn wir vor die Funktion den Namen des Paketes gefolgt von zwei Doppelpunkten schreiben, ruft R die Funktion aus diesem speziellen Paket auf Paketname::Funktionsname.

Das sieht dann wie folgt aus:

# Nutze my_function()
# aus my_package
my_package::my_function()

Wir können diese Möglichkeit nutzen unabhängig davon, ob es einen Konflikt der Funktionsnamen gibt oder nicht. Wenn wir einmalig eine spezielle Funktion aus einem Paket nutzen wollen, ohne das Paket mit library() zu laden, können wir ebenfalls Paketname::Funktionsname verwenden.

Für die nächste Übung nutzen wir wieder den SIPRI-Datensatz zu internationalen Transfers konventioneller Waffen, den wir bereits im Abschnitt data frames genutzt haben.

Führen Sie zunächst den nachstehenden Code-Block aus, ohne Veränderungen vorzunehmen.

Passen Sie den Code dann so an, dass die Funktion summarize() aus dem Paket dplyr verwendet wird.

# sipri_data wurde bereits erstellt

# Lade Hmisc
library(Hmisc)

summarize(sipri_data, 
          Mean_2017 = mean(exports_17), 
          Mean_2018 = mean(exports_18), 
          Difference = mean(exports_18) - mean(exports_17)
          )
# sipri_data wurde bereits erstellt

# Lade Hmisc
library(Hmisc)

dplyr::summarize(sipri_data, 
          Mean_2017 = mean(exports_17), 
          Mean_2018 = mean(exports_18), 
          Difference = mean(exports_18) - mean(exports_17)
          )

Woher weiß ich, welches Paket ich installieren soll?

Sie können natürlich in der Liste der 15282 beim CRAN verfügbaren Pakete nach einem geeigneten Paket suchen.

Das ist jedoch ein sehr aufwendiges und nicht zu empfehlendes Vorgehen.

Oft ist die Nutzung einer Suchmaschine mit entsprechenden Schlüsselwörtern hilfreich. Sie können auch auf dem Blog R-bloggers nach Paketen zu spezifischen Themenbereichen suchen.

Für den Anfang sollten Sie sich auf jeden Fall die kurze Liste nützlicher R-Pakete von RStudio anschauen.

Installation R & RStudio

Die folgenden Videos zeigen, wie Sie R und RStudio auf Ihrem Computer installieren können.

Die ersten beiden Videos zeigen die Installation für Windows. Das dritte und vierte Video zeigen die Installation für macOS.

Die in den Videos verwendeten Internetadressen sind:

Installation von R (Windows)

Installation von RStudio (Windows)

Installation von R (macOS)

Installation von RStudio (macOS)

RStudio

RStudio ist eine integrierte Entwicklungsumgebung (IDE: integrated development environment), die uns das Arbeiten mit R erleichtert. RStudio hat verschiedene Bereiche. Im folgenden Bild sehen wir die Konsole auf der linken Seite. Wenn wir Code in die Konsole eingeben und Enter drücken, wird der Code ausgeführt.

Auf der rechten Seite sehen wir die Hilfsseite, die wir bereits kennen. Wir können die Hilfsseite mit ?Funktionsname aufrufen.

Meist werden wir Code nicht direkt in die Konsole eingeben, sondern in ein Skript schreiben, das wir speichern können. Das hat den Vorteil, dass wir 1.) unsere Arbeit so (auch für andere) dokumentieren können, 2.) das nächste Mal mit unserer Arbeit nahtlos fortfahren können und 3.) auch in einem Jahr noch detailliert nachvollziehen können, was wir gemacht haben.

Auf der linken Seite sehen Sie ein Skript mit Code. Sie können ein neues Skript öffnen, indem Sie oben links unter “File” auf das kleine, grüne Kreuz drücken und “R Script” auswählen.

Der Code in dem Skript wurde ausgeführt (siehe Konsole) und hat eine Grafik erzeugt. Diese Grafik wird auf der rechten Seite im Plot-Bereich dargestellt.

Über dem Plot-Bereich auf der rechten Seite wird angezeigt, welche Objekte (z. B. Vektoren, Matrizen, data frames oder Listen) wir erstellt oder geladen haben. Diese Objekte befinden sich in der globalen Umgebung (global environment).

Aussehen ist alles…

Das wichtigste bei einer IDE (integrated development environment) ist natürlich, dass sie gut aussieht. Wenn Sie über die Menüleiste am oberen Bildschirmrand zuerst “Tools” und dann “Global Options…” auswählen, öffnet sich ein Fenster, das Sie im folgenden Bild sehen.

Wenn Sie in diesem Fenster auf der linken Seite “Appearance” auswählen, erscheint ein Menü, über das Sie das Aussehen der Oberfläche von RStudio verändern können.

Impressum

Inhaltlich Verantwortlicher gemäß § 10 Absatz 3 MDStV
Lehrstuhl für Methoden der empirischen Sozialforschung
August-Bebel-Straße 89
14482 Potsdam
Tel.: 0049 (0)331 977 3570
Fax: 0049 (0)331 977 3811
E-Mail: sek-lmes@uni-potsdam.de

Realisation, Gestaltung und technische Betreuung
Lehrstuhl für Methoden der empirischen Sozialforschung
Fabian Class
E-Mail: fabclass@uni-potsdam.de

Haftungshinweis
Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für den Inhalt externer Links. Für den Inhalt der verlinkten Seiten sind ausschließlich die Betreiber verantwortlich. Die Texte und Fotos der Seiten sind urheberrechtich geschützt. Das Kopieren dieser Dateien und ihre eventuelle Veränderung sind daher ohne Genehmigung des Urhebers nicht gestattet.