Die folgende Notation wird in diesem Dokument benutzt:
R Code (den Du über copy & paste in Euer Script überführen und ausführen kannst) wird so dargestellt:
R_Code() # Raute ("Hashtag") kennzeichnet einen Kommentar; wird von R ignoriert = nicht ausgeführt
Die Ausgabe von Befehlen in R wird hier so dargestellt:
## [1] "Die Ausgabe eines R-Befehls"
Aufgaben zu den einzelnen Kapiteln werden eingerückt dargestellt:
Simple Aufgabe
Klicke den Button, um die Lösung aufzuklappen!
Hier steht dann die Lösung.
Zusatzaufgaben sowie wichtige Hinweise und Tipps haben folgende Buttons:
R ist eine interpretierte Sprache - so wie auch Python oder Matlab. Im Gegensatz zu kompilierten Sprachen (so wie C, C++ oder Fortran) wird jedes Kommando sofort ausgeführt (“interpretiert”).
Die Ausführung erfolgt in RStudio, indem man sich mit dem Cursor auf
eine ausführbare Zeile bewegt und dann in der Toolbar den
Run
-Button drückt. Alternative:
Strg + Enter
.
Beispiel Wir nutzen den print
-Befehl,
um eine Ausgabe im “Hallo Welt”-Stil zu erzeugen (traditionell die erste
Operation beim Erlernen einer Programmiersprache). Führt dazu folgende
Zeile wie beschrieben aus!
print("Hallo R!")
## [1] "Hallo R!"
Aufgabe 1
Schreibe Dein eigenes “Hallo”-Statement und führe es aus.
Du weißt nun, wie man eine Zeile ausführt. Anstatt jetzt einen
print
-Befehl auszuführen, könnt Ihr auch einfache
Rechenoperationen ausführen. Das Ergebnis der Operation gibt RStudio
direkt aus.
1+1
## [1] 2
2**3
## [1] 8
Aufgabe 2
Berechne das Ergebnis der Operation \((\frac{22}{11} * (1 + 5))^2\)
(22/11 * (1+5))^2
## [1] 144
Du kannst alles, was Du in einer R-Sitzung an Befehlen benutzt, auch speichern, um später daran weiterzuarbeiten oder eine Analyse zu wiederholen. Dies betrifft nur die Befehle; etwaige Daten oder Zwischenergebnisse werden dann wieder neu erzeugt.
Die einfachere Art, wenn es primär darum geht, Deinen Quelltext zu sichern: Einfach unter “Datei”-> “Speichern unter…” speichern. Mit dem erneuten Öffnen von RStudio werden die letzten Dateien meist gleich mitgeöffnet.
Markdown kennst Du vielleicht schon aus der Lektion “git-together”. Ein schlanke Sprache, um übersichtlich formatierten Text zu erstellen. Mit der Markdown-Synthax lassen sich eine vielzahl von Formatierungen umsetzen.
Auch in R kannst Du Markdown-Dateien erstellen und dann “rendern”
(also hübsch formatiert darstellen). Dafür gehst Du in RStudio unter
File
auf New File
und klickst dort auf
R Markdown...
. Ein Fenster öffnet sich, in dem Du Titel,
Autor und das standardmäßige Output-Format angeben kannst. Nachdem Du
auf OK
klickst, wird eine Rmd-Datei erstellt, die schon
einige grundlegende Infos und Beispiel-Befehle für R-Markdown enthält.
Wenn Du nun auf den Knit
-Button klickst, wird eine
HTML-Datei erzeugt, die sowohl formatierten Text als auch Code-Blöcke
enthält. Das geht dann so:
```{r, include=TRUE, eval=TRUE} (22/11 * (1+5))^2 ```
Je nach Optionen in den geschweiften Klammern werden diese Blöcke dann mit Quellcode dargestellt und/oder ausgeführt und in das Dokument eingebunden.
Aufgabe 3
Füge der Markdown-Datei folgende Elemente hinzu:
(i) eine weitere Überschrift,
(ii) eine Liste mit drei Elementen,
(iii) eine weitere Codeblockzeile, die “Hallo” ausgibt,
(iv) einen weiteren funktionierenden Hyperlink.
# Eine weitere Überschrift
Eine weitere Überschrift
* ein Element * noch eines * und Nummer Drei
- ein Element
- noch eines
- und Nummer Drei
```{r, include=TRUE, eval=TRUE} print("Hello again!") ```
print("Hello again!")
## [1] "Hello again!"
[Link zu nerdigen Cartoons](https://xkcd.com/)
Die Zuweisung von Variablen und das Arbeiten mit diesen Variablen ist ein wesentliches Element der Programmierung. Wir kennen das Konzept der Zuweisung aus der Mathematik:
a <- 1
b <- 1
c <- a + b
# Die folgende Zeile sorgt dafür, dass der Wert von c ausgegeben wird.
c
## [1] 2
Anstelle der Zuweisung <-
akzeptiert R auch ein
einigen vielleicht intuitiver erscheinendes =
. Beides hat
Vor- und Nachteile; beides funktioniert.
Im Prinzip ist das Zuweisen von Variablenwerten und das Arbeiten mit Variablen intuitiv. Für Neulinge mag aber überraschend sein, dass die Zuweisung sich nicht auf numerische Werte beschränken muss.
# Zuweisung einer Zeichenkette
a <- "Rosalind"
b <- "Franklin"
a
## [1] "Rosalind"
b
## [1] "Franklin"
Zeichenketten lassen sich in R mit paste
zusammenfügen.
paste(a,b)
## [1] "Rosalind Franklin"
Aufgabe 4
Recherchiere, wer Rosalind Franklin war.
Es gibt unterschiedliche Datentypen, die wir zuweisen können. Den
Datentyp einer Variable können wir über den class
Befehl
abfragen:
a <- 1
b <- "Rosalind"
c <- 1.5
d <- TRUE
class(a)
## [1] "numeric"
class(b)
## [1] "character"
class(c)
## [1] "numeric"
class(d)
## [1] "logical"
Einige Datentypen kann man durch Operationen sinnvoll verknüpfen, andere nicht.
Aufgabe 5
Verknüpfe die Variablen
a
,b
,c
undd
jeweils paarweise mit dem+
-Operator. Erläutere Deine Beobachtungen.a+b
## Error in a + b: nicht-numerisches Argument für binären Operator
a+c
## [1] 2.5
a+d
## [1] 2
b+c
## Error in b + c: nicht-numerisches Argument für binären Operator
b+d
## Error in b + d: nicht-numerisches Argument für binären Operator
c+d
## [1] 2.5
Man kann sich für alle Anwendungsfälle eine eigene Lösung zurechtprogrammieren. Oft haben andere das aber schon besser gemacht. Das Ergebnis kann man sich als “Paket” (package) (Synonym: Bibliothek/library) importieren und direkt nutzen. Es gibt Pakete für alles: numerische Operationen, Dateisystemoperationen, Grafikerstellung, Statistik - es gibt fast nichts, was es fast nicht gibt.
Beispiel: Wir installieren und laden das
sessioninfo
-Paket. Damit kann man Informationen über die
aktuelle R-Session abfragen und anzeigen lassen.
# Paket installieren
install.packages("sessioninfo")
# Paket laden
library(sessioninfo)
Das war’s schon. Wir überprüfen mal eine Funktion, die uns
sessioninfo
zur Verfügung stellt und lassen uns
Informationen über die verwendete Plattform ausgeben:
sessioninfo::platform_info()
## setting value
## version R version 4.2.2 (2022-10-31 ucrt)
## os Windows 10 x64 (build 19045)
## system x86_64, mingw32
## ui RTerm
## language (EN)
## collate German_Germany.utf8
## ctype German_Germany.utf8
## tz Europe/Berlin
## date 2023-10-27
## pandoc 2.19.2 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
Die Angaben unter value sehen bei Dir möglicherweise etwas
anders aus. Falls Du mit einigen Angaben unter setting nichts
anfangen kannst (Wofür steht zum Beispiel ui?), kann man in der
Dokumentation des Paketes nachschauen, welche Werte einem die Funktion
eigentlich ausspuckt. Darauf werden wir später in der Lektion noch
eingehen, wenn wir uns mit dem Suchen und Finden von Hilfe beschäftigen.
Wichtig für Dich ist jetzt vor allem: Die Funktionen eines importierten
Paketes kann man mit paketname::funktionsname
ansprechen.
Wenn man wie oben das Paket mit library
geladen hat, recht
auch der Funktionsname allein - solange es keine Namensvettern in
gleichzeitig geladenen Paketen gibt. Mehr zu Funktionen dann später!
Das Arbeiten mit Daten beinhaltet meist den Zugriff auf Dateien, welche diese Daten bereitstellen. Das Lesen und Schreiben von Daten bzw. Dateien ist naturgemäß eine zentrale Komponente der Datenverarbeitung. Zwei Aspekte sind dabei wichtig:
Der Speicherort einer Datei wird über den “Pfad” angegeben. Man unterscheidet zwischen “absoluten” und “relativen” Pfadangaben. Der relative Pfad gibt den Speicherort relativ zum Arbeitsverzeichnis an.
Das aktuelle Arbeitsverezichnis kann man sich über
getwd()
(get working directory) anzeigen lassen und über
setwd()
(set working directory) neu festlegen
# Arbeitsverzeichnis anzeigen lassen
getwd()
# Arbeitsverzeichnis neu festlegen
setwd("D:/emac/Documents/Lehre/UmweltDV/01_environment")
Bei Pfadangaben in R ist es wichtig, forward slashes (“/”) und keine backslashes (“\”, was die typische Windows-Schreibweise bei Pfadangaben ist) zu nutzen.
Aufgabe 6
Lege als Arbeitsverzeichnis den Ordner fest, in dem Dein R-Skript gespeichert ist. Das kannst Du entweder über
setwd()
machen oder über dasSession
-Menü in der Funktionsleiste oben:Session
>Set Working Directy
>To Source File Location
.
Versuchen wir nun einmal, eine Datei im aktuellen Verzeichnis zu
lesen. Wir nutzen dazu den Befehl read.table
read.table("example-file-1.txt", sep="\n")
## V1
## 1 Hallo Welt!
## 2 (in einer Datei im gleichen Verzeichnis versteckt)
Das Argument sep
teilt R mit, wodurch verschiedene
Einträge in der Datei voneinander getrennt sind (z.B. durch Leerzeichen,
Kommata etc.). Da wir keine Tabelle mit mehreren Einträgen in Zeilen
oder Spalten einlesen wollen, müssen wir R mitteilen, dass es keinen
field separator gibt.
Nun öffnen wir die Datei example-file-2.txt
, die in dem
Unterverzeichnis data
relativ zu unserem Arbeitsverzeichnis
liegt.
read.table("data/example-file-2.txt", sep="\n")
## V1
## 1 Hallo andere Welt!
## 2 (in einer Datei im Unterverzeichnis data versteckt)
Aller guten Dinge sind drei: Nun greifen wir über einen relativen
Pfad auf eine Datei zu, die nicht in unserem Arbeitverzeichnis liegt,
sondern in dem data
-Verzeichnis, welches eine Ebene darüber
liegt. Übergeordnete Verzeichnisebenen spricht man mit dem
..
-Element an.
read.table("../data/example-file-3.txt", sep="\n")
## V1
## 1 Hallo untergeordnete Welt!
## 2 (in einer Datei in einer Verzeichnisebene darüber versteckt)
Bislang haben wir immer relative Pfadangaben (relativ zum
Arbeitsverzeichnis) genutzt. Wenn man auf Dateien zugreifen möchte, die
auf dem Rechner “weit weg” vom Arbeitsverzeichnis liegen, können solche
relativen Pfade aber sehr mühsam umzusetzen sein. Man kann auch einfach
den vollständigen (absoluten) Pfad zu einer Datei angeben. Dieser ist
dann aber auf jedem System anders, weil jeder auf seinem Rechner andere
Verzeichnisstrukturen hat. Der absolute Pfad zu meiner Datei
example-file-1.txt
lautet zum Beispiel:
D:/emac/Documents/Lehre/UmweltDV/01_environment/example-file-1.txt
.
Aufgabe 7
Wie lautet der absolute Pfad zu dieser Datei auf Deinem System? Lies den Dateiinhalt unter Nutzung einer absoluten Pfadangabe.
Wir haben eben bereits Textdateien eingelesen. Dabei haben wir
einfach den gesamten Inhalt komplett ausgegeben. Meist wollen wir den
Dateiinhalt jedoch interpretieren. Oft wird in Textdateien eine Tabelle
abgelegt, deren Spalten mit Zeichen wie ;
oder
,
getrennt sind.
Lesen wir statt einer txt-Datei doch mal eine csv-Datei ein.
df <- read.table("../data/example-table.csv", sep=";", header=TRUE)
df
## temperature saturation
## 1 -30 0.51
## 2 -20 1.26
## 3 -10 2.87
## 4 -5 4.22
## 5 0 6.11
## 6 5 8.72
## 7 10 12.26
## 8 15 17.02
## 9 20 23.33
## 10 25 31.60
## 11 30 42.34
## 12 35 56.13
Die zusätzliche Angabe header=TRUE
bedeutet lediglich,
dass die Einträge der ersten Zeile als Spaltennamen interpretiert werden
sollen.
Im nächsten Termin wirst Du mehr über das Einlesen und Arbeiten mit solchen Dataframes lernen.
In diesem Kurs werden wir uns noch oft und ausführlich mit der Erstellung von Grafiken beschäftigen. Jetzt nur ganz kurz, weil wir gerade schonmal Daten aus einer Tabelle im Arbeitsspeicher haben…
plot(df$temperature, df$saturation,
type = "l",
main = "Sättigungsdampfdruck über Wasser (Magnus-Formel)",
xlab = "Temperatur (degC)",
ylab = "Sättigungsdampfdruck (hPa)")
Mehr dazu in den kommenden Wochen!
Hilf mir, es allein zu tun.
Dieses Zitat von Maria Montessori trifft natürlich auch auf die Programmierung zu. Hilfe finden, um Probleme zu lösen - das ist sicherlich die Schlüsselkompetenz. Nur die wenigstens wissenschaftlichen R-Nutzer sprechen fließend R, sondern stückeln sich ihren Code so gut es geht zusammen.
RStudio
In einer R-Umgebung (also auch in RStudio), kann man sich über
Funktionen über help
oder ?
informieren.
# Hilfe zum print-Befehl
help(print) # oder ?print
Wenn Du den help
-Befehl in der Konsole oder einem
R-Skript eingibst, wird Dir die Hilfe im Fenster unten rechts unter dem
Reiter Help
angezeigt. Dort gibt es noch eine weitere
Möglichkeit nach Hilfe zu suchen - einfach in der Suchleiste den
entsprechenden Befehl eingeben. Wenn Du den help
-Befehl in
einem R-Markdown verwendest, öffnet sich eine HTML-Seite mit der
Hilfe.
RStudio bietet aber mehr. Der Schlüssel ist die
Tab
-Taste (Tabulator). Wenn Du einen Befehl eingibst,
kannst Du zu jedem Zeitpunkt Tab
drücken und RStudio bietet
Dir dann Optionen an oder vervollständigt den Code. Außerdem kannst Du
auch F1 drücken, und die Hilfe zum Befehl unter dem Cursor wird
erscheinen.
Aufgabe 8
- Gib
pr
ein und drücke dannTab
. Was passiert?- Gib nun
pri
ein und drücke dannTab
. Beobachtung?
Wie Du vielleicht gerade schon gemerkt hast, wird einem so auch Hilfe über den Aufruf einer Funktion angezeigt - also zum Beispiel welche Argumente eine Funktion benötigt.
Aufgabe 9
Unter Abschnitt 6 haben wir die Funktion
platform_info()
vom Paketsessioninfo
verwendet und uns gefragt, wofürui
in der Ausgabe steht. Nutze die Hilfefunktionen, um es herauszufinden!# Hilfe direkt zur Funktion help(platform_info, package=sessioninfo) # Hilfe über das Paket und alle darin enthaltenen Funktionen help(package=sessioninfo)
In der Hilfe zur Funktion ist unter
Value
aufgeführt, was Dir die Funktion ausgibt - eine Liste mit einer Reihe von Elementen.ui
steht dabei für das user interface, wie zum Beispiel RStudio.
RStudio bietet bequemen Zugang zur eingebauten R-Hilfe. Oft löst das aber nicht das Problem zum Verständnis der Funktion oder Lösung eines Problems. Fast genauso oft hatten aber andere Menschen schon das gleiche Problem und sich online Hilfe geholt. Eine der besten Hilfeplattformen ist stackoverflow. Dort landet man bei einer normalen Websuche nicht selten. Aber es gibt auch andere Plattformen, auf denen man auf Antworten stößt. rseek.org ist eine Suchmaschine, die Eure Suche gezielt auf R-Belange einschränkt - “R” allein ist sonst eher ein unglücklicher Suchbegriff.
Suche auf Englisch - so findest Du meist die hilfreicheren Quellen.
Oft erzeugen Fehlermeldungen lange Gesichter. Aber fürchte Dich nicht. Freue Dich, dass R versucht, Deinen Code in Ordnung zu bringen. Wenn Du mit der Fehlermeldung nichts anfangen kannst, kopiere sie einfach in eine Websuche und lasst Dir dort die Lösung servieren.
Aufgabe 10
Führe die folgenden Codezeilen aus und überlege, was die Fehlermeldungen Dir sagen. Versuch die Fehler zu korrigieren, sodass der Code ausgeführt wird.
print(Hallo Welt) print "Hallo Welt" read.table("data/example-file1.txt", sep="\n")
print(Hallo Welt)
## Error: <text>:1:13: unerwartetes Symbol
## 1: print(Hallo Welt
## ^
print "Hallo Welt"
## Error: <text>:1:7: unerwartete Zeichenkettenkonstante
## 1: print "Hallo Welt"
## ^
In diesen beiden Fällen stimmt die Syntax nicht - beim
print
-Befehl brauchen wir sowohl die Klammern als auch die
Anführungszeichen:
print("Hallo Welt")
## [1] "Hallo Welt"
Schauen wir uns die dritte Zeile an:
read.table("data/example-file1.txt", sep="\n")
## Warning in file(file, "rt"): kann Datei 'data/example-file1.txt' nicht öffnen:
## No such file or directory
## Error in file(file, "rt"): kann Verbindung nicht öffnen
R kann die Datei nicht einlesen, da die Pfadangabe und der Dateiname nicht stimmen. So funktioniert es:
read.table("example-file-1.txt", sep="\n")
## V1
## 1 Hallo Welt!
## 2 (in einer Datei im gleichen Verzeichnis versteckt)
Bearbeite zunächst die Übungsaufgaben zu dieser Lektion, denn in den Übungsaufgaben wirst Du einen weiteren wichtigen Datentyp in R kennenlernen: den Vektor (vector). Beispiele für Vektoren:
nottodolist = c("Frühzeitig an die eigene Rente denken.",
"Glastüren übersehen.",
"Etwas kaufen, weil es »Aloe Vera« enthält.")
ichzaehlbis3 = c(1, 2, 3)
# Länge eines Vektors
length(nottodolist)
## [1] 3
# Zugriff auf Elemente eines Vektors
nottodolist[1]
## [1] "Frühzeitig an die eigene Rente denken."
# Schleife über Elemente eines Vektors
for (i in 1:length(nottodolist)){
print(nottodolist[i])
}
## [1] "Frühzeitig an die eigene Rente denken."
## [1] "Glastüren übersehen."
## [1] "Etwas kaufen, weil es »Aloe Vera« enthält."
Die drei Begriffe “Vektor”, “Array” und “Matrix” werden in R teilweise synonym verwendet. Sie bezeichnen in jedem Fall eine Variable, in der mehr als nur ein Wert steckt (eine Varaible mit nur einem Wert heißt übrigens “skalar”).
Vektoren sind dabei eindimensional, Array und Matrizen können auch mehr Dimensionen beinhalten.
In dieser Vertiefung lernen wir benannte Vektoren
(named vectors
) kennen. Wie der Begriff vermuten lässt,
enthalten diese neben den eigentlichen Werten im Vektor auch noch für
jeden Wert einen Namen.
article = c(title = "River flow forecasting through conceptual models part I — A discussion of principles",
authors = "Nash, J. E., Sutcliffe, J. V.",
journal = "Journal of Hydrology",
year = 1970)
# Die Elemente kann man wie beim Vektor über Indizes aufrufen
article[3]
## journal
## "Journal of Hydrology"
# Die Elemente können aber auch über den entsprechenden Namen aufgerufen werden
article["title"]
## title
## "River flow forecasting through conceptual models part I — A discussion of principles"
# Übersicht über alle Namen
names(article)
## [1] "title" "authors" "journal" "year"
# Hinzufügen neuer Elemente
article["volume"] = 10
article["issue"] = 3
article["firstpage"] = 282
article["lastpage"] = 290
article
## title
## "River flow forecasting through conceptual models part I — A discussion of principles"
## authors
## "Nash, J. E., Sutcliffe, J. V."
## journal
## "Journal of Hydrology"
## year
## "1970"
## volume
## "10"
## issue
## "3"
## firstpage
## "282"
## lastpage
## "290"
Radiosondenaufstiege dienen der vertikalen Vermessung des Zustands der Atmopshäre. Der Deutsche Wetterdienst (DWD) betreibt 14 aktive Stationen, an denen regelmäßig Radiosondenaufstiege erfolgen (die Ballone, an denen die Sonden hängen, platzen dann in einer bestimmten Höhe und die Sonden kommen dann irgendwo wieder runter).
Die Metadaten der einzelnen Stationen hält der DWD hier
vor. Wir haben für unser Beispiel mal die Metadaten der Station Bergen
(Rügen) runtergeladen - Ihr findet Sie im Verzeichnis
../data/Meta_Daten_pkt_aero_00368/
in mehreren Dateien.
Eure Aufgabe besteht nun aus folgenden Schritten:
vector
) namens
attributes
, welcher die Bezeichner der Metadatenattribute
enthält (z.B. “Stations_ID”)readline
verwendet. Diese Funktion erfordert eine Nutzereingabe und überträgt
diese Nutzereingabe auf eine Variable (hier: value
). Wenn
Du also nach dem Wert gefragt wirst, musst Du ihn aus den Dateien
ablesen und eintragen. Hinweis: Gib immer nur den aktuellen
Wert ein, nicht die Historie der Metadaten der Station. Du musst
in dem Codeblock nun noch eine Zeile ergänzen, so dass
value
auch wirklich in den benannten Vektor
metadata
übertragen wird. Natürlich ist dieses
Skript nur dazu da, um Möglichkeiten für Nutzereingaben zu
demonstrieren. Du könntest alternativ auch direkt die Definition des
metadata
-Vektors aufschreiben.metadata
an.metadata
an und erlaubt es Dir, ein Attribut Deiner Wahl anzugeben. Für dieses
wird dann der Wert ausgegeben.# Definiere hier den Vektor mit Attributen
attributes =
# Dies ist der benannte Vektor, in dem die Werte der Attribute gesammelt werden - noch ist er leer...
metadata = vector()
# Nun gehen wir alle Attribute aus attributes durch...
for (attribute in attributes){
value = readline(paste("Geben Sie einen Wert für", attribute, "ein: "))
# HIER MUSST Du EINE ZEILE ERGÄNZEN!
}
# Was musst Du hier eintragen, um Dir den benannten Vektor anzuschauen?
print("Folgende Attribute stehen zur Verfügung:")
for (attribute in names(metadata)){
print(paste0(" - ", attribute))
}
attribute = readline("Über welches Attribut möchtest Du Dich informieren? ")
print("")
print("---")
print(paste0("Ergebnis der Abfrage für Attribut ", attribute, ":"))
# Hier musst Du nun ein weiteres print-statement einfügen,
# mit dem der Wert dieses Attributs ausgedruckt wird: