Herzlich Willkommen zum zweiten Teil dieses Crashkurses, in dem du deine ersten Programmierschritte in R gehen wirst. Dafür solltest du bereits R und RStudio heruntergeladen haben. Sollte das noch nicht der Fall sein, kommst du hier zur Installationsparty.

Wir werden jetzt zusammen ein R-Skript durchgehen, dass du hier herunter laden kannst. Dieses Tutorial ist sozusagen ein zusätzliches Handbuch zu dem Skript. Du kannst selbst entscheiden, ob du lieber nur mit dem Skript herum probierst, oder ob du meine Anmerkungen und Erklärungen dazu durchgehst. Tatsächlich ist es ein Ordner, in dem sich mehrere R-Skripts, ein Datensatz, ein Ordner mit Geodaten und eine Datei mit der Endung Rproj befinden. Das tolle an dieser Datei: Wenn du sie doppelklickst, öffnet sich ein RStudio-Fenster, über das du alle Dateien, die in dem Ordner mit der Rproj-Datei liegen, einfach über ihren Namen einlesen kannst, statt mit dem kompletten Dateipfad. Die Rproj-Datei vereinfacht nämlich das Setzen des Working Directories.

Wenn du beispielsweise einen Datensatz mit dem Namen data.csv laden möchtest, musst du R normalerweise genau sagen, welche Datei du meinst. Liegt sie in deinem Download-Ordner, oder liegt sie auf deinem Desktop? Wenn du an einem bestimmten Projekt arbeitest, für das du alle Datensätze in einem Ordner hast, kann es daher sinnvoll sein, R von Anfang an zu sagen, dass du in diesem Ordner arbeitest. Das geht beispielsweise mit dem Befehl setwd(). In dem Code-Snippet siehst du, wie ich eine Datei ohne und mit gesetztem Working Directory in R einlese:

# R
data <- read.csv("/Users/timcke/interaktiv/projects/analysis/polls.csv")

setwd("/Users/timcke/interaktiv/projects/analysis")
data <- read.csv("polls.csv")

Mit setwd() zu arbeiten, wird dann nervig, wenn du mit mehreren Leuten am gleichen Skript arbeitest. Denn dann muss jede*r den eigenen setwd()-Befehl im Kopf des Skripts hinterlegen und die der jeweils anderen auskommentieren (also deaktivieren), bevor das Skript ohne Fehlermeldungen ausgeführt werden kann. Die Rproj-Datei nimmt dir das Setzen des Working Directory ab und zeigt dir im geöffneten RStudio-Fenster im File-Tab direkt alle R-Skripte aus dem Projektordner, die du nun komfortabel über einen Klick öffnen kannst. Wo auch immer deine Kolleg*innen den Ordner ablegen, auch hier öffnet der Doppelklick auf die Rproj-Datei ein RStudio Fenster mit dem korrekten Working Directory. Ein neues R-Projekt kannst du über File > New Project erstellen.

Lade also bitte den Ordner r_crashcourse herunter und öffne das R-Projekt mit einem Doppelklick auf r_crash.Rproj. Öffne das Skript basics.R über den File-Tab im Panel unten rechts. Je nachdem, was für ein Editortheme du gewählt hast, sind deine Highlight-Farben etwas anders. In jedem Fall solltest du sehen, dass Funktionen, Nummern und von Anführungszeichen umschlossene Zeichen farblich hervorgehoben sind. Das hilft uns sehr dabei, Code von anderen zu verstehen oder Zeichensetzungsfehler zu bemerken.

Außerdem fallen meine auskommentierten Erklärungen auf, die jeweils von einem Rautezeichen angeführt werden. Mit diesem Zeichen sagen wir R, dass alles Folgende kein Code ist, R also nicht versuchen soll, die Zeile auszuführen. R ignoriert diese Zeilen stattdessen.

Klicke in eine dieser Zeilen oder markiere mehrere und schicke sie in die Konsole (entweder über den Run-Button oder einen Shortcut). Entweder wird die Erklärung kommentarlos in der Konsole wiedergegeben (wenn du ihn markiert hattest), oder R ignoriert sie komplett und führt stattdessen die nächste Zeile aus (wenn du nur in die Zeile geklickt hattest).

