›  Demo-R1: 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, der Erzeugung und dem Umgang mit Datensätzen und der speziell in R implementierten grafischen Darstellung der Daten in einem folgenden Teil. Wir verwenden RStudio als integrierte, benutzerfreundliche Entwicklungsumgebung von R. Nach einer kurzen Motivation folgen die Beschreibung der Entwicklungsumgebung und die ersten Codezeilen in R. Hinweise und Besonderheiten zur Syntax werden an Beispiel-Codes gezeigt.

info-icon 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 ausdrücklich 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 interne 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.

info-icon Übersicht

Das Tutorial ist in neun Abschnitte gegliedert, die die R-Syntax an einfachen Beispielen erklären und aufeinander aufbauen:

  1. RStudio als Entwicklungsumgebung

  2. Erste Codezeilen in R

  3. Vektoren

  4. Operationen

  5. Sequenzen und Wiederholungen

  6. Logische Werte und fehlende Werte

  7. Zeichen und Zeichenketten

  8. Matrizen

  9. Datensätze und das Einlesen von Daten

Die Entwicklungsumgebung RStudio

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 RStudio- Webseite unter Produkte: IDE for R. Alternativ kann RStudio auch als Web-Anwendung verwendet werden.

Die Benutzeroberfläche von RStudio besteht aus folgenden Feldern:

R Code kann auf zwei Weisen erstellt und ausgeführt werden:

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.

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:

R-Skript:
In RStudio wird ein neues Skript erstellt und unter dem Namen "test_hello.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 "test_hello.r" wie folgt aus:

Der Quellcode enthält in
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

 # 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

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.

Die Konsole kann durch mit der Tastenkombination STRG+L geleert werden, dazu muss der Cursor auf der Konsole liegen.

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.

Der Quellcode enthält in

Zeile 1: einen Kommentar mit einer Beschreibung des Skript-Inhaltes
Zeile 5,6,7: die Erzeugung von Vektoren mit Zahlen oder Zeichenketten oder Beidem als Elementen
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.

R-Skript Output
 # 2. Vektoren ---- 
  
 # Syntax: c(element1,element2,...) 
 # als Ausdruck: 
 c(2,4,5,6) 
 c("aber", "und", "oder", "gleich") 
 z=c(1,2,"drei","vier")  
  
 # als Zuweisung: 
 x=c(2,4,5,6) 
 worte=c("aber", "und", 
 "oder", "gleich") 
  
 # Aufruf von Teilelementen:   
 # Indizes in eckigen Klammern 
 # Achtung: Zählindex der Elemente 
 beginnt bei 1. 
 x[1] #1.Element des Vektors x 
 x[2:3] #2.-3. Element 
 x[c(1,3)] #1. und 3. Element 
 x[-2] # x ohne das 2. Element 
  
 # Element-Aufruf in umgekehrter  
Reihenfolge 
 x[3:2] #3.-2. Element  
  
 c(x,x)# hintereinanderfügen 
 von 2 mal x 

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

Der Quellcode enthält in

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.

R-Skript Output
 # 3. Operationen ----
 # Verknüpfungen: +,-,*,/,^ :
 # bei Einzelwerten:
 z=2
 z+2;z-2;z^2;z/3;z*4;
 
 # bei Vektoren:
 # Rechenoperationen werden elementweise durchgeführt
 x=c(2,4,5,6)
 x^2; x-2; x/2; x^0.5;
 
 y=c(1,1,1,1)
 x-y; x+y; x*y;
 
 # die Ergebnisse können auch gespeichert werden:
 z=x-y

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.

R-Skript Output
 # R-Funktionen auf Vektoren anwenden: 
 x=c(2,4,5,6) 
 x=c(0,x) 
 length(x) 
 min(x) 
 max(x) 
 sum(x) 
 exp(x) 
 log(x) 
 sin(x) 
 var(x) 
 sort(x) 
 mean(x) 
 summary(x) 

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().
Der Quellcode enthält in
Zeile 2: Erzeugung der Sequenz von Werten 1,2,...,10 mittels Kurzform ":"
Zeile 3: Erzeugung der Sequenz von Werten 1,2,...,10 mit der Sequenzfunktion. Diese ermöglicht weitere Optionen, wie Festlegung der Schrittweite oder des Endwertes.
Zeile 8: Sequenz im Bereich 1 bis 10 mit Schrittweite 0.5 erzeugen
Zeile 9: äquidistante Zerlegung mit 5 Werten in [1;10] erzeugen
Zeile 13: Sequenz im Bereich -3 bis 5 mit Schrittweite 0.2 erzeugen
Zeile 14: Sequenz im Bereich 6 bis 1 mit Schrittweite -0.2 erzeugen

R-Skript Output
 # Sequenzen: Syntax: 
 1:10 #oder:
 seq(1,10)
 
 #liefert beides: [1]  1  2  3  4  5  6  7  8  9 10
 
 #seq mit anderen Optionen:
 seq(1,10,by=0.5)  #Schrittweite 0.5
 seq(1,10,length.out=5)      
  #äquidistante Zerlegung mit 5 Werten in  [1;10]
 
 # weitere Besipiele:
 seq(-3,5,0.2)
 seq(6,1,-0.2)

Beispiel: Wiederholungen erzeugen
Das Beispiel zeigt, wie Wiederholungen mit Hilfe der Funktion rep() erzeugt werden.
Der Quellcode enthält in

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 18,19: Rechenoperationen wie sin(), Multiplikation mit PI und Division durch 18 werden elementweise auf die Sequenz 0,1,2,..,36 angewandt, danch wird das Ergbenis auf 2 Nachkommastellen gerundet mit round(... ,2).

R-Skript Output
 # Wiederholungen: Syntax:
 rep(1,4)
 #Output: [1] 1 1 1 1
 rep(1:4,3)
 #Output: [1] 1 2 3 4 1 2 3 4 1 2 3 4
 
 rep(1:4,each=3)
 #Output: [1] 1 1 1 2 2 2 3 3 3 4 4 4
 
 rep(1:3,rep(4,3))
 #Output: [1] 1 1 1 1 2 2 2 2 3 3 3 3
 
 rep(1:4, c(2,1,2,1))
 #Output: [1] 1 1 2 3 3 4
 
 #Berechnet sin(0), sin(pi/18), sin(2*pi/18),...,sin(36*pi/18): 
 #0,10,20,...,360 in Grad
 c=0:36
 round(sin(c*pi/18),2)  
    #round(x,2) rundet Werte in x auf 2 Nachkommastellen

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 Gewichtsvektor 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.

Der Quellcode enthält in

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.

R-Skript Output
 # TRUE oder FALSE sind Ergebnisse logischer Operationen, z.B.
 3<4; 3==4; 3!=4; 4<4; 4<=4;
 
 x=c(1,2,3,5,10)
 x>=5
 
 # Beispiel: extrahiere Werte aus Daten mittels Bedingungen
 groesse=170:180
 gewicht=65:75
 
 gewicht[groesse<=174 ]
 # Output: [1] 65 66 67 68 69
 
 gewicht[groesse<=175 & gewicht >68 ]
 # Output: [1] 69 70
 groesse[groesse<=175 & gewicht >68 ]
 # Output:   [1] 174 175
 
 # die Funktion which() zeigt, an welcher Stelle 
 im Vektor (Index) ein bestimmter
 # Wert vorkommt.
 which(gewicht==70)
 
 # Wo steht das maximale Gewicht?
 maxIndex=which(gewicht==max(gewicht))
 gewicht[maxIndex]

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
 # Symbol: NA, Not Available 
 gewicht=c(65:68,NA,70:75) 
  
 # Rechnungen mit NA liefern NA als Ergebnis 
 gewicht*2 
 # [1] 130 132 134 136  NA 140 142 144 146 148 150 
 max(gewicht) 
 #[1] NA 
 max(gewicht, na.rm=TRUE)   
 #remove/loescht missing values und führt Operation aus 
 #[1] 75 
 mean(gewicht) 
 #[1] NA 
 mean(gewicht, na.rm=TRUE) 
 #[1] 70. 
  
 #undefinierte Rechnungen liefern NaN: Not a Number 
 0/0 
  
 # feststellen wo die fehlenden Werte sind: 
 is.na(gewicht) 
 !is.na(gewicht) 
  
 gewicht[!is.na(gewicht)] 
 mean(gewicht[!is.na(gewicht)]) 
 #Output: [1] 70.1 wie bereits vorher ohne NA  

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.

