Software

Die Anwendung statistischer Methoden erfolgt heute in der Regel mittels entsprechender Software. Für unsere Statistikvorlesung werden wir die statistische Programmiersprache R einsetzen. Die folgende Einführung in R soll Ihnen den Einstieg erleichtern.

R und RStudio/Posit

R ist eine freie Programmiersprache für statistische Berechnungen und Grafiken. Sie ist eine der wichtigsten und am häufigsten verwendeten Programmiersprachen im Data Science Kontext. RStudio ist eine integrierte Entwicklungsumgebung oder IDE (Integrated Development Environment) für die Programmiersprache R und ein wichtiges Werkzeug bei der Arbeit mit R. R ist aktuell auf den wichtigsten Plattformen (Windows, Mac, Linux) verfügbar. Die Basis-Version von R sowie sämtliche Pakete sind über das “Comprehensive R Archive Network” (CRAN) abrufbar, das unter cran.r-project.org erreichbar ist. RStudio ist eine integrierte Entwicklungsumgebung für die Programmiersprache R und bietet für viele Funktionen von R eine grafische Benutzeroberfläche. Das Unternehmen hat sich vor kurzem von RStudio zu Posit umbenannt. Eine Softwareprodukte tragen noch den Namen RStudio, andere heißen bereits Posit.

RStudio Server der FH Münster

An der FH Münster haben Sie Zugang zur RStudio Workbench (heute Posit Workbench). Dieser ist erreichbar unter der Domain r-workbench.fh-muenster.de.

Zur Anmeldung verwenden Sie Ihre FH Kennung und das dazugehörige Passwort. Außerhalb des FH-Datennetzes ist die VPN Verbindung notwendig1.

Alternative 1: Installation von R und RStudio

Sie können R und RStudio auch lokal auf Ihrem eigenen Rechner installieren. Dazu können beide Softwarepakete heruntergeladen werden:

Anschließend müssen beide Programme in genau dieser Reihenfolge installiert werden (zunächst R, dann RStudio). Eventuell müssen noch zusätzliche Pakete nachinstalliert werden.

Alternative 2: RStudio Cloud (heute Posit Cloud)

RStudio/Posit Cloud ist eine cloudbasierte Lösung, mit der jeder online Statistik betreiben, teilen, lehren und lernen kann. Sie können Posit Cloud kostenlos nutzen, die Nutzungsdauer ist allerdings auf 25 Stunden pro Monat begrenzt. Um RStudio Cloud nutzen zu können, erstellen Sie sich dazu einen Account unter posit.cloud.

Verwendung von R und RStudio

Während R lediglich eine Konsole mit einem einfachen Editor zur Verfügung stellt, erweitert die Entwicklungsumgebung von RStudio die Funktionalität von R um viele weitere nützliche Tools.

Dabei unterscheiden sich die Server- und Desktop-Version von RStudio nicht wesentlich in ihrer Verwendung. Nur beim Laden von lokal gespeicherten Daten oder der Installation von Paketen gibt es kleinere Unterschiede zu beachten.

Aufbau von RStudio

RStudio zeigt standardmäßig verschiedene “Panes” (engl. Fensterausschnitte) (Abbildung 1). Diese Bereiche sind für unterschiedliche Aufgaben der Entwicklungsumgebung konzipiert. Sie lassen sich beliebig in der Größe verändern, auch die Inhalte lassen sich im Menü anpassen. Einige Panes können auch in einem weiteren (Browser-)Fenster angezeigt werden, was hilfreich ist, wenn man mit mehreren Monitoren arbeitet.

Im Wesentlichen lassen sich die Bereiche der Oberfläche nach ihren Aufgaben unterteilen, wie in Abbildung Abbildung 1 dargestellt.

Editor (1)

Im Editor werden standardmäßig R Programme erstellt. Diese enthalten eine Abfolge von Kommandos, Funktionen, Funktionsaufrufen etc., die in R ausgeführt werden sollen. Diese können in .R Dateien für die spätere Weiterbearbeitung und Verwendung abgespeichert werden.

Konsole (2)

Die Konsole bzw. Kommandozeile ist ein Eingabebereich für die Steuerung von R. Eingaben in die Konsole werden vom R Interpreter ausgewertet und die Ergebnisse der Berechnung wieder in der Konsole ausgegeben. R Skripte, welche im Editor erstellt werden, werden beim Ausführen in die Konsole gespielt und dort ausgeführt.

Umgebung, Historie, Versionskontrolle (3)

In diesem Bereich werden nützliche Informationen während der Arbeit mit R Skripten angezeigt. So werden beispielsweise alle in der Umgebung (Environment) definierten Variablen angezeigt, die Historie aller ausgeführten Befehle aufgelistet und es gibt die Möglichkeit zur Versionskontrolle.

Dateien, Grafiken, Pakete, Hilfe (4)