R unterscheidet verschiedene Typen von Input. Auskommentierten Code haben wir schon kennengelernt. Damit R etwas als reinen Text und nicht Code-Text erkennt, musst du es in Anführungszeichen setzen. In R heißt reiner Text „characters“, in vielen anderen Programmiersprachen nennt man es „strings“. Diese verschiedenen Typen werden im Editor in verschiedenen Farben dargestellt. Zahlen werden in meinem Theme lila und characters gelb dargestellt. Weiß ist alles, was R als Funktion oder Variablenname interpretieren würde. Was das genau ist, erkläre ich gleich.

Die unterschiedlichen Typen von Input werden von R auch unterschiedlich interpretiert. Alle Nicht-Zahlen in Datensätzen werden von R als characters interpretiert. Wenn R einen Input nicht korrekt interpretiert, gibt die Konsole einen Fehler zurück. Das passiert beispielsweise beim Ausführen von Zeile 8. Weil der Text weder auskommentiert, noch in Anführungszeichen gesetzt ist, versucht R, ihn als Variablen oder Funktionen zu interpretieren. Doch zum einen findet R keine Funktion oder Variable, die „Text“ heißt, zum anderen meckert R, weil du scheinbar Variablen oder Funktionen hintereinander in der gleichen Zeile hast, ohne zu sagen, was du genau willst. Deshalb solltest du erklärenden Text immer auskommentieren. R meckert auch, wenn du die Zeile 7 ausführst, weil es keine Variable oder Funktion finden kann, die x heißt.

 

# R
# Crashkurs: Programmieren in R für Journalist*innen | Teil 2: Grundvokabeln
# -------------------------------------------------------------------------- 

# Kommentar
5 # Zahl
sum(5,4) # Funktion
x # Variablenname, den wir aber noch nicht vergeben haben. Deshalb sagt uns R, dass sie nicht zu finden ist.
Text ohne Auskommentierung, den R als Code behandelt und versucht, auszuführen. Das führt dazu, dass die R-Konsole meckert. 
"string, also Zeichen, die als Text interpretiert werden"

 

BASICS

R als Taschenrechner: Kommen wir jetzt zu den absoluten R-Basics! Als erstes wollen wir R als simplen Taschenrechner benutzen, um die Zeichen dafür kennenzulernen. Wie wir erwarten würden, stehen + und – für Addition und Subtraktion, * und / für Multiplikation und Division. Mit Hilfe der Runden Klammern kannst du die Punkt- vor Strichrechnung aushebeln. Es gelten also die ganz normalen mathematischen Regeln. Es macht für R auch keinen Unterschied, ob du 5+5 oder 5 + 5 schreibst.

# R
## Basics ##
# R als Taschenrechner benutzen
5 + 2 # Addition
7 - 4 # Substraktion
6*8 # Multiplikation
9/3 # Division
(9-3)*8 # Es gelten die ganz normalen Regeln der Mathematik 😉

 

Logische Vergleiche: Manchmal willst du Bedingungen angeben, wie „Gib mir nur alle Gemeinden aus, in denen die Linke die Fünf-Prozent-Hürde überschritten hat“. Dafür sind die logischen Vergleiche sehr praktisch. Wie du im Skript siehst, steht ein doppeltes Gleichheitszeichen für die Frage, ob die beiden Variablen gleich sind. Wenn du die Zeilen in der R-Konsole ausführst, bekommst du als Antwort auf diese Frage entweder „True“ oder „False“. Ergänze meine Beispiele gerne noch durch deine eigenen. Funktioniert das ganze beispielsweise auch für Strings?

# R
# Logische Vergleiche
5 == 2 # Ist 5 das gleiche wie 2?
5 == 5 # Ist 5 das gleiche wie 5?
5 > 2 # Ist 5 größer als 2?
5 >= 2 # Ist 5 größer oder gleich 2?

 

Zuweisungen: Omnipräsent in Skripten sind Zuweisungen. Indem du einen Namen mit einem Pfeilsymbol <- oder einem Gleichheitszeichen = mit einem Wert, Datensatz oder auch einer Funktionsanweisung (dazu später noch mehr) verbindest und die Zeile ausführst, weist du sie einander zu. Sobald du die Zeilen ausgeführt hast, bekommst du sie von RStudio im Environment-Panel angezeigt. Das ist super praktisch, wenn du irrsinnig viele Variablen und Datensätze zugewiesen hast und den Überblick verlierst, welche du nicht noch einmal vergeben solltest, um sie nicht ungewollt zu überschreiben.

Das Ganze funktioniert natürlich auch mit Strings. Diese können wir zwar nicht addieren, mit der Funktion paste() können Strings aber aneinander gereiht werden. In Zeile 37 kannst du sehen, dass wir Strings und Zahlen, sogar Berechnungen innerhalb von paste() aneinander reihen können. Ich habe das in einer Analyse benutzt, um mir automatisch einen Ergebnissatz ausgeben zu lassen. Dabei habe ich R eine Korrelationsberechnung ausführen lassen, die abhängig davon, ob das Ergebnis einen bestimmten Wert überschritten hat (Stichwort: Logische Vergleiche!) einen Satz mit paste() gebaut hat, der mir die Variablennamen und die Zusammenhangsstärke genannt hat.

# R
# Zuweisungen
x <- 3 # Mit dem Pfeilsymbol "x" den Wert 3 zuordnen
y = 5 # Das gleiche geht auch mit dem Gleichheitszeichen

# Du kannst nun mit y und x rechnen:
x + y
xy <- x+y

# Wir können auch Strings zuweisen
text_1 <- "R"
text_2 <- "is awesome!"
paste(text_1, text_2) # paste() setzt Strings zusammen und speichert sie wieder als String
paste("Das Ergebnis von", x, "plus", y, "ist", x+y)

var_1 <- 3 # funktioniert!
var-1 <- 3 # funktioniert nicht!

Generell solltest du bei Variablennamen immer darauf achten, dass sie nicht zu lang aber trotzdem leicht zu verstehen sind. Außerdem dürfen sie keine Sonderzeichen enthalten außer Unterstriche oder Punkte. Alle anderen Zeichen sind in R mit irgendeinem Zweck hinterlegt und verwirren das Programm.

 

FUNKTIONEN UND PAKETE

Ein paar basic Funktionen: Funktionen sind wunderbar, denn sie fassen komplexere Anweisungen für uns zusammen und vereinfachen viele unserer Aufgaben. Dafür brauchen sie von uns nur einen passenden Input. Als kleines Beispiel die Funktion sum(): Diese Funktion berechnet die Summe aus den Zahlen, die wir ihr kommagetrennt geben. Statt 5+4 können wir also sum(5,4) schreiben. Was in diesem Fall keine große Zeitersparnis ist, macht einen großen Unterschied, wenn wir komplexe mathematische Formeln anwenden wollen oder Berechnungen unabhängig vom Input automatisiert ausführen wollen.

# R
## Funktionen und Pakete ##
# Ein paar basic Funktionen
?sum() # Hilfeseite aufrufen
c(3,6,5) # Zahlen zu Vektoren verbinden
mean(c(1,5,8,3,22,122)) # arithmetisches Mittel
median(c(1,5,8,3,22,122)) # Median
round(3.525312, 2) # Zahl runden auf zwei Nachkommastellen. P.S.: Dezimalzahlen werden in R mit Punkten getrennt!!

Wie gesagt ist das hier ein Crashkurs, deshalb zeige ich dir an dieser Stelle nur ein paar Funktionen und erkläre an einem einfachen Beispiel, wie du selbst Funktionen bauen kannst. Generell gibt es für fast alles schon Funktionen, die du recht leicht durch googlen findest, wenn du „R function for doing this and that“ suchst. Idealerweise googlest du immer auf Englisch, denn die Wahrscheinlichkeit, etwas passendes zu finden, ist dann viel höher. Gute Seiten für R-Fragen sind auch Stack Overflow und GNU.