Der Quellcode enthält in

Zeile 1: der Gewichtsvektor wird als Sequenz erstellt
Zeile 4: 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 9,10: 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 10 wird das Label "Hans" benutzt um das Element mit diesem Label aus dem Gewichtsvektor auszugeben.

R-Skript Output
 gewicht=65:75
 
 # Zusammenfügen von Zeichen/-ketten:
paste("Blutdruck nach", c(0,2,4,6,8), "h", sep=" ")

 # names()- Funktion zur Benennung der
 # Elemente eines Vektors, Labeling:
 
 names(gewicht)= c("Hans", "Michael", "Maike", rep("NN",8))
 gewicht
 gewicht["Hans"]    

Matrizen

Matrizen sind 2-dimensionale Felder, die einen Zeilen- und einen Spaltenindex besitzen, diese beginnen bei 1. 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
 a=matrix(1:12,3,4) 
 #Daten werden default spaltenweise eingelesen
 b=matrix(1:12,3,4, byrow=TRUE) 
 #Daten werden zeilenweise eingelesen

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 zuverknü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
 groesse=170:180
 gewicht=65:75
 rbind(groesse, gewicht)
 z=cbind(groesse, gewicht)
 z

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 einzelner Elemente:
 a[1,4]
 # Submatrizen: mit [Zeilenangabe, Spaltenangabe]
 a[1:2,2:3]
 a[3,] #liefert nur die 3.Zeile mit allen Spalten, 
 # leerer Index steht für "alles"
 a[,2] #liefert nur die 2.Spalte mit allen Zeilen

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.

R-Skript Output
 # Extraktion aus Matrix:
 z[groesse<=175 ,]
 z[groesse<=175 & gewicht >68, ]

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
 C=matrix(1:6,2,3)
 D=3*C
 C;D;D+C;D-C;D*C;D/C,D^C
 t(C) #liefert die Transponierte von Matrix C
 
 # Matrixmultiplikation mit Zeichen %*%
 
 x=c(1,2,2)  #Spaltenvektor x
 
  C%*%x
 # Matrixmultiplikation:  C*C^T in R:
 C%*%t(C)

Weitere nützliche Funktionen für Matrizen
In R stehen weitere nützliche Funktionen für Standardfragen zu Matrizen zur Verfügung.

R-Skript Output
 # nützliche Funktionen für Matrizen:
 Z=matrix(c(1,2,3,4),2,2, byrow=TRUE)
 
 t(Z) 
 diag(Z)     #Diagonale, wenn Z quadratisch
 nrow(Z)     # Anzahl der Zeilen
 ncol(Z)     # Anzahl der Spalten
 dim(Z)      # Dimension
 rowMeans(Z) # Zeilenmittelwerte
 colMeans(Z) #Spaltenmittelwerte
 solve(Z) # Inverse einer quadratischen Matrix
 eigen(Z) # Eigenwerte und -vektoren quadratischer Matrizen
 
 eigen(Z)$values       #nur Eigenwerte
 eigen(Z)$vectors       #nur Eigenvektoren
 
 # Diagonalmatrizen erzeugen: 
 diag(4)      #liefert 4x4-Einheitsmarix 
 diag(c(1,2,3)) 

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. Mit dem data.frame()-Kommando werden Matrizen in Datensätze umgewandelt. Der Name eines Datensatzes beginnt standardmäßig mit einem Großbuchstaben. Datensätze haben 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
 A=matrix(c(1:12),3,4)
 A
 
 A.dframe=data.frame(A)
 A.dframe
 
 A.dframe %*% 1:4    #Fehler!
 as.matrix(A.dframe) %*% 1:4 #kein Fehler! 

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, die Variablen können auch nachträglich mit der names()-Funktion umbenannt werden.