Über diesen Bereich haben Sie Zugriff auf das Dateisystem des RStudio Servers, Sie können also auf Ihre dort abgelegten Dateien zugreifen (R-Skripte, Datensätze, exportierte Abbildungen etc.). Bei der Desktop-Version können Sie entsprechend auf das Dateisystem Ihres Rechners zugreifen. Wenn Sie mit R Grafiken erstellen, werden diese in diesem Pane angezeigt. Sie haben außerdem die Möglichkeit, die Abbildungen abzuspeichern. Außerdem gibt es die Möglichkeit über den Reiter ‘Packages’ zusätzliche Pakete für R zu installieren bzw. installierte Pakete zu aktualisieren. Schließlich ist eine der wichtigsten Funktionen in diesem Bereich die Hilfe: Sie können auf die Hilfe und Dokumentation jeder einzelnen R-Funktion zugreifen.

Abbildung 1: Panes in RStudio

Grundlegende Befehle

Im Editor bzw. der Konsole kann R z.B. als Taschenrechner genutzt werden, es in Abbildung 2 abgebildet ist. Hierbei können unterschiedliche Operatoren verwendet werden, wie z.B.

  • Verwendung von Grundrechenarten wie plus (+), minus (-), mal (*), geteilt (/)
  • elementare Funktionen wie Exponentialfunktionen (^), Logarithmusfunktionen (log()) oder Quadratwurzelfunktionen (sqrt())
  • Trigonometrische Funktionen: sin(), cos()
  • Absolutbetrag (abs()) oder Rundenfunktion (round())
  • Nutzung von Vergleichsoperatoren: größer (>), größer gleich (>=), gleich (==), ungleich (!=), kleiner gleich (<=), kleiner (<)
  • Logische Operatoren: logisches UND (&), logisches ODER (|)
  • Verwendung der Wahrheitswerte: TRUE, FALSE

Im Editor oben wird die Rechnung in eine Zeile eingegeben und mit STRG+Enter ausgeführt. Das Ergebnis steht unten in der Konsole. In dieser kann auch gerechnet werden, nur die Rechnungen und Kommentare können nicht gespeichert werden. Aber mit einem einfachen Enter am Ende der Rechenzeile wird die Eingabe ebenso ausgeführt.

Abbildung 2: Eingabe im Editor und der Konsole in R Studio

Beispiele für Arithmetische Operatoren

  • Die Eingabe von 3+4 ergibt die Lösung 7:
3+4
[1] 7
  • Die Eingabe von (2+1)*3-3 ergibt die Lösung 6:
(2+1)*3-3
[1] 6
  • D.h. es kann mit Klammern gerechnet werden und mathematische Rechengesetze wie Punkt- vor Strichrechnung werden beachtet.
  • Die Eingabe von 2/0.5+1 ergibt die Lösung 5:
2/0.5+1
[1] 5
  • In R ist das Dezimaltrennzeichen ein Punkt, kein Komma, wie es sonst im deutschsprachigen Raum verwendet wird.
  • Die Eingabe von -1+5 ergibt die Lösung 4:
-1+5
[1] 4
  • D.h. negative Zahlen werden einfach mit einem Minuszeichen beschrieben.

Beispiele für das Rechnen mit Exponenten, Logarithmen oder Wurzeln

  • Die Eingabe von 2^3 bedeutet “2 hoch 3” und ergibt das gleiche Ergebnis wie 2 * 2 * 2, also 8.

  • Die Eingabe von sqrt(4) ergibt die Quadratwurzel aus 4, also 2.

  • Die Eingabe von 8^(1/3) bedeutet “8 hoch 1/3” und ergibt somit die dritte Wurzel aus 8, also 2.

  • Die Eingabe von 2^(-1) ergibt das gleiche Ergebnis wie 1/2, also 0.5.

  • Der Logarithmus zur Basis 10 kann z.B. mit log10(10) berechnet werden und ergibt hier die Lösung 1.

  • Der Logarithmus zur Basis 2 kann z.B. mit log2(4) berechnet werden und gibt hier die Lösung 2.

  • Der natürliche Logarithmus zur Basis e kann z.B. mit log(1) berechnet werden und ergibt hier die Lösung 0.

  • Der Wert für die Eulersche Zahl e kann mit exp(1), also “e hoch 1” abgerufen werden.

Beispiele zum Runden und Berechnen des Absolutbetrags von Zahlenwerten

  • Die Eingabe von round(5.1234, 2) nutzt die Funktion zum Runden von Zahlen. Hier ergibt sich der auf zwei Nachkommastellen gerundete Wert 5.12. Die erste Zahl in runden Klammern gibt die zu rundende Zahl als erstes übergebenes Argument an, die zweite, hier das optionale zweite Argument, gibt an, auf wie viele Nachkommastellen gerundet werden soll.
  • Die Eingabe von round(5.1234) ergibt den auf 0 Stellen gerundeten Wert 5.
  • Die Eingabe von abs(-2) ergibt den Absolutbetrag von 2.
  • Die Eingabe in den Funktionsaufrufen kann auch Formeln oder komplexere Abfragen bzw. weitere Funktionen enthalten, so ergibt die Eingabe von abs(10-20) z.B. den Absolutbetrag von -10, also 10.
  • Die Eingabe von der zu rundenden Funktion mit Rechnung, d.h. round(abs(2-5.4321),2) ergibt 3.43.

Beispiele für Logische Operatoren und Vergleichsoperatoren

Abbildung 3: Nutzung von Vergleichsoperatoren sowie logischen Operatoren

Werden Vergleiche zwischen zwei einzelnen Eingaben aufgestellt, ergibt sich als Ausgabe stets einer der Wahrheitswerte TRUE oder FALSE, wie in Abbildung 3 für einige Beispiele gezeigt wird. Die Eingabe

sqrt(2) > 1.5
[1] FALSE

berechnet den Wert für Wurzel aus 2 und vergleicht, ob dieser Wert größer als 1.5 ist. Da dies nicht der Fall ist, wird hier FALSE zurückgegeben.

Verwenden der Hilfefunktion in R Studio

Für alle Funktionen in R kann eine Hilfefunktion aufgerufen werden. Mit ?(funktion) oder auch help(funktion) wird die Hilfefunktion für die Funktion funktion aufgerufen und eine Dokumentation der Funktion inkl. optionaler Argumente im rechten unteren Fenster in R-Studio aufgezeigt. Mit args(funktion) werden die Argumente einer Funktion gezeigt, mit example(funktion) werden unterschiedliche Beispielaufrufe einer Funktion gezeigt, wie Sie in Abbildung 4 sehen können.

Abbildung 4: Hilfefunktion für die Funktion round() in R Studio

Dabei bedeutet in der Hilfe die Zeile round(x, digits = 0), dass die Zahl x mit der Funktion round() defaultmäßig auf eine ganze Zahl ohne Nachkommastellen gerundet wird.

Objekte, Zuweisungen und Environments

Grundsätzlich lassen sich Objekte neuen Variablen mit Hilfe eines Pfeils <- zuweisen. Wollen wir zum Beispiel der Variable x den Wert 5 zuweisen, y den Wert 2 und z den Wert 1, so schreiben wir

x <- 5
y <- 2
z <- 1

Wenn wir dann im Folgenden den Wert von x ansehen möchten, geben wir einfach x ein und erhalten das Resultat zurück:

x
[1] 5

Wir können mit x und y nun auch Berechnungen anstellen, so ergibt sich \(x^y = 5^2\) mit

x^y
[1] 25

Zuweisungen auf ein schon bestehendes Objekt, überschreibt dieses:

a <- 1
a <- 2
a
[1] 2

Mit einer Zuweisung wird ein Objekt also erstellt und ist in der Arbeitsumgebung (Environment) von nun an verfügbar. In RStudio können wir diese Objekte auch in dem entsprechenden oberen rechten Fensterabschnitt im Reiter “Environment” sehen (siehe Abbildung 5).

Abbildung 5: Darstellung der Environment in RStudio

Zuweisungen können grundsätzlich auch mit einem = erfolgen, d.h. x = 5 würde ebenfalls der Variable x den Wert 5 zuweisen. Sie werden diese Schreibweise immer wieder in fremdem R-Code finden. Allerdings wird von dieser Schreibweise abgeraten, da das Gleichheitszeichen auch für die Definition von Parametern in Funktionen verwendet wird und damit zu Fehlern führen kann.

Möchte man ein Objekt wieder aus der Umgebung entfernen, geschieht dies über die Funktion rm, in unserem Fall also

rm(x)

Möchte man mehrere Objekte in der Umgebung löschen, listet man diese in der Funktion rm einfach auf (z. B. rm(x,y)).

Möchte man sich alle Objekte in der aktuellen Environment anzeigen lassen, so geht dies mit der “List Objects” Funktion

ls()
[1] "a" "y" "z"

Alle verfügbaren Objekte werden mit Ihrem Namen (also in Anführungszeichen) aufgelistet. Zu diesem Zeitpunkt sind also nur noch a, y und z in der Umgebung verfügbar, da wir zuvor x entfernt haben. Möchten wir alle Objekte der Umgebung löschen, können wir dies mit dem Befehl

rm(list = ls())

erledigen.

Einzelne oder mehrere Objekte aus einer Umgebung, ja sogar die gesamte Umgebung lassen sich in einer Datei abspeichern und später wieder laden. Hierfür gibt es die Befehle save (bzw. save.image) und load. Hierzu gibt man die Objekte an, welche abgespeichert werden sollen (durch Komma getrennt) und anschließend mit dem Argument file einen Pfad und Dateinamen, in dem die Objekte abgelegt werden. Beispielsweise speichern wir mit

save(y,z, file = "C:/Daten/datenxy.RData")

die Objekte y und zin der Datei “datenxy.RData” im Ordner “C:/Daten” ab. Typischerweise verwendet man für R Objekte die Dateiendung “.RData” oder “.rds”. Die gesamte Arbeitsumgebung lässt sich mit dem Befehl save.image unter einem beliebigen Pfad abspeichern.

Mit dem Befehl

load(file = "C:/Daten/datenxy.RData")

können wir zu einem späteren Zeitpunkt alle Objekte aus der Datei “datenxy.RData” wieder in unsere Umgebung laden.

Mit dem load Befehl lassen sich nur R Objekte laden. Datensätze in Formaten wie Excel, als Textdatei oder gar in Datenbanken lassen sich hiermit nicht einlesen.

Datentypen und Datenstrukturen

Atomische Datentypen

Wie in jeder Programmiersprache werden auch in R Daten in verschiedenen Typen abgespeichert. Ähnlich wie die Skalenniveaus aus der Statistik unterscheiden diese Typen die Daten nach Informationsgehalt (z. B. metrisch und nominal skalierte Daten). Außerdem wird über die Datentypen geregelt, wie R die Daten intern im Arbeitsspeicher ablegt.

Die von R verwendeten Datentypen sind

  • numeric: Dezimalzahlen
  • integer: ganzzahlige Zahlen
  • complex: komplexe Zahlen
  • logical: logische Werte (d.h. wahr oder falsch, bzw. in R TRUE oder FALSE)
  • character: Textzeichen

Um festzustellen, welcher Typ einem Objekt in R zugewiesen wurde, verwenden wir die Funktion mode

x <- 5
mode(x)
[1] "numeric"
y <- TRUE
mode(y)
[1] "logical"

Man kann auch die einzelnen Typen abfragen, indem man vor die Typenbezeichnung ein is.setzt:

is.numeric(x)
[1] TRUE
is.character(x)
[1] FALSE

R gibt in diesem Fall ein TRUE oder FALSE zurück, je nachdem ob das Objekt den jeweiligen Datentyp besitzt. Mit einem as. gefolgt von der Typenbezeichnung lässt sich der Datentyp eines Objekts konvertieren:

x2 <- as.integer(x)
is.integer(x2)
[1] TRUE
x3 <- as.character(x)
mode(x3)
[1] "character"
x3
[1] "5"

Neben diesen Datentypen gibt es außerdem einige besondere Typen:

  • NaN: “Not a Number”, kommt zum Beispiel durch Teilen durch 0 zustande
  • NA: “Not Available”, also fehlender Wert
  • NULL: leeres Objekt
  • Inf, -Inf: Unendlich (positiv und negativ)

Datenstrukturen

Wenn wir mit Daten arbeiten, nutzen wir typischerweise Strukturen, um einzelne Zahlen zu größeren Objekten zusammenzufassen. Einfachste Beispiele hierfür sind Vektoren und Matrizen. Neben diesen gibt es weitere Datenstrukturen in R, mit denen man arbeiten kann. Sie unterscheiden sich im Wesentlich dadurch, wie viele Dimensionen sie umfassen

  • vector: Vektor – eindimensionale Kombination von atomischen Datenpunkten gleichen Typs
  • matrix: Matrix – zweidimensionale Kombination von atomischen Datenpunkten gleichen Typs
  • array: Array – mehrdimensionale Kombination von atomischen Datenpunkten gleichen Typs
  • list: Liste – eindimensionale Kombination von atomischen Datenpunkten unterschiedlichen Typs
  • data.frame: Data Frame – zweidimensionale Kombination von atomischen Datenpunkten unterschiedlichen Typs
Abbildung 6: Datenstrukturen in R

Vektoren

Einen Vektor können wir erstellen, indem wir mehrere atomare Objekte (oder andere Vektoren) mit Hilfe der “Combine”-Funktion verknüpfen:

x <- c(1,2,3)
x
[1] 1 2 3

Für ganzzahlige Zahlenfolgen können wir die Kurzschreibweise m:n verwenden:

x <- -5:5
x
 [1] -5 -4 -3 -2 -1  0  1  2  3  4  5

Um auf einzelne Elemente aus einem Vektor zuzugreifen, geben wir in eckigen Klammern die Stellen im Vektor an, die zurückgegeben werden sollen. Diese Stellen nennt man auch Index.

x[1]
[1] -5
x[4:5]
[1] -2 -1

Ein vorangesetztes Minus-Zeichen ergibt, dass alle Elemente des Vektors ausgegeben werden außer diejenigen mit negativem Index

x[-1]
 [1] -4 -3 -2 -1  0  1  2  3  4  5
x[-c(1,6)]
[1] -4 -3 -2 -1  1  2  3  4  5

Über die Indizierung lassen sich auch einzelne Werte überschreiben

x[1] <- 10000
x
 [1] 10000    -4    -3    -2    -1     0     1     2     3     4     5

Statt eines Index’ kann die Referenzierung auch mit Hilfe von logischen Werten erfolgen. Dazu ist ein logischer Vektor der gleichen Länge zu verwenden – die Rückgabe entspricht dann allen Einträgen, für die der logische Vektor gleich TRUE ist.

x <- 1:5
y <- c(TRUE, FALSE, TRUE, FALSE, TRUE)
x[y]
[1] 1 3 5

Matrizen und Arrays

Matrizen sind Datenstrukturen mit zwei Dimensionen (Zeilen und Spalten), Arrays können beliebig viele Dimensionen haben, was deren Darstellung in der zwei-dimensionalen Konsole schwieriger macht.

Matrizen oder Arrays können direkt aus Vektoren erstellt werden:

x <- 1:12
m1 <- matrix(x, nrow = 3, byrow = TRUE)
m1
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
m2 <- matrix(x, nrow = 4, byrow = FALSE)
m2
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12
a <- array(x, dim = c(2,2,3))
a
, , 1

     [,1] [,2]
[1,]    1    3
[2,]    2    4

, , 2

     [,1] [,2]
[1,]    5    7
[2,]    6    8

, , 3

     [,1] [,2]
[1,]    9   11
[2,]   10   12

Auf die einzelnen Elemente aus einer Matrix oder einem Array kann man auch wieder über die eckigen Klammern zugreifen, wobei die Dimensionen durch ein Komma getrennt werden. Bei einer Matrix entsprechen die Zeilen der ersten Dimension und die Spalten der zweiten Dimension. Das heißt, möchten wir von Matrix m1 das Element in der zweiten Zeile und dritten Spalte auswählen, erfolgt dies mit

m1[2,3]
[1] 7

Auch hier könnte man wie bei Vektoren logische Werte für die Referenzierung verwenden.

Um ganze Zeilen oder Spalten auszuwählen, wird die jeweils andere Dimension leer gelassen. Es können auch mehrere Zeilen oder Spalten gleichzeitig gewählt werden. So ergibt sich zum Beispiel für m1 für die Auswahl der zweiten und vierten Spalte

m1[,c(2,4)]
     [,1] [,2]
[1,]    2    4
[2,]    6    8
[3,]   10   12

Negative Indizes funktionieren genau wie bei Vektoren und helfen dabei, auf alle Elemente bis auf ausgewählte zuzugreifen.

a[1,2,-2]
[1]  3 11

Matrizen (und Vektoren) transponiert man mit der Funktion t

t(m1)
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12

Die gewöhnliche Addition oder Multiplikation (auch Potenzieren) von Skalaren mit Vektoren oder Matrizen erfolgt elementweise

3+x
 [1]  4  5  6  7  8  9 10 11 12 13 14 15
x^2
 [1]   1   4   9  16  25  36  49  64  81 100 121 144
2*m1
     [,1] [,2] [,3] [,4]
[1,]    2    4    6    8
[2,]   10   12   14   16
[3,]   18   20   22   24

Das Skalarprodukt kann per %*% verwendet werden:

v1 <- 1:3
v2 <- 1:4
t(v1) %*% m1 %*% v2
     [,1]
[1,]  500

Vektoren, Matrizen und Arrays enthalten immer nur einen Datentyp. Dieser wird immer gewählt als der Datentyp, in den sich alle einzelnen Elemente höchstens umwandeln lassen (je höher das Skalenniveau, umso besser). Eine Zahl kann beispielsweise leicht in einen Text bzw. Character umgewandelt werden, andersherum funktioniert das aber nicht.

x <- c(1,2,3,"R")
x
[1] "1" "2" "3" "R"
mode(x)
[1] "character"
as.numeric(x)
Warning: NAs introduced by coercion
[1]  1  2  3 NA

Listen

Listen sind eindimensionale Datenstrukturen, welche jedoch in den einzelnen Elementen Daten unterschiedlichen Typs enthalten können. So kann eine Liste zum Beispiel im ersten Element eine Zahl enthalten und im zweiten einen Character. Das ist bei Vektoren wie oben gesehen nicht möglich.

x <- list(1,2,3,"R")
x
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

[[4]]
[1] "R"

Listen können auch als Elemente nicht-atomare (sogar beliebige) Datenstrukturen enthalten, zum Beispiel Vektoren, Matrizen oder Arrays (ja sogar andere Listen!). Außerdem können einzelne Elemente mit einem Namen versehen werden.

l <- list(Vektor = 1:10, 
          Matrix = matrix(1:12, nrow = 3), 
          Array = array(1:12, dim = c(2,2,3)), 
          Character = c("a","b","c"))
l
$Vektor
 [1]  1  2  3  4  5  6  7  8  9 10

$Matrix
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

$Array
, , 1

     [,1] [,2]
[1,]    1    3
[2,]    2    4

, , 2

     [,1] [,2]
[1,]    5    7
[2,]    6    8

, , 3

     [,1] [,2]
[1,]    9   11
[2,]   10   12


$Character
[1] "a" "b" "c"

RStudio hilft dabei, durch sinnvolle Einrückungen den Code lesbarer zu machen. Im obigen Beispiel hilft der Zeilenumbruch nach jedem definierten Listenelement dabei, dass der Code nicht in einer sehr langen Zeile resultiert. Die Einrückungen nach dem Zeilenumbruch macht RStudio automatisch, und zwar so, dass der Code logisch strukturiert und gut lesbar ist.