Wenn du R frisch heruntergeladen hast, enthält es schon alle möglichen Funktionen, die sogenannten Base-Funktionen. Dazu gehört beispielsweise die Funktion sum(). Über den Befehl ?Funktionsnname kannst du dir die Dokumentation zu einer Funktion anschauen. Diese Seiten sind immer auf Englisch und meistens viel zu kompliziert geschrieben. Trotzdem können sie sehr praktisch sein, weil sie dir erklären, wofür die Funktion verwendet werden kann und was sie als Input benötigt oder was du alles einstellen kannst. Außerdem gibt es am Ende der Hilfeseite immer einige Beispiele für den Gebrauch der Funktion, die oft weiterhelfen können. Manchmal hilft aber auch nur googlen oder fragen.

Eine ziemlich unscheinbare, in R aber sehr elementare Funktion ist c(). Mit ihr kann man Zahlen und Strings zu sogenannten Vektoren verknüpfen. Vektoren spielen in R eine wichtige Rolle, weil jede Zahl und jeder String von R als Vektor interpretiert wird. Die Zahl 5 ist für R beispielsweise ein Zahlenvektor, der nur eine einzige Zahl enthält. Wir können aber auch mehrere Zahlen mit c() zu einem Vektor verknüpfen. Das zu tun ist für einige Funktionen wichtig, damit sie die Zahlenfolge als zusammenhängenden Input wahrnehmen. Nehmen wir beispielsweise die Funktion mean(), welche das arithmetische Mittel, also den Durchschnitt berechnet. Wenn du mean(1,5,8,3,22,122) in die Konsole tippst, wirst du 1 als Ergebnis bekommen. Leider akzeptiert die Funktion ganz ohne Fehlermeldung, dass du allerlei Argumente als Input eingibst, mit denen mean() gar nichts anfangen kann, und verwendet für die Berechnung nur die erste Zahl.

Wenn du die Hilfeseite von mean() aufrufst, kannst du sehen, dass die verschiedenen Input-Argumente mit einem Komma getrennt an die Funktion gegeben werden. Das erste Argument ist x, das Objekt, von dem der Durchschnitt berechnet wird. Weitere Argumente sind nur optional, das zeigen die drei Punkte an. Zwar kann die Funktion unmöglich wissen, welche Argumente du mit 5,8,3,22 und 122 belegen wolltest, die 1 nimmt sie aber als das Objekt x an, da dieses in ihrer Dokumentation ebenfalls an erster Stelle steht. Wir können x auch benennen: Gibst du beispielsweise mean(1,5,8,3,22,x = 122) ein, wird das Ergebnis 122 sein. Das ist aber nicht, was wir wollten. Wir wollten den Durchschnitt von der gesamten Zahlenmenge. Um der Funktion klarzumachen, dass die Zahlen zusammengehören, können wir sie zu einem Vektor verbinden: mean(c(1,5,8,3,22,122)).

 

Pakete mit Zusatzfunktionen laden: Probiere gerne noch ein wenig mit den Funktionen herum, die ich dir ins Skript geschrieben habe, oder ergoogle dir noch weitere! Je spezifischer die Berechnungen und Funktionen, die du suchst, desto wahrscheinlicher ist es, dass du zusätzliche R-Pakete installieren und laden musst, um auf sie zugreifen zu können. Ein Funktionenpaket, mit dem ich immer arbeite, ist das tidyverse. Genau genommen ist dieses Paket sogar ein Paket aus mehreren Paketen, nämlich unter anderem tidyr, dplyr und ggplot2. Das tidyverse-Paket enthält alle Zusatzfunktionen dieser drei äußerst mächtigen Pakete und ist ein Liebling – nicht nur aller R-nutzenden Datenjournalist*innen. Wir werden die Funktionen erst im dritten Teil des Crashkurses nutzen, trotzdem möchte ich dir an dieser Stelle kurz zeigen, wie du Pakete installieren kannst.

Alles, was du dazu wissen musst, ist der Name des Pakets. Dann kannst du es über die Funktion install.packages() installieren. Doch installiert ist nicht gleich geladen! Um auch wirklich auf die Funktionen zugreifen zu können, musst du das Paket vor dem Benutzen mit dem Befehl library() öffnen. Installieren musst du das Paket nur einmal. R nervt dich sogar mit einem Warnhinweis, wenn du die Installation mehrfach ausführen willst. Deshalb kommentierst du die Zeile am besten aus, sobald das Paket installiert ist. Laden musst du das Paket aber mit jeder neuen R-Session erneut.

Nervig wird dieses Funktionen-Gespann, wenn man mehrere Pakete installieren und laden möchte. Ich habe mir deshalb eine Funktion geschrieben, die als Input die Paketnamen bekommt und dann installiert und lädt, abhängig davon, ob das Paket bereits installiert und geladen ist. Das war aber gar nicht nötig, weil es diese Funktion bereits gibt! Sie heißt needs() und wird in diesem Übungsskript einmal beispielhaft installiert und geladen. Danach fragt needs() dich, ob es sich automatisch selbst laden darf, wenn du es benutzt. Wenn du zustimmst, kannst du ab sofort alle Pakete installieren und laden, indem du ihre Namen kommagetrennt an needs() übergibst, wie du es im Skript siehst.

# R
# Pakete mit Zusatzfunktionen laden
needs(tidyverse) # Wenn du needs noch nicht installiert hast, gibt dir R hier einen Fehler, weil es die Funktion nicht kennt
install.packages("needs") # Funktion installieren (Internetverbindung notwendig!)
library(needs) # Funktion laden
needs(tidyverse) # Funktion benutzen

Ein Nachteil von install.packages(), den needs() ebenfalls hat, ist, dass wir hier nirgends die Paketversion angeben können, die wir gerne hätten. Da R Open Source ist, gibt es immer wieder Paket-Updates, die manchmal ungewünschte Nebenwirkungen haben. Es kann beispielsweise passieren, dass ein altes Skript mit der neuen Paketversion nicht mehr fehlerfrei läuft, da sich Funktionalitäten oder Bezeichnungen geändert haben. Es gibt aber die Möglichkeit, ganz bestimmte Versionen von Paketen zu laden. Mehr dazu erfährst du hier.

 

Eigene Funktion schreiben: Manchmal hilft es alles nichts, und du musst eine eigene Funktion schreiben. Das ist aber etwas, das mit der Zeit kommt und das du auf keinen Fall direkt einwandfrei beherrschen musst. Ich zeige es dir hier nur einmal an einem einfachen Beispiel, damit du grundsätzlich weißt, wie das funktioniert. Mit der Zeit wirst du R immer besser kennenlernen, und dann wird Funktionen zu schreiben zu einer der leichtesten Übungen.

Für das Schreiben von Funktionen musst du dir über drei Hauptteile Gedanken machen:

1. Was ist das Ziel, der gewünschte Output meiner Funktion?

2. Was für einen Input braucht meine Funktion? Welche Voraussetzungen muss dieser erfüllen?

3. Welche universellen Schritte sind in welcher Reihenfolge nötig, um vom Input zum Output zu kommen?

# R
# Eigene Funktion schreiben
myfunction <- function(x,y){
  return(paste("Das Ergebnis von", x, "plus", y, "ist", x+y))
}

myfunction(1,5)
myfunction(-5,4)
myfunction(2,"string") # Fehler, da x+y hier nicht berechnet werden kann

myfunction2 <- function(x,y){ ifelse(x>y, return(x), return(y)) # Bedingter Output
}

myfunction2(3,4)
myfunction2(4,3)

Im Skript siehst du, dass ich eine Funktion namens myfunction() geschrieben habe. Eigene Funktionen können wir mit der Funktion function(){} schreiben. In die runden Klammern schreiben wir die Input-Argumente, in die geschweiften unsere Anweisungen samt dem gewünschten Output. Ziel meiner Funktion myfunction() ist es, den Satz, den wir weiter oben im Skript schon einmal mit paste() gebaut haben, für jegliche zwei Zahlen zu erzeugen. Als Input möchte ich also zwei Zahlen haben, als Output lasse ich mir den Satz mit Hilfe der Funktion return() ausgeben. Wenn du den Code von myfunction() ausführst, erscheint die Funktion auch im Environment von RStudio und kann benutzt werden.

Die zweite Funktion, myfunction2(), möchte ebenfalls zwei Zahlen als Input haben. Dann vergleicht sie die beiden Zahlen und gibt abhängig von dem Ergebnis eine andere Antwort als Output. Ich benutze dafür die Funktion ifelse(). Wenn x größer ist als y, gibt die Funktion x aus. Wenn x nicht größer als y ist, gibt die Funktion y aus.

Versuche dich gerne noch an deinen ersten eigenen Funktionen, aber verzweifle nicht, wenn dir das erstmal nur mit einfachen Anweisungen gelingt. Programmieren lernt man am besten nach dem Motto „try and error“. Vor allem Fehlermeldungen richtig interpretieren zu können, kommt erst mit der Zeit. Die sind nämlich manchmal weniger eindeutig, als man es sich wünschen würde.

 

DATEN

Kommen wir jetzt zum letzten Teil der R-Grundvokabeln für Journalist*innen: Daten und Datensätze einlesen, verändern und abspeichern.

Vektoren: Wir haben eben schon einmal kurz Vektoren benutzt, sozusagen die kleinste Einheit, in der R Daten speichert. Die Anzahl der Werte in einem Vektor kann zwischen 1 und unendlich vielen liegen. Die Funktion dafür ist c(). Praktisch ist aber auch der Doppelpunkt. Mit ihm können wir alle Zahlen zwischen der ersten und zweiten in Einer-Schritten in einen Vektor packen. Das nimmt uns vor allem Arbeit ab, wenn wir zum Beispiel einen Datensatz nach der Größe einer Spalte sortieren und dann nur die ersten zehn Zeilen haben möchten.

Wir können Zahlen, aber auch Characters in einen Vektor packen. Dabei musst du immer beachten, dass R einen Vektor nicht als Gemischtwarenladen abspeichert. Sobald ein einziger Wert in einem Vektor ein Character ist, wird der ganze Vektor als String abgespeichert. Da Spalten von Datensätzen für R nichts anderes sind als Vektoren, kann es dir öfter passieren, dass du Rechnungen nicht ausführen kannst, weil R eine augenscheinlich aus Zahlen bestehende Spalte als Characters abgespeichert hat. Nicht selten liegt das daran, dass irgendwo in der Spalte ein String vorkommt, beispielsweise der Eintrag „keine Daten“. Den gilt es dann zu entfernen oder mit NA, dem Platzhalter für fehlende Werte, zu ersetzen. Dann erst kann eine Spalte über die Funktion as.numeric() als numerisch abgespeichert werden.

# R
## Daten ##
# Vektoren
vec <- c(1,2,3,4,5)
vec2 <- 6:10 # Vektor aus allen Zahlen zwischen der ersten und der zweiten in Einer-Schritten
strnum <- c("eins","zwei",3) # sobald Strings in einem Vektor vorkommen, werden auch die vorkommenden Zahlen als Strings gespeichert

 

Datensätze: Wie gesagt, Spalten von Datensätzen sind für R nichts anderes als Vektoren. Wir können Vektoren der gleichen Länge, also mit der gleichen Anzahl an Elementen, mit der Funktion data.frame() zu einem Datensatz verknüpfen. Weisen wir dem Datensatz einen Namen zu, können wir ihn uns in der Konsole anzeigen lassen. Er erscheint aber auch mit einer kleinen Zusammenfassung im RStudio-Environment-Panel. Mit einem Klick auf den Namen in diesem Panel wird die Funktion View() ausgeführt, die wir auch selbst in die Konsole schreiben könnten. Diese öffnet den Datensatz in einem zusätzlichen Tab im Skript-Panel. Hier können wir den Datensatz filtern, durchsuchen oder nach Spalten sortieren.

# R
# Datensätze
df <- data.frame(col1 = vec, col2 = vec2, col3 = c("a", "b", "c", "d", "e")) # Alle Spalten müssen die gleiche Länge haben!
df # Datensatz in Konsole anzeigen
View(df) # Datensatz als filter- und sortierbare Tabelle öffnen

df[1] # nimmt nur die erste Spalte
df[1:2] # nimmt nur die ersten beiden Spalten
df[c(1,3)] # nimmt nur die erste und dritte Spalte

df[1,] # nimmt nur die erste Zeile
df[1,3] # erste Zeile, dritte Spalte

df[1] + df[2] # Mit Spalten rechnen

Über eckige Klammern kannst du auf bestimmte Teile des Datensatzes zugreifen. Diese sogenannte Indizierung wirst du öfter benutzen, um beispielsweise alle Spalten mit Wahlstimmen durch die Anzahl gültiger Stimmen zu teilen. Spalten mit ihrer Position im Datensatz anzusprechen kann aber auch nervig werden, wenn du beispielsweise sehr viele Spalten hast und erst einmal herausfinden musst, die wievielte deine gewünschte Spalte ist.

Wenn deine Spalten Namen haben, kannst du diese auch mithilfe des Dollar-Operators ansprechen. Indem du das Dollarzeichen nutzt, um eine noch nicht existierende Spalte anzusprechen, kannst du dem Datensatz sogar neue Spalten hinzufügen. Auch Funktionen lassen sich über den Dollar-Operator auf benannte Spalten anwenden.

# R
df$col1 # eine Spalte mit dem Namen ansprechen mit dem $-Operator
df$neu <- df$col1 + df$col2 # neue Spalte kreieren

sum(df[1])
sum(df$col1)

mean(df$col1)
median(df$col1)

 

Datensatz speichern und einlesen: Du kannst Datensätze in allen möglichen Formaten aus R auf deinem PC speichern. Ich finde das Dateiformat CSV (kurz für Comma Separated Values) immer am praktischsten, da es sich sowohl mit Text Editoren als auch mit Programmen wie Excel öffnen lässt. Du kannst einen benannten Datensatz aus R mit der Funktion write.csv() als kommagetrennte Werte abspeichern. Über die Hilfeseite kannst du dir anschauen, welche Argumente du hier setzen kannst. Gerade bei deutschen Datensätzen muss manchmal das Encoding, also die Art, wie Sonderzeichen codiert sind, festgelegt werden, damit Umlaute richtig abgespeichert werden.

Auch das Dezimalzeichen oder, ob das Trennzeichen ein Komma oder ein Semikolon sein soll, können wir der Funktion mitgeben. Gespeichert wird der Datensatz an dem Ort, zu dem der Pfad im Dateinamen zeigt. In unserem Fall, da ich keinen zusätzlichen Pfad mit angegeben habe, landen die Dateien test.csv und test2.csv direkt im Working Directory.

# R
# Datensatz speichern und einlesen
?write.csv
write.csv(df, "test.csv")
write.csv(df, "test2.csv", row.names = F) # was unterscheidet die beiden Dateien?

 

Das Ganze funktioniert natürlich auch andersherum: Mit read.csv() kannst du Datensätze, die als CSV auf deinem Computer liegen, auch einlesen. Auch hier lohnt es sich, die Hilfeseite aufzurufen. Viele Fehlermeldungen, die das Einlesen von Datensätzen erschweren, haben mit Encoding-Problemen zu tun. Wenn du statt üs und äs seltsame Zeichen siehst, versuch es mal mit dem Argument fileEncoding=“utf8″ oder „latin1“. Ich hatte aber auch schon viel Spaß mit französischen Namen, die Accents oder Apostrophen enthielten. Vor allem Apostrophen können einem die Suppe ganz schön versalzen, wenn R sie als Start von Quotes interpretiert. Dann nämlich ignoriert R das Zeichen, das den Beginn einer neuen Spalte signalisieren sollte, und denkt, dass alles bis zum nächsten Apostroph ein String sein soll.

Vor dem Einlesen lohnt es sich also immer, den Datensatz kurz in einem Text Editor anzuschauen und zu überlegen, welche Sonderzeichen Probleme machen könnten. Liest du einen Datensatz ein, und er hat statt der erwarteten Anzahl von Spalten nur eine, dann musst du wahrscheinlich das Separator-Zeichen mit dem Argument sep mit angeben. Schau dir dazu die Hilfeseite von read.csv() an oder google „R read.csv set separator“.

# R
# Datensätze einlesen
?read.csv
btw17 <- read.csv("btw17.csv")
View(btw17)

 

Als Datenjournalist*in wirst du sicher oft das Bedürfnis haben, Shapefiles, also beispielsweise die Umrisse von Ländern oder Wahlkreisen in R zu laden, mit anderen Datensätzen zu verbinden und die Shapes dann nach einem Wert einzufärben. Das alles geht auch mit den Grafikfunktionen von Base-R. Da ich dir aber vor allem zeigen will, wie ich und andere Datenjournalist*innen mit R arbeiten, zeige ich dir die ganze Visualisierungsprozedur im nächsten Teil des Crashkurses direkt mit den Funktionen des Tidyverse.

Bevor wir ins Tidyverse abtauchen, zeige ich dir aber noch kurz, wie du Shapefiles in R einliest. Dazu ist es wichtig zu wissen, dass Shapefiles in den verschiedensten Dateiformaten kommen können. Es gibt KML, ESRI Shapefiles, GeoJSON und einige mehr. Im Ordner wahlkreise_small liegen die Dateien eines ESRI Shapefiles. Wenn du mehr über Geodatenformate wissen möchtest, findest du hier ein paar Informationen. Für den Moment musst du nur wissen, dass alle Dateien in dem gleichen Ordner liegen müssen, damit R das SHP-File korrekt laden und darstellen kann.

Wenn du das Programm QGIS hast, kannst du auch die Dateien via Drag and Drop darin öffnen, um sie vor dem Einlesen in R zu inspizieren. Ich benutze auch oft das freie Webprogramm mapshaper.org, um einen Blick auf meine Geoshapes zu werfen. Unter dem Export-Button kannst du hier sogar Shapefiles in einem anderen Format herunterladen. Beispielsweise kannst du ein GeoJSON in Mapshaper öffnen und es dann als ESRI Shapefile exportieren. Am Rande: Das Tool ist auch großartig, um Shapes zu vereinfachen. Die Shapes werden dann immer einfacher dargestellt und die File-Größe verkleinert sich.

Um das ESRI-Shapefile in R einzulesen, benutzen wir die Funktion readOGR des Pakets rgdal. Wenn alle anderen Files im selben Ordner liegen wie das File mit der Endung shp, können wir dieses recht einfach ansprechen. Wenn alles geklappt hat, sieh dir gerne in Ruhe die Dateistruktur an. Beispielsweise mit der Übersichtsfunktion des Environment-Panels oder, indem du den zugewiesenen Namen in die Konsole gibst. Da dieses Dateiformat keine gleichlangen Spalten hat, funktioniert der View-Befehl hier nicht.

Als letztes weihen wir noch schnell dein RStudio Plot-Fenster mit einem Übersichtsplot des Shapefiles ein.

# R
needs(rgdal) # mit der Funktion readOGR vom Paket rgdal können wir Geodaten einlesen 
shp <- readOGR("wahlkreise_small/wahlkreise_small.shp") # Shapefile laden 
plot(shp) # Übersichtsplot

 

Das war wahrscheinlich ziemlich viel Input in einem einzigen Skript. Lass dir ruhig Zeit, geh nochmal alle Funktionen und Infos durch, probiere noch etwas herum, oder google dir noch ein paar Zusatzinformationen zu den R-Basics zusammen. Du bist mit mir gerade durch ziemlich viele R-Vokabeln gejagt, die ich selbst Schritt für Schritt mit vielen Übungsaufgaben gelernt habe. Es ist ganz normal, dass nicht sofort alles sitzt und du eventuell mit anderen Datensätzen auf Probleme stößt, die du nicht direkt bewältigen kannst. Das ist auch nicht weiter schlimm, denn durch solche Herausforderungen lernst du sehr viel mehr, als ich dir in einem Crashkurs beibringen kann.

Wenn du soweit bist, kannst du weiter gehen zu Crashkurs: Programmieren in R für Journalist*innen | Teil 3: Das Tidyverse, der letzte Teil dieses Crashkurses, in dem wir die Bundestagswahldaten ein bisschen präparieren, analysieren und visualisieren werden.

Wenn du Probleme oder offene Fragen hast, die dir das Internet nicht so richtig beantworten kann, dann hau am besten Journocode, die Datenjournalismus-Initiative, zu der ich auch gehöre, via Slack, Twitter oder Facebook an. Wir versuchen gerne, dir weiterzuhelfen!