R-Skript Output
 #Zeilenname, direkt beim Erzeugen des Datensatzes:
 
 A.dframe=data.frame(A, row.names=c("A","B","C")) 
 A.dframe
 
 # Variablen umbenennen:
 
 names(A.dframe) # Output: [1] "X1" "X2" "X3" "X4"
 names(A.dframe)=paste('Variable',1:4) 
 names(A.dframe)
 A.dframe

Objekttyp abfragen
Der Objekttyp kann mit class() abgefragt werden oder gezielt nach einem Datensatz gefragt werden mit der is.data.frame()-Funktion.

R-Skript Output
 # Objekttyp abfragen
 is.data.frame(A.dframe)
 class(A.dframe)"

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. Es kann aber auch die klassische Extraktionsweise von Matrizen genutzt werden mit Zeilen- und Spaltenaufruf in eckigen Klammern um Beobachtungen abzurufen.

R-Skript Output
 # einzelne Variablen abrufen: mit $-Zeichen
 A.dframe$"Variable 4"    #mit $SpaltenName 
 # oder wie bei Matrizen:
 A.dframe[,4]
 A.dframe[,"Variable 4"] # Spaltenaufruf über Variablenname
 
 A.dframe["A",] # Zeilenaufruf "A"
 A.dframe["A",-2] # Zeilenaufruf "A" ohne 2.Variable/Spalte

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. Zum Einfügen neuer Variablen und Beobachtungen stehen die Funktionen cbind() und rbind() zur Verfügung.

R-Skript Output
 subset1=subset(A.dframe, A.dframe$"Variable 1" >= 2)
 subset1
 
 #neue Variablen einfügen:
 A.dframe=cbind(A.dframe, geschlecht=c("w","m", "m"))
 
 #neue Beobachtungen einfügen:
 A.dframe=rbind(A.dframe, list(5,5,5,5, "w"))
 
 row.names(A.dframe)=c("A", "B", "C", "D")
 A.dframe

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() erzeugt automatisch einen Datensatz mit Format data.frame bei Einlesen einer Standard-Textdatei, die die folgende 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:

Andere Optionen können

sein. Beim Einlesen der Daten muss der Arbeitspfad richtig gesetzt sein und die Daten sich dann im gleichen Ordner wie das verwendete R-Skript befinden, dann muss nur der Name der Datei genannt werden. Wenn nicht, dann kann auch ein anderer Pfad bei Aufruf von read.table() angegeben werden.

R-Skript Output
 read.table("StandardData.txt") 
 kurs=read.table("Kursdaten00.txt",
   col.names=c("Alter", "Geschlecht", 
   "Groesse", "Textverarb", "Matlab", 
   "Python", "R", "AndereProg"))
 
 kurs

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 als Bezugsdatensatz festzulegen, d.h. der Variablenaufruf des Bezugsdatensatz kann ohne das $-Zeichen erfolgen. Mit detach wird der Bezugsdatensatz wieder entfernt.

R-Skript Output
 attach(kurs)
 
 Alter; Matlab; R;                
 #Aufruf der Variablen ohne kurs$VariablenName
 
 detach()     # Wichtig: entferne kurs als Bezugs-Datensatz
 
 Alter
 #Fehler! Da kein Bezugsdatensatz mehr vorhanden.

Autoren:
 M.Sc. Anke Welz
 Prof. Dr. Eva Maria Kiss
Tools: R, RStudio,
R-Dokumentation im Comprehensive R Archive Network (CRAN)