Auf einzelne Listenelemente kann man auf verschiedene Arten zugreifen – entweder über einen Index in doppelten eckigen Klammern, über die Referenzierung mit logischen Werten oder über den Namen des Listenelements nach einem Dollarzeichen:

x[[1]]
[1] 1
x$Vektor
NULL

Data Frames

Der Data Frame ist die Datenstruktur, die in R wahrscheinlich am häufigsten zur Anwendung kommt. Ein Data Frame entspricht dem, wie wir uns eine typische Datentabelle vorstellen. Ähnlich wie eine Matrix hat ein Data Frame zwei Dimensionen (Zeilen und Spalten). Die Spalten entsprechen dabei den Variablen, die Zeilen den Beobachtungen des Datensatzes. Entsprechend kann im Unterschied zu einer Matrix jede Spalte eines Data Frames einen unterschiedlichen Datentyp haben (z. B. numerisch als numeric, kategoriell als factor), was uns wiederum an Listen erinnert. Spalten und Zeilen von Data Frames bekommen Namen.

Im Grunde sind Data Frame nichts anderes als Listen, die etwas anders darstellt werden und einige Einschränkungen haben (z. B. jedes Listenelement = Spalte ist ein Vektor und gleich lang) – mehr dazu siehe http://adv-r.had.co.nz/Data-structures.html#data-frames.

Data Frames lassen sich neu definieren, aus Matrizen erstellen, oder auch aus externen Datenquellen einlesen.

as.data.frame(m1)
  V1 V2 V3 V4
1  1  2  3  4
2  5  6  7  8
3  9 10 11 12

Wenn nicht anders angegeben, lauten die Namen der Zeilen 1,2,3,… und die Namen der Spalten V1, V2, V3, … – es können aber auch Namen bei der Definition angegeben werden

df <- data.frame(Name = c("Mueller", "Meyer", "Schneider", "Meyer", "Meier"), 
                 Alter = c(45,23,62,32,22), 
                 Premiumkunde = c(TRUE, FALSE, FALSE, TRUE, TRUE))
df
       Name Alter Premiumkunde
1   Mueller    45         TRUE
2     Meyer    23        FALSE
3 Schneider    62        FALSE
4     Meyer    32         TRUE
5     Meier    22         TRUE

Ähnlich wie bei Listen, kann auch bei Data Frames der Zugriff auf einzelne Elemente über die Namen oder Indizes erfolgen:

df$Alter
[1] 45 23 62 32 22
df[3,]
       Name Alter Premiumkunde
3 Schneider    62        FALSE
df[1,2]
[1] 45

R enthält viele Datensätze (als Data Frames), mit denen man üben und Algorithmen testen kann. Es gibt dafür ein spezielles Paket, welches in der Basis-Installation von R bereits enthalten ist: datasets (für eine Übersicht: help(package = "datasets")). Diese Datensätze lassen sich ganz einfach mit ihrem Namen aufrufen, z. B. der Datensatz iris ist bereits in der Umgebung verfügbar und kann direkt verwendet werden.2

Kategorielle Variablen

In der Statistik arbeitet man häufig mit ordinal oder nominal skalierten Daten. Hierfür bietet R einen speziellen Datentyp: factor.

Ein factor wird in R intern als Merkmal mit ganzzahligen Ausprägungen gespeichert. Jeder dieser Ausprägungen kann ein “Label” vergeben werden. Faktoren lassen sich zum Beispiel aus character-Vektoren erstellen:

automarke_chr <- c("Opel", "BMW", "Mercedes", "Mercedes", "Opel", "BMW")
automarke_factor <- factor(automarke_chr)
automarke_chr
[1] "Opel"     "BMW"      "Mercedes" "Mercedes" "Opel"     "BMW"     
automarke_factor
[1] Opel     BMW      Mercedes Mercedes Opel     BMW     
Levels: BMW Mercedes Opel

Bei der Ausgabe eines Faktors werden die Beobachtungen angezeigt und auch eine Übersicht über die enthaltenen Faktorlevels (Kategorien) gegeben. Auf diese kann man auch über die Funktion levels zugreifen und die Bezeichnungen gegebenenfalls überschreiben:

levels(automarke_factor)
[1] "BMW"      "Mercedes" "Opel"    
levels(automarke_factor)[2] <- "Mercedes Benz"
automarke_factor
[1] Opel          BMW           Mercedes Benz Mercedes Benz Opel         
[6] BMW          
Levels: BMW Mercedes Benz Opel

Für einen Faktor mit definierten Faktorlevels können keine Beobachtungen mit anderen Faktorlevels eingetragen werden

automarke_factor[1] <- "BMW"
automarke_factor
[1] BMW           BMW           Mercedes Benz Mercedes Benz Opel         
[6] BMW          
Levels: BMW Mercedes Benz Opel
automarke_factor[1] <- "Audi"
Warning in `[<-.factor`(`*tmp*`, 1, value = "Audi"): invalid factor level, NA
generated
automarke_factor
[1] <NA>          BMW           Mercedes Benz Mercedes Benz Opel         
[6] BMW          
Levels: BMW Mercedes Benz Opel

Dazu muss zunächst ein zusätzliches Faktorlevel definiert werden

levels(automarke_factor) <- c(levels(automarke_factor), "Audi")
automarke_factor
[1] <NA>          BMW           Mercedes Benz Mercedes Benz Opel         
[6] BMW          
Levels: BMW Mercedes Benz Opel Audi
automarke_factor[1] <- "Audi"
automarke_factor
[1] Audi          BMW           Mercedes Benz Mercedes Benz Opel         
[6] BMW          
Levels: BMW Mercedes Benz Opel Audi

Intern werden die Faktorstufen als Integer abgespeichert (in der Reihenfolge der Faktorlevels beginnend mit 1, also hier: BMW = 1, Mercedes Benz = 2, Opel = 3 und Audi = 4). Wenn man einen Faktor in einen numeric umwandelt, entsprechen die Elemente diesen Werten.

as.numeric(automarke_factor)
[1] 4 1 2 2 3 1

Neben den hier vorgestellten Datentypen gibt es noch viele weitere, die jeweils für spezielle Aufgaben gedacht sind. So gibt es beispielsweise Datentypen für Datum, Zeitreihen, Geokoordinaten etc., welche an dieser Stelle nicht im Detail vorgestellt werden.

Ermitteln der Struktur eines Objektes

Strukturen von Objekten können sehr komplex und verschachtelt sein (z. B. Listen mit vielen verschiedenen Datentypen). Die Funktion str fasst die Struktur zusammen und macht sie so transparent. Sie gibt die interne Struktur eines R Objekts zurück. Für jedes grundlegende Strukturelement gibt sie eine Zeile mit den wesentlichen Informationen zurück. Für die Liste l ist dies der Typ, die Größe und einige Werte der Listenelemente.

str(l)
List of 4
 $ Vektor   : int [1:10] 1 2 3 4 5 6 7 8 9 10
 $ Matrix   : int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
 $ Array    : int [1:2, 1:2, 1:3] 1 2 3 4 5 6 7 8 9 10 ...
 $ Character: chr [1:3] "a" "b" "c"

Für den Data Frame df wird die Anzahl Beobachtungen und Variablen angegeben, sowie eine kurze Übersicht über jede einzelne Variable.

str(df)
'data.frame':   5 obs. of  3 variables:
 $ Name        : chr  "Mueller" "Meyer" "Schneider" "Meyer" ...
 $ Alter       : num  45 23 62 32 22
 $ Premiumkunde: logi  TRUE FALSE FALSE TRUE TRUE

Deskriptive Statistik in R

Absolute und relative Häufigkeiten

Für einen ersten Überblick über die Datengrundlage kann man sich z.B. auch eine Häufigkeitstabelle erstellen lassen. Im Folgenden soll der Vektor

muenze <- c("Kopf", "Zahl", "Zahl", "Kopf", 
            "Kopf", "Zahl", "Zahl", "Zahl", 
            "Zahl", "Kopf")

das Ergebnis von zehn Münzwürfen angeben. Mit

table(muenze) 
muenze
Kopf Zahl 
   4    6 

werden die absoluten Häufigkeiten des gesamten Vektors bestimmt und ausgegeben. Relative Häufigkeiten nutzen die Funktion für absolute Häufigkeiten und geben den prozentualen Anteil der unterschiedlichen Ausprägungen aus, wie man mit

prop.table(table(muenze))
muenze
Kopf Zahl 
 0.4  0.6 

sehen kann. Alternativ kann eine Häufigkeitstabelle mit den relativen Anteilen auch mit

table(muenze)/length(muenze)
muenze
Kopf Zahl 
 0.4  0.6 

erstellt werden, wie es in Abbildung 7 dargestellt ist.

Abbildung 7: Häufigkeitstabellen und Säulendiagramm für Münzwurf-Vektor

Säulendiagramme

Graphisch ausgeben kann man solche Häufigkeitstabellen z.B. mit Hilfe eines Säulen- oder eines Tortendiagramms. Säulendiagramme können mit der Funktion barplot() ausgegeben werden, erwartet als erstes Argument einen Vektor, der die Höhen der darzustellenden Säulen enthält. D.h. wenn eine Tabelle mit (absoluten) Häufigkeiten, d.h. mit

barplot(table(muenze))

übergeben wird, wird die Verteilung des Münzwurfs aus dem Vektor muenze jetzt visualisiert. Mit table(muenze) werden die Höhen der einzelnen Balken übergeben. Die Breite der Balken ist immer gleich. Mit weiteren Argumenten wie main, xlab oder ylab können Überschriften und Achsenbeschriftungen hinzugefügt werden, wie man bei

barplot(table(muenze), 
        main="Überschrift", 
        xlab="Beschriftung der x-Achse", 
        ylab="Beschriftung der y-Achse")

und in Abbildung Abbildung 7 sehen kann. Weitere Argumente finden sich in der Hilfedokumentation.

Visuelle Analyse für metrische Variablen

Liniendiagrammen

Für stetige Daten kann der Verlauf dieser auch mit Hilfe eines Liniendiagramms dargestellt werden. Mit der Funktion plot() kann beispielsweise der Vektor a visualisiert werden:

plot(a)

oder auch

plot(a, type="l")

wobei das l für “line” steht. Auch hier können mit den optionalen Argumenten wie main, col, xlab oder ylab können Überschriften, Farben und Achsenbeschriftungen hinzugefügt werden:

plot(a, col="blue", 
     main="Überschrift", 
     xlab="neun Punkte", 
     ylab="Wert der Punkte")

Weitere Argumente stehen in der Hilfe zur Funktion plot(). Soll eine weitere Datenreihe, z.B.

b <- c(10,9,4,15,9,20,2,3,11)

in der gleichen Ausgabe visualisiert werden, kann die Funktion lines() genutzt werden:

plot(a, col="blue", 
     main="Überschrift", 
     xlab="neun Punkte", 
     ylab="Wert der Punkte")
lines(b, col = "red")

Histogramm

Um die empirischen Verteilung eines kontinuierlichen Merkmals zu visualisieren, kann ein Histogramm verwendet werden. Dies kann für den Vektor

wuerfel <- c(1, 1, 5, 5, 4, 6, 1, 2, 6, 3, 4, 2, 1, 2, 5, 6, 2, 2, 1, 1, 5, 6, 1, 1, 4)

mit

hist(wuerfel)

visualisiert werden. Die Funktion hist() erwartet dabei als erstes Argument den Vektor der darzustellenden Daten (kein Häufigkeitsdiagramm). Die Höhe der Zellen entspricht dabei standardmäßig (für das Argument freq=TRUE) der absoluten Klassenhäufigkeit. Alternativ kann auch mit dem Flächeninhalt der jeweiligen Zellen die relative Klassenhäufigkeit angegeben werden. In diesem Fall ändert sich die Beschriftung der y-Achse, wie man hier sehen kann:

hist(wuerfel, freq=FALSE)

Die Anzahl der darzustellenden Klassen, die im Histogramm festgelegt werden, kann mit dem Argument breaks beeinflusst werden.3 Mit folgendem Befehl werden 6 Klassen erzeugt:

hist(wuerfel, breaks=6)

Alternativ können auch die Grnezen explzit angegeben werden:

hist(wuerfel, breaks = seq(0,6, length=6))

Boxplots

Ein Boxplot ist eine sehr kompakte Art der Darstellung empirischer Verteilungen. Dieser Diagramm-Typ ermöglicht es, schnell einen Eindruck darüber zu vermitteln, in welchem Bereich die Daten liegen und wie sie sich verteilen. Hier können auf einen Blick, Lage, Streuung und Symmetrie einer Verteilung erfasst werden, da Median, die zwei Quartile und die beiden Extremwerte visualisiert werden. Der Vektor box sei

box <- c(1,2,3,4,2,2,3,4,1,2,3,4,3,2,1,1,1,1,1,1,1,1-3,10)

und kann im Boxplot visualisiert werden:

boxplot(box)

Diese Werte werden mit dem Boxplot visualisiert: Die untere Grenze der Box entspricht dem 1. Quartil, d.h. 25% der Daten sind größer als dieser Wert. Die obere Grenze der Box entspricht dem 3. Quartil, d.h. 75% der Daten sind kleiner als dieser Wert. Die Breite der Box, also der Wert der Differenz zwischen dem 1. und 3. Quartil ergibt den sogenannten Interquartilsabstand (IQ). Der Strich in der Box entspricht dem Median, welcher auch 2. Quartil genannt wird, bei dem 50% der Daten größer sind. Der unterer/oberer Whisker markiert die kleinste/größte Beobachtung des Datensatzes, der gerade noch innerhalb des 1,5fachen IQ ist. Mit dem optionalen Argument range kann dieser Wert angepasst werden. Ausreißer, die außerhalb dieses Bereichs liegen, werden durch Punkte dargestellt. Mit dem Argument horizontal = FALSE wird der Boxplot senkrecht dargestellt.

Zurück nach oben

Fußnoten

  1. Informationen, wie Sie sich per VPN mit den Netzen der Fachhochschule verbinden, finden Sie unter https://wiki.fh-muenster.de/dvz/anleitungen/doku.php?id=netzwerk:vpn_anyconnect:uebersicht↩︎

  2. Der Datensatz liegt streng genommen in der Environment des Pakets datasets. Da dieses Paket beim Start von R automatisch geladen wird, ist der Datensatz immer verfügbar.↩︎

  3. Die Anzahl, die durch breaks bestimmten Anzahl von Klassen entspricht nur ungefähr dem festgelegten Wert, da R bei der Berechnung der Klassengrenzen besonders runde Werte generiert und die gewünschte Klassenzahl daher nur näherungsweise einhalten kann.↩︎