R-Tutorial: Teil 1
Diese Tutorial-Reihe ist eine Einführung in die statistische Programmiersprache R. Der erste Teil befasst sich mit der grundlegenden Syntax: Variablen, Vektoren, Matrizen, regelmäßige Folgen, Funktionen, Arbeiten mit Datensätzen. Die in R implementierte grafische Darstellung der Daten wird in einem folgenden Teil vorgestellt. Nach einer kurzen Motivation folgen die Beschreibung der Entwicklungsumgebung RStudio und die ersten Codezeilen in R. Hinweise und Besonderheiten zur Syntax werden an Beispiel-Codes gezeigt.
Motivation
R ist eine freie Programmiersprache für statistische Berechnungen und Grafiken.
Sie wurde 1992 von den Statistikern Ross Ihaka und Robert Gentleman an der Universität Auckland für Anwender mit statistischen Aufgaben neu entwickelt und
ist auf UNIX-Plattformen, Windows and MacOS lauffähig. Die R-Umgebung wird ebenfalls als R bezeichnet und ist Teil
des GNU-Projekts.
R grenzt sich von allgemeinen Programmiersprachen wie C oder Java durch die speziell für die Statistik entworfenen Datenstrukturen
und Funktionen sowie die darauf bezogenen Möglichkeiten der Grafikerzeugung ab.
Viele herunterladbare Pakete enthalten zusätzliche Funktionen, um Daten hinsichtlich verschiedener Fragestellungen
je nach Fachbereichen zu analysieren und weitere eigene Funktionen sind problemlos erstellbar.
Warum R?
R gilt als eine Standardsprache für statistische Problemstellungen sowohl in der Wirtschaft als auch in der Wissenschaft.
Da der Quellcode öffentlich ist, bietet R die Möglichkeit, schnell neue Pakete zu entwickeln und zur Verfügung zu stellen.
Die kostenlosen und online verfügbaren Pakete erweitern das Anwendungsfeld von R auf viele
Fachbereiche. Die internen Dokumentationen und auch die Foren, die sich mit der Anwendung von R befassen, bieten dem Benutzer die Möglichkeit die
Funktionalität von R leicht zu erfassen und anzuwenden.
Warum RStudio?
RStudio ist eine kostenlose und integrierte Entwicklungsumgebung für die Progammiersprache R, durch RStudio wird die Benutzerfreundlichkeit von R erhöht. Der Aufbau der Entwicklungsumgebung ist einfach und sehr übersichtlich.
R vs. MATLAB und Python
R wird, wie MATLAB und Python, insbesondere für die Entwicklung von Anwendungen im Bereich des Maschinellen Lernens verwendet, um z.B. im Rahmen der Vorausschauenden Wartung Prognosen oder Clusteranalysen zu erstellen. Die drei Sprachen bieten zum Teil ähnliche Funktionalität (Bibliotheken für statistische Probleme, ausgefeilte Grafik- und Visualisierungsmodule), wobei jede ihre Stärken und Schwächen hat. Während R auf statistische Programmierung spezialisiert ist, ist MATLAB allgemeiner auf mathematische Problemstellungen ausgelegt. Python hingegen ist eine Programmiersprache, die um statistische Programmbibliotheken erweitert wurde. Die Gemeinsamkeiten und Unterschiede in der Syntax und Verwendung werden hervorgehoben, um Wechslern den Einstieg in R zu erleichtern.
Übersicht
Das vorliegende R-Tutorial ist in zehn Abschnitte gegliedert. Zunächst wird die Entwicklungsumgebung RStudio vorgestellt und deren Installation und Aufbau erläutert. Danach folgen Abschnitte, die die R-Syntax an einfachen Beispielen erklären. Die Abschnitte bauen aufeinander auf und sollten in der angegebenen Reihenfolge bearbeitet werden.
Ein YouTube-Video veranschaulicht den R-Code zur Demo und dessen Ausführung in der Entwicklungsumgebung RStudio.
Die Entwicklungsumgebung RStudio
Als Tool wird RStudio eingesetzt, eine Entwicklungsumgebung und grafische Benutzeroberfläche
für die statistische Programmiersprache R, die in Open-Source- und kommerziellen Editionen
erhältlich ist und auf dem Desktop (Windows, Mac und Linux) oder in einem Browser läuft.
Komplexere Algorithmen und Methoden sind in R in Paketen zusammengefasst, die nach Bedarf über die R-Konsole
geladen werden können.
Eine R Version ist vor Installation von RStudio von der R-Webseite
zu installieren, danach kann RStudio als Desktop-Anwendung installiert werden, siehe auf der
Posit-Webseite
unter Produkte: RStudio IDE. Alternativ kann RStudio auch als Web-Anwendung verwendet werden.
Die Benutzeroberfläche von RStudio ist in vier konfigurierbare Panels unterteilt, die zum Entwickeln und Ausführen von Skripts verwendet werden. Die Konfiguration kann über View > Panes > Pane Layout Menu vorgenommen werden, und beschränkt sich hauptsächlich auf eine Auswahlmöglichkeit, welche Ansichten in welchem Panel angezeigt werden sollen. Die Benutzeroberfläche von RStudio Cloud ist sehr ähnlich, außer, dass sie links eine Seitenleiste mit den Arbeitsbereichen und eine Breadcrumb-Navigation mit dem aktuellen Projekt anzeigt.
- Menü-Leiste: die Funktionalität der IDE ist in den Menüpunkten File, Edit, Code, View, Plots, Session, View, Debug gruppiert.
- Übersicht: zeigt den Inhalt des Arbeitsverzeichnisses, die erstellten Grafiken, die Package-Übersicht und die interne Hilfe an
- Environment: zeigt die Objekte der aktuellen R-Sitzung (Session) an.
- Editor: enthält den Inhalt (Quellcode, Kommentare) einer R-Datei und den RUN-Button zum Ausführen des Codes.
- Konsole: zeigt den ausgeführten Code an und deren Output, falls dieser ausgegeben werden soll.
R Code kann auf zwei Weisen erstellt und ausgeführt werden:
- Interaktiv:
Die Befehle werden direkt in der Konsole eingegeben und mit der Enter-Taste ausgeführt, mit den Pfeiltasten nach Oben/Unten können die letzten Befehle aufgerufen werden bzw. in der History (Tab neben Environment) angesehen werden. -
R-Skript:
Größere Programme, d.h. mehrere Codezeilen, werden besser in einem R-Skript (Endung: .R) gespeichert, dieses R-Skript wird in einem Ordner, der als Arbeitsverzeichnis verwendet wird, gespeichert, siehe den Abschnitt "R-Skript erstellen". Die Anzeige des aktuellen Arbeitsverzeichnisses erfolgt mit dem Befehl getwd() (get working directory) und kann mit setwd("Pfad") auf einen beliebigen Ordner gesetzt werden. Die Angabe des Verzeichnispfades erfolgt mit dem "/"-Symbol und muss mit Anführungszeichen umrahmt werden.
Durch das Anlegen eines R-Projektes, indem alle für das Projekt relevanten Dateien und die R-Skripte abgespeichert werden, wird der Umgang mit R für den Benutzer ansprechender und einfacher gestaltet. Das Arbeitsverzeichnis wird z.B. automatisch auf das aktive Projekt gesetzt und der Pfad zum Arbeitsverzeichnis muss nicht explizit im Skript mit setwd("Pfad") gesetzt werden, siehe den Abschnitt "R-Projekt erstellen". - R Shiny-App:
Das Shiny-Paket stellt Funktionen zur Erstellung einer interaktiven Webanwendung zur Verfügung, dieses Paket wurde in Demo 4: Interaktive PradMaintApp mit R erläutert und angewandt.
Verwendete Funktionen
Die setwd-Funktion setzt den Arbeitspfad für die aktuelle R-Sitzung.
Die setwd-Funktion aus dem base-Paket (also dem default installierten R-Paket base) ist eine Funktion, die den Arbeitspfad der aktuellen R-Sitzung festlegt, damit entfällt die Angabe des Pfades beim Speichern oder Laden von Workspaces und Daten. Die Angabe des Verzeichnispfades erfolgt mit dem "/"-Symbol und muss mit Anführungszeichen umrahmt werden, z.B.
setwd("C:/R/DemoR1")
Die getwd-Funktion gibt den Arbeitspfad für die aktuelle R-Sitzung aus.
Die getwd-Funktion aus dem base-Paket (also dem default installierten R-Paket base) ist eine Funktion, die den Arbeitspfad der aktuellen R-Sitzung in der Konsole ausgibt. Der allgemeine Aufruf hat keine Übergabeparameter und lautet
getwd()
1 Erste Codezeilen in R
R-Code besteht aus Befehlen und Kommentaren.
Befehle / Kommandos sind ausführbare Anweisungen: Variablen-Zuweisungen, Ausdrücke, Funktionsaufrufe. Variablen sind benannte Speicherplätze, denen man Werte unterschiedlichen Datentyps (numerische Werte, Zeichen, Zeichenketten) und Ausdrücke zuweisen kann. R-Befehle unterscheiden zwischen Groß- und Kleinschreibung, d.h. max(x) ist nicht dasselbe wie Max(x). Eine Zuweisung erfolgt mittels dem = -Symbol oder dem Zuweisungssymbol <- -Symbol. Ein Ausdruck ist im Gegensatz zu einer Zuweisung zwar auch ein Befehl, wird jedoch sofort in der Konsole ausgeführt und liefert einen Output.
Kommentare dienen der besseren Verständlichkeit von Codezeilen und werden nicht ausgeführt. Alles was in der Zeile nach einem #-Symbol steht, ist als Kommentar gekennzeichnet und wird grün hinterlegt.
Codezeilen können direkt in der Konsole eingegeben werden oder in einem R-Skript gespeichert und über die RUN-Funktion ausgeführt werden. Hier wurde die Konsole benutzt um den Unterschied zwischen Kommentaren und Kommandos zu demonstrieren.
Wenn der Wert einer Zuweisung angezeigt werden soll, dann muss der bei Zuweisung vergebene Name als Ausdruck in der Konsole eingegeben werden. Um mehrere Kommandos in einer Zeile verwenden zu können, wird das Semikolon verwendet. Im Unterschied zu MATLAB trennt das Semikolon dabei Kommandos bei der Aufzählung und unterdrückt nicht die Ausgabe.
Hello World-Programm in R
Das Hello-World-Programm ist das kleinste ausführbare Programm in einer Programmiersprache und gibt den Text "Hello World" in der Konsole aus. Dies kann direkt in der Konsole eingegeben werden (Interaktiv) oder in ein R-Skript geschrieben und ausgeführt werden.
Interaktiv:
Die Befehle werden direkt in der Konsole eingegeben und mit ENTER ausgeführt, siehe die folgende Eingabe und Ausgabe in
der Konsole von RStudio:
2 R-Skript erstellen
Ein R-Skript ist eine Text-Datei mit R-Befehlen und Kommentaren, diese Datei hat die Endung .R. Zulässige Skript-Namen bestehen aus
Buchstaben, Zahlen und den Zeichen . und _ . Der Name beginnt mit einem Buchstaben oder dem Punkt, dabei darf keine Zahl nach dem Punkt folgen,
d.h. ".2way" ist nicht zulässig. Ebenfalls nicht zulässig sind bereits von R reservierte Namen wie TRUE, FALSE, if, NULL usw.
R-Skripte werden über die Menüleiste File >New File >R Script oder das Tastenkürzel STRG+Shift+N erzeugt,
weiterhin steht das Symbol ganz links
(Papier mit dem grün-umrundeten Plus-Symbol) in der Symbol-Leiste dazu zur Verfügung. Das Skript wird über den Tab Code der Menüleiste und dessen
entsprechenden RUN-Anweisungen ausgeführt, einfacher ist es jedoch über den RUN-Button im Editor, der die Zeile auf der der Cursor liegt oder die Zeilen, die markiert wurden, ausführt.
Als Nächstes wird mit File > New File > R Script ein neues R-Skript HelloWorld.R erstellt, das den R-Code enthalten wird.
R-Skript "HelloWorld"
In RStudio wird ein neues Skript erstellt und unter dem Namen "HelloWorld.R" gespeichert.
Dann wird der String "Hello World" in einer Variablen t gespeichert.
Im Unterschied zu MATLAB wird der Wert der Variablen t bei Ausführung des Befehls nicht sofort ausgegeben , sondern
erst bei Aufruf des Variablennamens "t".
RStudio sieht nach Erstellung, Änderung und Ausführung des Skriptes "HelloWorld.R" wie folgt aus:
R-Code: Hello World
# R-Tutorial: Hello-World-Programm
# die Zeichenkette/String in einer Variablen
# mit Namen Text speichern
t="Hello World"
# Ausgabe des Inhalts der Variablen
# durch Aufruf des Namens
t
Erläuterung des R-Codes
Zeile 1: einen Kommentar mit einer Beschreibung des Skript-Inhaltes
Zeile 6: der String "Hello World" wird unter dem Variablennamen "t" gespeichert
Zeile 11: die Variable "t" wird aufgerufen und damit wird ihr Wert ausgegeben
Erläuterungen zur Ausführung
Die Ausführung des Skriptes erfolgt entweder mit dem RUN-Button, der eine markierte Auswahl oder die aktuelle Zeile, auf der Cursor liegt,
ausführt oder die komplette Ausführung mit der Tastenkombination STRG+ALT+R. Im Environment-Feld werden die erstellten Variablen und deren Inhalt
angezeigt.
Der Arbeitspfad wird mit Kommando "getwd()" abgerufen und kann mit dem Kommando "setwd()" auf einen Ordner gesetzt werden, dessen Inhalt
dann unter "Files" angezeigt wird. Der Pfad darf keine Backslashs enthalten, sondern nur Slashs.
Hinweis:
Mit dem folgenden Befehlen wird die Arbeitsumgebung (Environment) und die Konsole geleert.
rm(list = ls()) # Leere Arbeitsumgebung
cat("\014") # Leere Konsole
Die Konsole kann auch durch mit der Tastenkombination STRG+L geleert werden, dazu muss der Cursor auf der Konsole liegen.
Verwendete Funktionen
Die rm-Funktion entfernt Objekte.
Die rm-Funktion aus dem base-Paket (also dem default installierten R-Paket) ist eine Funktion, Objekt entfernt. Dazu wird der Name (Zeichenkette, character string) des zu entfernenden Objektes als Parameter übergeben oder eine Liste mit Zeichenketten, die entfernt werden sollen. Die Liste ls() gibt alle Objekte der aktuellen Arbeitsumgebung aus, siehe auch Environment-Tab, d.h. mit
rm(list = ls())werden alle Objekte aus der aktuellen Arbeitsumgebung gelöscht.
Die cat-Funktion leert die Konsole.
Mit dem Befehl
cat("\014")wird in RStudio die Konsole geleert, alternativ ist dies auch mit der Tastenkombination STRG+L möglich.
3 R-Projekt erstellen
Zunächst wird in RStudio mit File > New Project ein neues Projekt "DemoR1" angelegt, das alle Skripte und Daten zu
Demo-R1 enthalten wird.
Beim Anlegen des neuen Projektes erstellt RStudio den Ordner C:\R\DemoR1, der als Arbeitsverzeichnis für die neue Demo genutzt wird.
Das Arbeiten mit Projekten in RStudio hat verschiedene Vorteile, z.B. können Projekt-Templates (Directory, R Package, Shiny Web Applications)
verwendet werden, auch die Versionskontrolle und damit kollaboratives Arbeiten wird über Projekte unterstützt.
Weiterhin wird durch das Anlegen eines Projektes das Arbeitsverzeichnis automatisch auf das aktive Projekt gesetzt und
der Pfad zum Arbeitsverzeichnis muss nicht explizit im Skript mit setwd gesetzt werden.
Die Struktur des DemoR1-Projektes sieht nach Erstellen des "HelloWorld"-Skriptes wie abgebildet aus.
Vorbereitungen: Struktur vom Skript demoR1_teil1.R
Der folgende Quellcode dieser Demo und die bereits ausgeführten ersten Codezeilen werden in einem R-Skript namens demoR1_teil1 gespeichert. Das
Skript wird wie oben beim HelloWorld-Skript beschrieben erstellt und ist in Sektionen unterteilt.
Wir gliedern das R-Skript demoR1_teil1.R in zehn Abschnitte, die den Abschnitten in diesem Tutorial entsprechen,
dies macht den Code übersichtlicher.
Ein Abschnitt/eine Sektion kann in RStudio mit Code > Insert Section eingefügt werden, oder auch einfach, indem man einen benannten Kommentar
einfügt, der von mindestens 4 Symbolen desselben Typs gefolgt wird, und erzeugt ein einklappbares und separat ausführbares Code-Fragment, das mit dem Tastenkürzel
STRG+ALT+T ausgeführt wird, wenn der Cursor auf der Sektion liegt.
Der R-Code der einzelnen Sektionen wird in den folgenden Abschnitten dieses Tutorials beschrieben und kann an den mit TODO gekennzeichneten Stellen eingefügt werden.
Die Gliederung des Skriptes wird über den rechten Menü-Punkt im Editor angezeigt.
Die Struktur des DemoR1-Projektes sieht nach Erstellen der Skripte wie abgebildet aus.
4 Vektoren
Vektoren sind eindimensionale Matrizen, die nur eine Spalte oder eine Zeile enthalten. Die Elemente eines Vektors können neben Zahlen
auch Zeichenketten sein.
Ein Spaltenvektor ist z.B. x = c(2,4,5,6) und y = t(c(2,4,5,6)) ist ein Zeilenvektor, wobei der Befehl t() für das Transponieren,
also Vertauschung von Zeilen und Spalten und umgekehrt, steht.
Die Elemente eines Vektors werden über einen Index, der bei 1 beginnt, aufgerufen, z.B. liefert x[1] das erste Element des Vektors x. Diese Indexnummerierung ist
auch in MATLAB gegeben, dort werden die Elemente aber mit runden Klammern aufgerufen (MATLAB: x(1)).
Beispiel: Vektoren verwenden
Im folgenden Beispiel werden Zeilen- und Spaltenvektoren mit unterschiedlichen Datentypen
erzeugt und deren Elemente aufgerufen.
R-Skript | Output |
---|---|
|
|
Erläuterungen zum Code:
Zeile 1: Die Sektion mit Namen "2. Vektoren" wird erzeugt
Zeile 5, 6: die Erzeugung von Vektoren mit Zahlen oder Zeichenketten als Elementen
Zeile 7: die Erzeugung eines Vektors mit Zahlen und Zeichenketten als Elementen und Speicherung unter dem Namen z
Zeile 10, 11, 12: die Erzeugung von Vektoren und Speicherung unter einem Variablennamen
Zeile 18-21: Aufrufe von einzelnen Elementen des Vektors x mittels Indexaufruf oder Weglassen eines Elementes mit "-Indexnr."
Zeile 25: Elementaufruf in umgekehrter Reihenfolge
Zeile 27: Der Vektor x wird 2mal hintereinander zusammengefügt.
5 Operationen
In R werden alle Vektoroperationen standardmäßig elementweise ausgeführt. Dies beruht auf der Anwendung von R zur Lösung statistischer Fragestellungen. Die Vektoren stellen dabei Beobachtungen aus Datensätzen dar, auf denen elementweise Operationen ausgeführt werden. Anders als in MATLAB, dort wird der Schwerpunkt auf die Matrixmultiplikation gelegt, d.h. x*y führt die Matrixmultiplikation aus, wenn man stattdessen elementweise Multiplizieren möchte, dann muss das explizit mit dem "." ausgewiesen werden (MATLAB: x.*y).
Die Regelung mit elementweisen Operationen als Standardausführung gilt auch für Matrizen, da diese einem Zusammenfügen von Beobachtungen zu einem Datensatz entsprechen.
Beispiel-Quellcode
R-Skript | Output |
---|---|
|
|
Erläuterungen zum Code:
Zeile 4: eine Variable z mit dem Wert 2 wird erzeugt
Zeile 5: Operationen werden auf die Variable angewandt
Zeile 10: elementweise (default) Operationen werden auf den Vektor x angewandt
Zeile 13: die Vektoren x und y werden subtrahiert, addiert und multipliziert, dies erfolgt elementweise.
Zeile 16: das Ergebnis der Subtraktion wird unter dem Namen z gespeichert.
Kommandos aus dem base-Paket
Auf Vektoren können auch vordefinierte Funktionen aus Paketen, wie z.B. dem base-Paket, angewandt werden.
Mit dem Befehl library(help = "base") werden alle Funktionen dieses Paketes angezeigt.
Eine Auswahl der zur Verfügung stehenden Funktionen ist im fogenden Quellcode enthalten.
Neben den klassischen
Funktionen, wie Minimum, Maximum, Länge usw., stehen auch speziell für die Datenanalyse interessante Kennzahlen zur Verfügung,
wie der Mittelwert, der Median oder die Quantile usw.
Abhängig vom übergebenen Objekt liefert die summary()-Funktion verschiedene für das Objekt interessante Kennzahl-Übersichten, bei Vektoren
verschiedene Lagekennzahlen, das Minimum, das Maximum und den Mittelwert. Es ist ratsam, auf im Quellcode erzeugte Objekte oder Modelle
die summary()-Funktion
anzuwenden, um erste Informationen über die Objekte oder Modelle zu erhalten.
R-Skript | Output |
---|---|
|
|
6 Sequenzen und Wiederholungen
Bei der Entwicklung statistischer Anwendungen benötigt man oft regelmäßige Folgen (engl. sequences) oder Wiederholungen (engl. repetitions) von Werten, z.B. die Sequenz 2,4,6,8,10 der geraden Zahlen, die kleiner sind als 10, oder 1,1,1,1 als viermalige Wiederholung der Zahl 1. R bietet die Möglichkeit, auf einfache und schnelle Weise Sequenzen mit Hilfe der Funktion seq() und Wiederholungen mit Hilfe der Funktion rep() zu erzeugen. Mit Hilfe von seq(2, 10, by=2) wird z.B. die Sequenz der Zahlen mit Anfangswert 2, Endwert 10 und Schrittweite 2 erzeugt.
Beispiel: Sequenzen erzeugen
Das Beispiel zeigt, wie regelmäßige Zahlenfolgen erzeugt werden, entweder mit Hilfe des :-Operators, oder mit Hilfe der
der Funktion seq().
R-Skript | Output |
---|---|
|
|
Erläuterungen zum Code:
Zeile 3: Erzeugung der Sequenz von Werten 1,2,...,10 mittels Kurzform ":"
Zeile 4: Erzeugung der Sequenz von Werten 1,2,...,10 mit der Sequenzfunktion. Diese ermöglicht
weitere Optionen, wie Festlegung der Schrittweite oder des Endwertes.
Zeile 9: Sequenz im Bereich 1 bis 10 mit Schrittweite 0.5 erzeugen
Zeile 10: äquidistante Zerlegung mit 5 Werten in [1;10] erzeugen
Zeile 15: Sequenz im Bereich -3 bis 5 mit Schrittweite 0.2 erzeugen
Zeile 16: Sequenz im Bereich 6 bis 1 mit Schrittweite -0.2 erzeugen
Beispiel: Wiederholungen erzeugen
Das Beispiel zeigt, wie Wiederholungen mit Hilfe der Funktion rep() erzeugt werden.
R-Skript | Output |
---|---|
|
|
Erläuterungen zum Code:
Zeile 2: der Wert 1 wird 4 mal wiederholt.
Zeile 4: der Vektor (1,2,3,4) wird 3 mal wiederholt
Zeile 7: jedes Element des Vektors (1,2,3,4) wird 3 mal wiederholt
Zeile 10: geschachtelte Wiederholung: jedes Element des Vektors (1,2,3) wird 4 mal wiederholt
Zeile 13: das erste und dritte Element des Vektors (1,2,3,4) wird 2 mal wiederholt, die anderen einmal.
Zeile 19, 20: Rechenoperationen wie sin(), Multiplikation mit PI und Division durch 18 werden
elementweise auf die Sequenz 0,1,2,..,36
angewandt, danach wird das Ergebnis auf 2 Nachkommastellen gerundet mit round(... ,2).
7 Logische Werte und fehlende Werte
Logische Werte
TRUE oder FALSE sind Ergebnisse logischer Operationen und werden als logische Werte bezeichnet. Besonders bei der Extraktion von Beobachtungen aus Datensätzen spielen diese eine wichtige Rolle. Dies wird im folgenden Code deutlich.
Beispiel: Extrahiere Werte aus Daten mittels Bedingungen
Aus den als Sequenz erzeugten Größen- und Gewichtsvektoren werden über einzelne oder verknüpfte Bedingungen (&-Operator) Werte extrahiert. Mit der which()-Funktion kann der Index abgefragt werden, an dem eine bestimmt Bedingung erfüllt ist. Dieser Index wird dann zur Extraktion, hier des Maximums des Gewichtsvektors, verwendet.
R-Skript | Output |
---|---|
|
|
Erläuterungen zum Code:
Zeile 2: Einzelwerte werden mit dem Wert 4 über verschiedene Vergleichsoperatoren (<, ==, !=, usw.) verglichen und
liefern logische Werte als Ergebnis
Zeile 5: der Vektor (1,2,3,5,10) wird mittels des Vergleichsoperators >= (größer oder gleich) elementweise mit der 5 verglichen und
liefert einen Vektor aus logischen Werten zurück
Zeile 8, 9: die Vektoren bestehend aus Größen und Gewichten werden als Sequenzen erzeugt: 170,171,...179,180 und 65,66,...,74,75
Zeile 11: die Elemente vom Gewichtsvektor, die an den Indexstellen ein TRUE aufweisen, werden ausgegeben. TRUE ist nur an den Stellen, an denen
der Größenvektor kleiner oder gleich 174 ist.
Zeile 14: die Elemente vom Gewichtsvektor, die an den Indexstellen bei Abfrage groesse<=175 & gewicht >68 ein TRUE enthalten, werden ausgegeben.
Zeile 16: die Elemente vom Größenvektor, die an den Indexstellen bei Abfrage groesse<=175 & gewicht >68 ein TRUE enthalten, werden ausgegeben.
Zeile 22: which() gibt den Index wieder, an dessen Stelle die Bedingung gewicht==70 erfüllt ist und kann dann im nächsten Schritt weiter verwendet werden.
Zeile 25: fragt den Index mit dem maximalen Gewicht ab und
Zeile 26: gibt das Element an dieser Indexstelle aus, d.h. das maximale Gewicht.
Fehlende Werte
Fehlende Werte müssen in Datensätzen erkannt und notfalls damit umgegangen werden.
Es ist wichtig, diese Stellen/Index auch in einer großen Menge von Werten schnell zu erkennen, dazu stehen Kommandos zur Verfügung.
Fehlende Werte werden mit NA betitelt, d.h. Not Available/Nicht Verfügbar.
Nicht definierte Rechnenoperationen liefern NaN (Not a Number) zurück.
Enthalten Vektoren NA-Werte, dann beeinflusst dies alle Operationen. Z.B. wird das Maximum dann als NA ausgegeben oder auch der
Mittelwert (mean()), bevor Kennzahlen oder Operationen sinnvoll auf Vektoren angewandt werden können, müssen die NA-Werte mittels der Option
na.rm=TRUE (Missing values remove= TRUE) aus der Bestimmung der Kennzahlen ausgeschlossen werden. Bei Rechenoperationen eines NA-Wertes mit einer
Zahl ist das Ergebnis immer NA.
Die Funktion is.na() liefert einen Vektor mit logischen Werten und TRUE an der Indexstelle, an der ein NA steht.
Beispiel: Umgang mit NA-Werten
Der erzeugte Gewichtsvektor enthält einen fehlenden Wert (NA). Bei Anwendung von Funktionen muss dieser fehlende Wert zuerst mittels der Option na.rm=TRUE ausgeschlossen werden, dann liefert die Funktionen einen sinnvollen Rückgabewert. Anstatt die Option na.rm bei Funktionsaufruf auf TRUE zu setzen, kann der Vektor Gewicht auch ohne die NA-Werte an die Funktion übergeben werden. Dazu stellt man mittels is.na() fest, wo sich die fehlenden Werte befinden (Indexangabe) oder an welchen Indexstellen eben keine fehlenden Werte zugeordnet sind (!is.na(), wobei das "!" für NICHT steht). Damit kann ein reduzierter Gewichtsvektor an die Funktion übergeben werden.
R-Skript | Output |
---|---|
|
|
8 Zeichen und Zeichenketten
Zeichen oder Zeichenketten sind nützliche Werkzeuge zum Benennen (Labeln) von Daten. Mit dem Label können Daten auch gezielt aufgerufen werden, das Label kann also wie ein Index genutzt werden. Das Zusammenfügen von einzelnen Strings, die viele gemeinsame Komponenten aufweisen und sich z.B. nur in der Stundenanzahl (siehe Beispiel) unterscheiden, ist mit der paste()-Funktion möglich.
Beispiel-Quellcode: Erzeugung von Strings und Labeling zur Extraktion von Werten
Der String "Blutdruck nach ... h" soll um die Stunden 0, 2, 4, 6 und 8 ergänzt werden. Die paste()-Funktion verknüpft dazu die Strings "Blutdruck nach" und "h" komponentenweise mit den Werten des Vektors c(0,2,4,6,8). Der Gewichtsvektor erhält mit der names()-Funktion Label für die einzelnen Komponeneten (hier: Personennamen). Damit wird das Gewicht von "Hans" gezielt extrahiert.
R-Skript | Output |
---|---|
|
|
Erläuterungen zum Code:
Zeile 1: der Gewichtsvektor wird als Sequenz erstellt
Zeile 4, 5: mit der paste()-Funktion werden der String "Blutdruck nach" mit dem Vektor (0,2,4,6,8) und dem Zeichen "h" verbunden,
die Trennung zwischen den Komponenten soll das Leerzeichen sein (sep=" "). Jedes Element des Vektors wird mit dem vorderen String und dem
hinteren Zeichen verknüpft, also erfolgt eine Ausgabe von 5 Strings.
Zeile 10, 11: die names()-Funktion vergibt für die Elemente des Vektors gewicht Label/Namen, d.h. 3 Namen und 8 mal den String NN.
In Zeile 13
wird das Label "Hans" benutzt um das Element mit diesem Label aus dem Gewichtsvektor auszugeben.
9 Matrizen
Matrizen sind 2-dimensionale Felder, die einen Zeilen- und einen Spaltenindex besitzen, diese beginnen bei 1. Diese Objekte enthalten nur numerische Werte oder nur Zeichenketten, eine Mischung des Types der Elemente einer Matrix ist nicht möglich, sie sind also im Gegensatz zu Vektoren sogenannte "atomic objects" (deutsch: atomare Objekte). Da Datensätze ähnlich wie Matrizen aus Zeilen und Spalten bestehen, ist der Umgang mit Matrizen wichtig um Datensätze editieren und aufrufen zu können. In R werden Matrizen oft mit Kleinbuchstaben benannt, da die Großbuchstaben für Datensätze stehen. In MATLAB werden aber auch schon Matrizen mit Großbuchstaben benannt.
Die Erstellung von Matrizen in R
Die Syntax zur Erstellung einer Matrix lautet: matrix(data, nrow, ncol). Die matrix()-Funktion wird aufgerufen und die Daten,
die in der Matrix stehen sollen, und die weiteren Parameter nrow (Zeilenanzahl) und ncol (Spaltenanzahl) werden übergeben. Das Grundgerüst
der (nrow x ncol)-Matrix wird spaltenweise mit den Daten gefüllt. Wenn zeilenweise gefüllt werden soll, muss der Parameter
byrow auf TRUE gesetzt werden.
R-Skript | Output |
---|---|
|
|
Hinweis: Eine Mischung von Element-Typen ist bei Matrizen nicht möglich, siehe Beispiel-Code Matrix c oder c2. Der numerische Wert 15 wurde in einen String umgewandelt, damit alle Elemente von c bzw. c2 vom Typ String sind.
Die Erstellung von Matrizen mittels rbind und cbind
Die Funktionen rbind() und cbind() erleichtern den Umgang mit Daten, indem sie die Möglichkeit bieten, Vektoren/Daten
aneinander zu fügen und das zeilen- oder spaltenweise. Dabei muss die Länge der zu verknüpfenden Vektoren gleich sein.
Die verknüpften Zeilen bzw. Spalten erhalten die Vektornamen als Label. Diese Labels können dazu verwendet werden, um Teilelemente zu
extrahieren.
Beispiel-Quellcode: Verwendung von rbind() und cbind()
Die Funktion rbind() fügt den Gewichts- und Größenvektor zeilenweise zusammen, die Funktion cbind() spaltenweise.
R-Skript | Output |
---|---|
|
|
Extraktion von Elementen aus Matrizen
Durch Angabe des Zeilen- und Spaltenindex können einzelne Elemente oder Teilmatrizen extrahiert werden. Die Index-Angabe erfolgt in
eckigen Klammern: [Zeilenangabe, Spaltenangabe]. Ein leerer
Index steht dabei für alle Elemente aus dieser Zeile oder Spalte, d.h. a[ , ] liefert die gesamte Matrix a als Ausgabe.
Hinweis: In MATLAB erfolgt die Angabe mit runden Klammern: (Zeilenangabe, Spaltenangabe).
Beispiel-Quellcode: Extraktion von Elementen oder Teilmatrizen
Durch die Indexangabe mittels [Zeilenangabe, Spaltenangabe] werden aus der Matrix a=matrix(1:12,3,4) gezielt Elemente oder Teilmatrizen extrahiert.
R-Skript | Output |
---|---|
|
|
Extraktion von Elementen aus Matrizen mit Labeln
Durch Angabe der Bedingung für eines der Labels oder eine logische Verknüpfung von Bedingungen mehrerer Labels erfolgt eine
Extraktion von Teilmatrizen. Dabei stehen die Bedingungen an erster Stelle des Indexaufrufs, danach folgt ein Leerzeichen im
2. Indexaufruf: [Bedingung(en), ].
Beispiel-Quellcode: Extraktion von Elementen mittels Labels
Aus der Matrix z = cbind (groesse, gewicht) werden über Bedingungen an die Label groesse und gewicht gezielt Teilmatrizen extrahiert, nämlich diejenigen Zeilen, bei denen die Größe kleiner gleich 175 ist, bzw. diejenigen Zeilen, bei denen Größe kleiner gleich 175 und Gewicht größer als 68 ist.
R-Skript | Output |
---|---|
|
|
Matrixoperationen
In R werden alle Matrixoperationen standardmäßig elementweise ausgeführt, dies beruht auf der Anwendung von R zur Lösung
statistischer Fragestellungen. Die Zeilen stellen dabei Beobachtungen und die Spalten die Merkmale/Variablen aus Datensätzen dar.
Es können Rechenoperationen auf Matrizen angewandt werden, diese werden elementweise ausgeführt. Die Transponierte wird mit der t()-Funktion
erzeugt (MATLAB: A', Anführungszeichen als Transposition) und die bekannte Matrixmultiplikation wird in R mit "%*%" durchgeführt.
Hinweis: In MATLAB wird der Schwerpunkt auf die Matrixmultiplikation gelegt, d.h. A*B führt die Matrixmultiplikation aus.
Wenn man in MATLAB elementweise multiplizieren möchte, muss das explizit mit dem "." ausgewiesen werden (MATLAB: A.*B).
Beispiel-Quellcode
R-Skript | Output |
---|---|
|
|
Weitere nützliche Funktionen für Matrizen
In R stehen weitere nützliche Funktionen für Standardfragen zu Matrizen zur Verfügung. Diese sind z.B. in dem R-Paket base enthalten. Mit der
diag()-Funktion wird bei Übergabe einer quadratischen Matrix als Rückgabewert deren Diagonale ausgegeben bzw. bei Übergabe eines Vektors eine Diagonalmatrix
mit dem Vektor als Diagonale erzeugt. Die Funktion nrow() bzw. ncol() geben die Zeilen- bzw. Spaltenanzahl
zurück, dim() liefert die Dimension der Matrix, also zwei Werte zurück und mit der Funktion eigen() werden die Eigenwerte und -vektoren quadratischer Matrizen bestimmt.
Durch Eingabe von library(help = "base") in die Konsole wird eine Übersicht aller Funktionen des Paketes base geöffnet.
R-Skript | Output |
---|---|
|
|
10 Datensätze und das Einlesen von Daten
Daten werden in einer Rechteckmatrix aus Beobachtungen (Zeilen) und Merkmalen/Variablen (Spalten) dargestellt. Hierbei können verschiedene Variablentypen in den Spalten enthalten sein. Der Name eines Datensatzes beginnt standardmäßig mit einem Großbuchstaben. Zur Erstellung eines Datensatzes wird die data.frame-Funktion des base-Paketes verwendet. Mit
# Vektoren als Elemente von Datensätzen
name=c("Lisa", "Norman", "Tilla")
punkte=c(86,70, 87)
bestanden=c(rep("ja",3))
werden drei Vektoren erzeugt, die die Spalten des Datensatzes bilden sollen. Diese drei Vektoren werden mit dem minimal Aufruf der data.frame-Funktion zu einem Datensatz names "Klausur1" zusammengefügt
Klausur1=data.frame(name, punkte, bestanden)
und liefern die bei Aufruf des Datensatzes in der Konsole die Ausgabe
Die Vektornamen wurden bei der Erzeugung des Datensatzes als Spaltennamen übernommen. Die Beobachtungen/Zeilen
werden durchnummeriert.
In der Arbeitsumgebung (Environment-Tab) ist ein Datensatz an dem Dreieck-Symbol zu erkennen, bei Doppelklick auf das
data.frame-Objekt in der Umgebungsliste wird der Datensatz in einem Tab im Editor geöffnet:
Der data.frame-Funktion können Parameter übergeben werden, mit dem row.names-Parameter werden die Zeilennamen angepasst. Im Beispiel wird ein Vektor mit den Zeichenketten Student1, Student2 und Student3 als Zeilen- bzw. Beobachtungsnamen übergeben
Klausur1=data.frame(name, punkte, bestanden,
row.names = c("Student1", "Student2", "Student3"))
Die Zeilennamen des Datensatzes sehen damit wie folgt aus:
Ein weiterer nützlicher Parameter beim Aufruf der data.frame-Funktion ist der stringsAsFactors-Parameter, damit werden Zeichenketten direkt in Faktoren mit Levels (deutsch Kategorien) umgewandelt. Dies ist für die weitere Verwendung der Daten hilfreich. Mit
Klausur1=data.frame(name, punkte, bestanden,
row.names = c("Student1", "Student2", "Student3"))
stringsAsFactors = TRUE)
erfolgt die Umwandlung der Strings in Faktoren, deren Typ mit der is.factor-Funktion des base-Paketes überprüft werden kann.
Matrizen in Datensätze umwandeln
Ein einfacher Weg einen Datensatz zu erzeugen, ist eine schon vorhandene Matrix in einen Datensatz umzuwandeln, dies ist ebenfalls mit der data.frame()-Funktion möglich. Das Datensatz-Objekt hat viele Eigenschaften und Operationen mit Matrizen gemeinsam, aber nicht alle, die Matrixmultiplikation führt bei Umwandlung in einen Datensatz zu einem Fehler. Die as.matrix()-Funktion schafft dort Abhilfe und wandelt den Datensatz wieder in eine Matrix um. Die Darstellung eines Datensatzes unterscheidet sich bei Aufruf und Ausgabe in der Konsole auch von Matrizen, die Zeilen- und Spaltenangabe fällt weg, stattdessen erfolgt ein Labeling der Spalten/Variablen mit X1,X2,..
R-Skript | Output |
---|---|
|
|
Hinweis:
In Python steht eine Datenstrukturen für Listen (Listen (engl. lists)) zur Verfügung, die aufgrund ihrer Eigenschaften
(änderbar, geordnet und Duplikate erlauben) mit den DataFrames in R vergleichbar ist. Dabei werden die Listen mit rechteckigen Klammern definiert
(z.B. studenten = ["Max Muster", "Anna Test", "John Doe"]) und
die Listenelemente werden über einen Index ausgewählt, wobei der Indexaufruf Unterschiede zu R aufweist. Der Index beginnt bei Null und beim Aufruf
studenten[1,3] werden alle Elemente mit Index ≥ 1 und < 3 ausgewählt. Wobei R beim Matrixaufruf a[1:2,2:3] den Wert nach dem ":" miteinbezieht.
Eine Liste kann als eine mögliche Spalte/Variable eines Datensatzes angesehen werden.
Desweiteren verfügt die Pandas-Bibliothek in Python über zwei Datenstrukturen: Series und DataFrames. Eine Series ist ein eindimensionales
indizierbares Objekt, das Daten in einer Zeile oder Spalte speichert. Die einfachste Series entsteht aus einer Liste von Daten (z.B. name = pandas.Series(["Max Muster", "Anna Test", "John Doe"])).
DataFrames können in Python auf verschiedene Arten erzeugt werden, zum Beispiel aus mehreren Series oder aus einem Dictionary, dessen Werte gleich lange Listen sind.
Siehe dazu Demo-PY2: Datenverwaltung mit Pandas.
Label vergeben oder umbenennen
Manchmal ist es sinnvoll, auch den Beobachtungen Labels zu geben, dies kann mit der row.names()-Funktion bei
der Erstellung der Matrix oder nachträglich erfolgen. Mit der Funktion names() werden die Namen von Objekten ausgelesen oder gesetzt.
D.h. die Variablen in Datensätzen können auch nachträglich mit der names()-Funktion umbenannt werden. Die paste()-Funktion zum Verketten von Vektoren, die
dabei in Strings umgewandelt werden, ist an dieser Stelle wieder sinnvoll einsetzbar.
R-Skript | Output |
---|---|
|
|
Objekttyp abfragen
Mit der Funktion is.data.frame() wird abgefragt, ob das übergebene Objekt ein DataFrame ist, hier: TRUE.
Mit class() wird die Klasse eines Objektes abgefragt, hier: data.frame.
R-Skript | Output |
---|---|
|
|
Variablen oder Beobachtungen extrahieren
Durch den Datentyp data.frame können speziell Variablen mit dem $-Zeichen extrahiert werden, z.B. gibt
A.dframe$"Variable 4" die Werte der Variablen 4 aus,
dazu wird also das Label der jeweiligen Spalte/Variablen benutzt.
Um Beobachtungen abzurufen, kann auch die klassische Extraktionsweise von Matrizen genutzt werden,
mit Zeilen- und Spaltenaufruf in eckigen Klammern.
R-Skript | Output |
---|---|
|
|
Hinweis: Die Pandas-Bibliothek stellt die iloc()-Funktion zur Extraktion von Teildatensätzen zur Verfügung. Dabei extrahiert data_frame.iloc[:,[2,4,5]] alle Zeilen, aber nur die Spalten 2, 4 und 5. Das :-Symbol ist mit dem Leerzeichen-Aufruf in R identisch.
Teildatensätze extrahieren oder neue Variablen einfügen
Durch die subset(x, Bedingung für x)-Funktion können gezielt Teildatensätze mittels einer Bedingung an die Variablen erstellt werden.
Diese Funktion ist auch auf Vektoren und Matrizen anwendbar.
Zum Einfügen neuer Variablen und Beobachtungen stehen die Funktionen cbind() und rbind() zur Verfügung, die entweder spalten- oder zeilenweise
Teile von Matrizen, Vektoren oder Datensätzen kombinieren.
R-Skript | Output |
---|---|
|
|
Hinweis: In Python kann durch den Aufruf des Index/Variablennamen eine Spalte extrahiert werden, z.B. dataframe.index.year, und als neue Spalte eingefügt werden, z.B. dataframe['Name_neuer_Spalte'] = dataframe.index.year.
Externe Daten einlesen
Die Funktion read.table aus dem utils-Paket erzeugt automatisch einen Datensatz mit Format data.frame bei Einlesen einer
Standard-Datei, die die folgende Tabellen-Form hat:
Wenn dieses Format nicht vorliegt, müssen Optionen bei der read.table()-Funktion eingegeben werden, z.B. header, col.names, row.names, siehe die folgende Kursdaten00.txt-Datei:
Diese wird mit dem Befehl
read.table("Kursdaten00.txt",col.names=c(...))
eingelesen, wobei nach Übergabe des Dateinames, der hier im gleichen Ordner wie das aktuell verwendete R-Skript liegt bzw. im Projekt-Ordner von
Demo R1 abgelegt ist, der Option col.names()
die Variablennamen als Vektor übergeben werden müssen. Dabei muss die Anzahl der Variablen in der einzulesenden Datei bekannt sein und
es muss eine übereinstimmende Anzahl von Elementen im Names-Vektor (=c(..)) vorhanden sein.
Andere Optionen können das Separationszeichen "sep" oder auch das Überspringen von Zeilen am Anfang mit "skip" sein:
- sep="" default: eine oder mehrere Leerzeichen
- sep=",": Komma als Trenner von Beobachtungen
- skip= : Zeilen am Anfang überspringen
Beim Einlesen der Daten muss der Arbeitspfad richtig gesetzt sein oder ein R-Projekt geöffnet sein und die Daten sich dann im gleichen Ordner bzw. Projekt wie das verwendete R-Skript befinden, dann muss nur der Name der Datei genannt werden. Es kann aber auch ein Dateipfad beim Aufruf von read.table() angegeben werden.
R-Skript | Output |
---|---|
|
|
Hinweis: In Python wird mit der pandas.read_csv('CSV_Name', ...)-Funktion und deren weiteren Optionen eine .csv-Datei eingelesen und in einem Data Frame gespeichert.
Bezugsdatensatz festlegen/entfernen: attach/detach
Die Funktionen attach() und detach() erlauben einen Datensatz oder ein Listen-Objekt als Suchpfad, also als Bezugsdatensatz festzulegen,
dabei wird bei Aufruf einer Variablen direkt in dem vorher durch attach() als Suchpfad festgelegten Objekt nach der Variablen gesucht. D.h. der Variablenaufruf
des Bezugsdatensatz kann ohne das $-Zeichen erfolgen. Mit detach wird dieser Suchpfad bzw. der Bezugsdatensatz oder die Bezugsliste wieder entfernt.
R-Skript | Output |
---|---|
|
|
11 YouTube-Video
Der Einstieg in R mit RStudio wird durch YouTube-Videos (Screencast mit zusätzlichen Erläuterungen) veranschaulicht.
Fazit & Ausblick
Dieser erste Teil der R-Tutorial-Reihe
zeigte einen Einstieg in das Basiswissen der Programmiersprache R
bzgl. der Syntax, Variablen, Matrizen, regelmäßigen Folgen und dem Umgang mit Datensätzen.
Um größere R-Programme für Datenanalyse mit einem komplexeren Programmablauf zu schreiben,
werden weitere Befehle benötigt, diese werden im zweiten und dritten Teil der Tutorial-Reihe vermittelt.
Teil 2 der R-Tutorial-Reihe
bietet eine Einführung in Kontrollstrukturen (bedingte Verzweigungen und Schleifen), die den Programmablauf steuern,
und die Verwendung und Erstellung von Funktionen in der Programmiersprache R.
Der dritte Teil der Tutorial-Reihe
Teil 3: Grafiken und Zufallszahlen bietet einen Einblick in die Syntax
zur Erzeugung von Grafiken und von Zufallszahlen und -stichproben in der Programmiersprache R.
Autoren, Tools und Quellen
Autoren:
M.Sc. Anke Welz
Prof. Dr. Eva Maria Kiss
Tools:
elab2go Links:
- Demo-R1: R-Tutorial Teil 2: Kontrollstrukturen und Funktionen
- Demo-R1: R-Tutorial Teil 3: Grafiken und Zufallszahlen
Nützliche Links zu R:
- 1. R-Dokumentation im Comprehensive R Archive Network (CRAN)
- 2. Comprehensive R Archive Network (CRAN): An Introduction to R
- 3. RStudio Support: Quick list of useful R packages
- 4. Hadley Wickham, Garrett Grolemund: R for Data Science. O'Reilly, Januar 2017 (eBook)
- 5. R Tutorial "Fundamentals": Eine erweiterte englische Version dieses Tutorials mit weiterführenden Infos bzgl. R-Paketen, Visualisierung etc.