Einführung in R

Als R wird sowohl die Programmiersprache für statistische Anwendungen als auch das kostenlose Software-System, das auf diese Sprache zurückgreift, bezeichnet. R wurde 1992 von Ross Ihaka und Robert Gentleman auf Basis der Programmiersprache S entwickelt. Gegenwärtig ist R für Windows-, macOs- und Linux-Distributionen verfügbar.

Im Folgenden wird ein kurzer Überblick über das Einrichten von R und den weit verbreiteten Editor RStudio auf dem eigenen Computer gegeben. Daran anschließend wird die R-Syntax und einige grundlegende Datentypen vorgestellt. Abschließend findet sich noch eine kurze Erläuterung zur Installation und Verwendung von packages, die R um weitere Funktionen ergänzen können.

Überblick

Sowohl die Installation als auch die Verwendung von R ist kostenlos. Da R ein GNU-Projekt (General Public Licence) ist, können seine Nutzer*innen zusätzlich eigene Erweiterungen erstellen oder Erweiterungen aus der R-Community frei nutzen. Parallel dazu wird die Grundstruktur von R durch das R (Development) Core Team beständig weiterentwickelt. Dies hat zur Folge, dass aktuelle Verfahren und Techniken der Statistik häufig zuerst in R umsetzbar sind.

R wird mit Programmiercode in einer Console bedient — anstatt z.B. durch Menüs zu klicken. Für Einsteiger*innen ohne Programmiererfahrung kann dieses Vorgehen abschreckend wirken. Einfache statistische Auswertungen können jedoch schon mit wenigen grundlegenden Funktionen durchgeführt werden. Zahlreiche (Online-)Publikationen erleichtern zudem auch komplexere Analysen.

Einstieg und technische Voraussetzungen

Um mit R auf einem Computer arbeiten zu können, wird eine R-Installation benötigt und eine integrierte Enwicklungsumgebung (IDEintegrated development environment) empfohlen.

Üblicherweise handelt es sich bei letzterem um das kostenlose und opensource RStudio, das von dem gleichnamigen Unternehmen vertrieben wird. (Es können aber auch Alternativen wie Jupyter notebook, Visual Studio, Vim und andere verwendet werden. In dieser Einführung beschränken wir uns jedoch darauf RStudio vorzustellen, da es das verbreitetste IDE für R ist.)

Durch das Installieren von R wird automatisch das Rgui (graphical user interface) mit eingerichtet. In dieser grafischen Benutzeroberfläche kann jeder R-Code eingegeben und ausgeführt werden. Es ist also möglich, alle statistischen Berechnungen mit R allein in dem Rgui durchzuführen.

Wir empfehlen dennoch ein IDE wie RStudio für Analysen mit R. Das Rgui soll lediglich das Arbeiten mit R durch eine grafische Oberfläche ermöglichen. Daneben bietet es kaum weitere Funktionen, die das Programmieren mit R vereinfachen und dadurch beschleunigen. RStudio bietet dagegen Features, die u. a. das Erkennen von Fehlern verbessern, Code-Vorschläge zugänglicher machen und die Übersicht über die Analyseschritte angenehmer gestalten (um hier nur eine ganz kleine Auswahl zu nennen). Aus diesem Grund wird in dieser Einführung hauptsächlich das Arbeiten mit RStudio gezeigt.

Um zu verstehen, wie R und RStudio miteinander interagieren, stellen wir uns vor, dass eine Nutzer*in eine statistische Berechnung mit R durchführen möchte:

technische_struktur1.png

Von Außen betrachtet muss sie dafür lediglich R-Code in einer Benutzeroberfläche (RStudio, Rgui,...) ausführen (I.). Nach der Berechnung des Codes wird ein Ergebnis dargestellt (II.).

In einem solchen Schema wird jedoch unterschlagen, dass in der Benutzoberfäche der Code nicht verarbeitet wird, sondern in dem Prozessor des Computers. Der Prozessor kann jedoch nur Binärcode (bestehend aus 0 und 1) lesen und erzeugen. Es braucht daher eine Instanz, die den R-Code in Binärcode umwandeln kann und umgekehrt. Diese Instanz ist der R-interpreter, der ein Teil der R-Installation ist.

technische_struktur2.png

Technisch stellt sich der Weg von der Eingabe zur Ausgabe stark vereinfacht wie folgt dar: Die Nutzer*in schreibt den R-Code in der Benutzeroberfläche (I.). Durch das Ausführen des Codes wird dieser an den R-interpreter geleitet (II.). Dort wird die Anweisung in Binärcode umgewandelt und an den Prozessor gesendet (III.). Hier wird schließlich das Ergebnis der Eingabe berechnet (z.B. eine Zahl, eine Grafik oder eine Fehlermeldung) und anschließend wieder an den R-interpreter in Binärcode übermittelt (IV.) Dieser wandelt den Code wieder um (V.), sodass er in der Benutzeroberfläche dargestellt werden kann (VI.).

Zusammenfassung: Für die Nutzung von R wird eine Benutzeroberfläche benötigt. Dabei muss es sich jedoch nicht RStudio handeln, sondern kann auch das Rgui, ein Terminal oder eine andere Entwicklungsumgebungen sein. Damit der R-Code ausgeführt werden kann, ist der R-interpreter zwingend erforderlich. Oder kurz: R funktioniert ohne RStudio, RStudio jedoch nicht ohne R. Aus diesem Grund empfehlen wir R zuerst zu installieren und dann RStudio.

Installation und Einrichtung von R/RStudio

R und RStudio können nur separat voneinander installiert werden. Im Folgenden wird zuerst die Installation von R und dann von RStudio gezeigt.

Die offizielle R-Installationsanleitung kann auf cran.r-project.org abgerufen werden. Ein Kurzeinführung für RStudio findet sich auf dem github-Profil von RStudio Education.

Download der R-Installationsdatei von r-project.org

R und seine Erweiterungen (sogenannte packages, s.u.) sind zum Download auf www.r-project.org — der Internetseite des Comprehensive R Archive Network (kurz: CRAN) — verfügbar.

Zur besseren Ausnutzung der Bandbreite und Serverlast werden Mirrors verwendet, von denen R und die packages heruntergeladen werden. Von der Liste der CRAN Mirrors muss zuerst ein passender Server ausgewählt werden. Dieser sollte möglichst nahe am eigenen Arbeitsplatz liegen. (Aus Bochum und der Umgebung bietet sich der Server der Universität Münster an.)

Nach der Serverauswahl können die benötigten Installationsdateien heruntergeladen werden.

Nachdem ein Mirror ausgewählt worden ist, kann die R-Installationsdatei heruntergeladen werden.

Hier ein Überblick zur Auswahl des passenden Mirrors:

Windows

Um am schnellsten zu der aktuellsten R-Version zu gelangen, kann die Adresse CRAN MIRROR/bin/windows/base/release.html verwendet werden: Wenn also der Mirror der Universität Münster benutzt wird, ist die Linkadresse https://cran.uni-muenster.de/bin/windows/base/release.html.

Alternativ zu diesem direkten Weg, ist auch eine Auswahl bestimmter Dateien über die CRAN-Webseite möglich — auf diese Weise können die Installationsanleitung, FAQ, ältere Versionen etc. eingesehen werden.

Das folgende Video zeigt den Download der R-Installationsdatei und die Installation von R auf einem Windows-Rechner. Klicke auf die PLUS-Buttons, wenn du zu einzelnen Schritten weitere Informationen erhalten möchtest:

macOS

Um die Installationsdatei für Mac-Betriebssysteme herunterladen zu können, muss die Option Download R for macOS ausgewählt werden.

Der Download des aktuellsten Installations-Package findet sich unter R-4.1.1.pkg (der Name ist versionsabgängig) für macOS 10.13 (High Sierra) oder jünger. R kann jedoch auch auf älteren macOS-Versionen eingerichtet werden (die Links zu den Download-Dateien finden sich ebenfalls auf der Seite).

Nach der Ausführung des Installations-Package muss den Read Me-Informationen und der Lizenzvereinbarung zugestimmt werden (evtl. wird noch nach dem Administrator-Passwort gefragt). Danach beginnt die Installation von R.

Wenn die Installation abgeschlossen ist, muss R zu den Programmen hinzugefügt werden und kann von dort ausgeführt werden.

Linux

Hinweis: Bei manchen Linux-Distributionen ist R bereits vorinstalliert.

Die korrekten Terminal-Befehle für die Installation von R unter Linux-Distributionen finden sich unter Download R for Linux (Debian, Fedora/Redhat, Ubuntu). Nachdem die eigene Linux-Distribution ausgewählt worden ist, können die jeweiligen Terminal-Befehle für die Installation eingesehen werden.

Nach dem Abschluss der Installation kann R mit dem Befehl


$ R

im Terminal gestartet werden.

Starten des Rgui

Klicke auf die PLUS-Buttons, wenn du zu einzelnen Schritten weitere Informationen erhalten möchtest:

Installation von RStudio

Klicke auf die PLUS-Buttons, wenn du zu einzelnen Schritten weitere Informationen erhalten möchtest:

Windows

MacOS

Die Download-Datei für macOS kann im Download-Bereich von rstudio.com unter macOS 10.14+ heruntergeladen werden

Die aktuellste Version von RStudio Desktop setzt macOS 10.13 (High Sierra) oder höher voraus. Für ältere Betriebssysteme können ältere Versionen von RStudio verwendet werden. Nach dem Download der Datei RStudio-2021.09.0-351.dmg (der Name ist versionsabhängig) muss diese installiert werden, evtl. muss dazu das eigene Passwort angegeben werden. Nach dem Beenden der Installation muss RStudio zu den Programmen hinzugefügt werden und kann von dort aus ausgeführt werden.

Linux

Bevor RStudio auf Rechnern mit Linux-Distributionen installiert werden kann, muss je nach Distribution der Public Key von RStudio validiert werden. Eine Anleitung dazu findet sich auf rstudio.com. Die aktuellsten Versionen von RStudio Desktop für Linux-Distributionen setzen ein 64-bit System voraus. Ältere Versionen können jedoch auch verwendet werden. Der Ablauf der Installation ist abhängig von der jeweiligen Distribution. RStudio wird wie andere Programme gestartet.

RStudio

Die Arbeit mit R kann nun komplett in RStudio erfolgen, R muss nicht separat gestartet werden.

In der folgenden Präsentation werden ein paar grundlegende Funktionen von RStudio gezeigt. Eine ausführliche Dokumentation findet sich auf rstudio.com.

Schnelleinstieg in RStudio

Arbeiten mit RStudio

R-Syntax

R ist eine Programmiersprache, die für Statistik-Anwendungen optimiert ist. Sie bringt viele grundlegende Statistikbefehle mit, sodass nicht jede Analyse völlig neu programmiert werden muss. Ihre Syntax legt fest, nach welchen Regeln ihre einzelnen Elemente verwendet werden dürfen.

Code schreiben

R-Code wird von oben nach unten und von links nach rechts ausgeführt — dabei gelten alle Rechenregeln (Punkt vor Strich, Klammern zuerst etc.). Zudem steht jede Eingabe immer in einer einzigen Zeile, außer sie wird durch ein Rechenzeichen am Ende der Zeile offen gehalten (durch eine offene Klammer, ein Plus, ein Divisionszeichen etc.).

Beispiel: Wir wollen folgende Rechnung in R durchführen: $$3+\frac{6}{10}+2$$ Wir können alle dafür benötigten Zeichen in eine einzige Zeile schreiben und erhalten das korrekte Ergebnis.

> 3 + 6 / 10 + 2
[1] 5.6

Es ist ebenfalls möglich, dass jede Zahl in einer einzelnen Zeile steht. Dann müssen die Zeilen am Ende durch ein Rechenzeichen offengehalten werden.

> 3 + 
    6 /
    10 + 
    2
[1] 5.6

Steht das Rechenzeichen am Anfang der Zeile, erhalten wir ein ungewolltes Ergebnis. (Für R ist die Codezeile abgeschlossen und + 2 somit wieder eine neue Codezeile.)

> 3 + 
   6 /
   10
   + 2
[1] 3.6
[1] 2

Case-Sensitivität

R ist case-sensitives wird zwischen Groß- und Kleinschreibung unterschieden! Z.B.: Mit der Eingabe Sys.time() kann die aktuelle Zeit angezeigt werden:

> Sys.time()
[1] "2021-07-14 11:10:29 CEST"

Wird stattdessen sys.time() (also ein kleines s) in den Code geschrieben, liefert die Console bei der Ausführung eine Fehlermeldung:

> sys.time()
Error in sys.time() : could not find function "sys.time"

Rechnen mit R

Rechenoperatoren

Rechenoperation können in R mit folgenden Zeichen durchgeführt werden:

RechenoperationZeichen
Addition+
Subtraktion -
Multiplikation *
Division/
Potenz^
Spektrum:
Quadratwurzelsqrt()
natürlicher Logarithmuslog()
Exponentexp()
Skalarprodukt%*%

Z.B.:

> 3 + 4
[1] 7
> 4^2 / 8
[1] 2
> 5 : 12
[1]  5  6  7  8  9 10 11 12
> exp(1)
[1] 2.718282

Logische Operatoren

Neben Rechenoperatoren können auch logische Operatoren verwendet werden:

Logischer OperatorZeichen
Gleich==
Ungleich!=
Nicht!
Größer als>
Kleiner als<
Größer gleich>=
Kleiner gleich<=
Und&
Oder|

Diese Operatoren können nur eines von zwei Ergebnissen erzielen — sie sind entweder wahr (TRUE) oder unwahr (FALSE):

Es ist wahr, dass 6 nicht 4 entspricht.

> 6 != 4
[1] TRUE

Es ist unwahr, dass 9 größer als 10 ist.

> 9 > 10
[1] FALSE

Es ist unwahr, dass sowohl 8 als auch 9 gleich 3 hoch 2 sind.

> 8 & 9 == 3^2
[1] FALSE

Es ist wahr, dass entweder 8 oder 9 3 hoch 2 entsprechen.

> 8 | 9 == 3^2
[1] TRUE

Kommentare

Es kann sinnvoll sein, den eigenen Code zu kommentieren, damit dieser zu einem späteren Zeitpunkt und/oder von Dritten nachvollzogen werden kann. Ein Kommentar beginnt immer nach einem "hash" (#). Alles was in der selben Zeile nach dem # folgt, wird von R nicht ausgeführt:

> 31 + 53 # Summe der Lehrer*innen in Schule A und B  
[1] 84
> sqrt(100) # * 3 
[1] 10

Objekte und Funktionen

Zentrale Konzepte bei der Programmierung in R sind Objekte und Funktionen — beide vereinfachen und beschleunigen Analysen in R erheblich. Alle Informationen, die im Laufe einer Berechnung verwendet werden, können in Objekten gespeichert werden. Funktionen erlauben es komplexe Auswertungen mit wenig Code durchzuführen.

Objekte

In Objekte werden Inhalte gespeichert, um sie für die weitere Analyse zu sichern. Die Inhalte des Objektes können sich in ihrer Art und Größe stark unterscheiden — sie können eine einzelne Zahl, ein Datensatz mit mehrere tausend Beobachtungen und Variablen, ein Text, ein Zeitspanne, eine Grafik etc. sein. Wollen wir auf diese Inhalte zurückgreifen, müssen wir lediglich das entsprechende Objekt in unserem Code ansprechen.

Objekte erstellen

Objekte werden immer auf diese gleiche Weise erstellt: Zuerst muss der Name des Objektes festgelegt werden. Dann wird ihm der gewünscht Inhalt zugewiesen (sprich in ihm gespeichert). Eine solche Zuweisung erfolgt immer nach dem selben Schema Name des Objektes <- Inhalt des Objektes.

Beispiel:

Wir wollen die Notenpunkte von drei Schüler*innen im Fach Mathematik miteinander vergleichen. Die erste Schüler*in hat 13 Punkte, die zweite 11 Punkte und die dritte 10 Punkte erzielt. Die "Objekte" sind in diesem Fall die einzelnen Schüler*innen und der Inhalt die jeweiligen Notepunkte:

> SchuelerIn_A <- 13 # erste Schüler*in
> SchuelerIn_B <- 11 # zweite Schüler*in
> SchuelerIn_C <- 10 # dritte Schüler*in

Objekte verwenden

Nachdem ein Objekt erstellt wurde, ist es im Workspace (dt. der Umgebung) der aktuellen R-Sitzung gespeichert. Auf die Objekte und ihren Inhalt kann nun wieder zurückgegriffen werden. Hinweis: In RStudio werden die erstellten Objekte in dem Environment-Reiter aufgelistet. Wenn der Name eines Objektes im Code angesprochen wird, wird immer Bezug auf seinen Inhalt genommen:

> SchuelerIn_A # Dem Objekt wurde der Inhalt 13 zugewiesen.
[1] 13
> SchuelerIn_B # Dem Objekt wurde der Inhalt 11 zugewiesen.
[1] 11
> SchuelerIn_C # Dem Objekt wurde der Inhalt 10 zugewiesen.
[1] 10

Objektnamen stehen somit auch in Rechnungen stellvertretend für ihren jeweiligen Inhalt.

> SchuelerIn_A - SchuelerIn_B # Differenz der Notenpunkte von Schüler\*in A und B
[1] 2
> SchuelerIn_B < SchuelerIn_C # Überprüfung ob Schüler\in B weniger Punkte erzielt hat als Schüler\*in C
[1] FALSE

Aus Objekten können wiederum neue Objekte erstellt werden:

# Durchschnittliche Punktzahl
> Durchschnitt_ABC <- (SchuelerIn_A + SchuelerIn_B + SchuelerIn_C) / 3
> Durchschnitt_ABC
[1] 11.33333

Benennen von Objekten

Damit es auch bei größeren Datenmengen nicht zu Verwechselungen kommt, ist es ratsam den Objekten sinnvolle Namen zu geben. In unserem Beispiel hätten wir das Objekt "SchuelerIn_A" auch einfach "A", "S1" oder "A_SchuelerIn" nennen können — theoretisch kann jede beliebige Zeichenkette als Objektname verwendet werden. Drei Regeln müssen bei der Benennung von Objekten jedoch beachtet werden:

  1. Der Objektname darf nicht mit einer Zahl beginnen.
> 1.Rechnung <- 7 + 9*(11 + 5)
Error: unexpected symbol in "1.Rechnung"
> Rechnung_1 <- 7 + 9*(11 + 5)
> Rechnung_1
[1] 151
  1. Der Objektname darf keinen der bereits gezeigten Operatoren enthalten. (Das gilt ebenfalls für Kommata und Leerzeichen)
> Apfel+Birne <- 30 + 12
Error in Apfel + Birne <- 30 + 12 : object 'Apfel' not found
> Apfel Birne <- 30 + 12
Error: unexpected symbol in "Apfel Birne"
> Apfel,Birne <- 30 + 12
Error: unexpected ',' in "Apfel,"
> ApfelBirne <- 30 + 12
> ApfelBirne
[1] 42
  1. Es wird zwischen Groß- und Kleinschreibung unterschieden (siehe case-Sensivität)
> klein <- 1^3
> Klein
Error: object 'Klein' not found
> klein
[1] 1

Zusätzlich muss berücksichtigt werden, dass ein Objekt überschrieben werden kann. Es sollte derselbe Name also nicht mehrfach vergeben werden:

> Objekt1 <- 25
> Objekt1 <- 5
> Objekt1
[1] 5

Diesen Umstand können wir uns aber auch zunutze machen. Hier wollen wir einen Geldbetrag von Cent in Euro umwandeln:

> Taschengeld <- 2000
> Taschengeld
[1] 2000
> Taschengeld <- Taschengeld/100
> Taschengeld
[1] 20

Funktionen

Es wurde bereits gezeigt, dass R mit Hilfe von Operatoren wie ein Taschenrechner verwendet werden kann. In den meisten Fällen werden Statistikprogramme für viel komplexere Aufgaben benötigt. Deren Bearbeitung wird durch Funktionen vereinfacht. Funktionen haben immer denselben Aufbau:

<Name der Funktion>(<Argument_1>,<Argument_2>,...,<Argument_n>)

Die Argumente einer Funktion sind ihr Input, das aus ihm ermittelte Ergebnis ihr Output. Der Output ist nicht zwangsläufig eine Zahl, sondern könnte z.B. auch eine Grafik oder ein Wort sein.

Ein paar Funktionen wurden bereits verwendet, ohne sie weiter zu erklären. Schauen wir uns die sqrt() Funktion näher an, mit der Quadratwurzeln berechnet werden können — ihr Input ist der Radikand (eine Zahl ≥ 0) und der Output ihre (positive) Wurzel:

> sqrt(100)
[1] 10
> sqrt(16)
[1] 4
> sqrt(-16)
[1] NaN
Warning message:
In sqrt(-16) : NaNs produced

Ein Großteil aller Funktionen in R verfügt über weiteren Argumente mit deren Hilfe ihr Output spezifiziert werden kann. Ein simples Beispiel dafür ist die round() Funktion mit der Zahlen gerundet werden können. Standardmäßig wird der Input ganzzahlig gerundet:

> round(10/3)
[1] 3

Die Funktion verfügt allerdings über ein weiteres Argument digits =, mit dem die Anzahl der Nachkommastellen manipuliert werden kann:

> round(10/3, digits = 1) # Eine Nachkommastelle
[1] 3.3
> round(10/3, digits = 2) # Zwei Nachkommastellen
[1] 3.33
> round(10/3, digits = 5) # Fünf Nachkommastellen
[1] 3.33333

Häufig werden die Namen der Argumente selbst nicht in die Funktion aufgenommen. Um Verwirrung und Fehler zu vermeiden, raten wir gerade am Anfang davon ab:

> round(10/3, 1) # Eine Nachkommastelle
[1] 3.3
> round(10/3, 2) # Zwei Nachkommastellen
[1] 3.33
> round(10/3, 5) # Fünf Nachkommastellen
[1] 3.33333

Ja, das Erstellen eigener Funktionen kann das Arbeiten in R erheblich vereinfachen (vor allem bei Operationen die mehrmals durchgeführt werden sollen). Einsteiger*innen mag das Schreiben eigener Funktionen anfangs etwas abschrecken. Aus diesem Grund zeigen wir hier die Möglichkeit die Umrechnungsfunktion der Notenpunkte als Funktion in R zu schreiben. (An dieser Stelle geht es nur darum zu zeigen, was mit der R-Syntax prinzipiell möglich ist. Wie genau die Funktion geschrieben wird, muss nicht nachvollzogen werden.)

Unsere Funktion nennen wir Punkte_Note, ihren Input Note:

Punkte_Note <- function(Note){ # Der Name der Funktion wird mit "<-" zugewiesen.
  if (Note >= 13) {return("sehr gut")} 
  else if (Note >= 10 & Note <= 12) {return("gut")}
  else if (Note >= 7 & Note <= 9) {return("befriedigend")}
  else if (Note >= 4 & Note <= 6) {return("ausreichend")}
  else if (Note >= 1 & Note <= 3) {return("mangelhaft")}
  else
    return("ungenügend")
}

So kann sowohl den Objekten SchuelerIn_A, SchuelerIn_B und SchuelerIn_C als auch anderen Notenpunkten eine Zeugnisnote zugeordnet werden:

> Punkte_Note(SchuelerIn_A)
[1] "sehr gut"
> Punkte_Note(SchuelerIn_B)
[1] "gut"
> Punkte_Note(SchuelerIn_C)
[1] "gut"
> Punkte_Note(14)
[1] "sehr gut"
> Punkte_Note(9)
[1] "befriedigend"
> Punkte_Note(1)
[1] "mangelhaft"

Hinweis: Auch bei der Benennung von Funktionen muss zusätzlich beachtet werden, dass sie nicht nach integrierten Funktionen benannt werden können (die Funktion sqrt() kann es nicht zweimal geben).

Datentypen in R

Es wurde schon angedeutet, dass sehr verschiedenartige Informationen in R als Daten verwendet werden können. Die Art der Daten — der sogenannte Datentyp — gibt Auskunft über das Format ihrer Information (handelt es sich um eine Zahl, eine Zeichenkette, eine Funktion, eine Grafik...?) und über die Operationen die auf diese angewendet werden können (ist es möglich die Information zu dividieren oder in einem Balkendiagramm darzustellen oder als Überschrift für eine Tabelle zu verwenden...?).

Wird eine falsche Operation mit einer Information durchgeführt, erzeugt dies entweder unerwünschte Ergebnisse oder eine Fehlermeldung in der R-Console. Es ist daher wichtig, einige grundlegende Datentypen in R zu kennen! Dies ermöglicht es, Fehler zu verhindern und Fehlermeldungen richtig zu interpretieren.

Einschub: Alles ist ein Objekt — jedes Objekt hat einen Inhalt und repräsentiert einen Datentyp!

Sämtliche Berechnungen werden in R mithilfe von Objekten durchgeführt, da in ihnen die dafür notwendigen Informationen gespeichert sind. (Ausgenommen sind hier nur die Rechen- und logischen Operatoren, die keine Funktionen sind.) Für die Arbeitsweise von R ist es unerheblich, ob in einer Codezeile ein selbst erstelltes Objekt wie SchuelerIn_A oder eine 1 verwendet wird — beides sind Objekte.

Jedes Objekt repräsentiert immer einen Datentyp. Dieser ist abhängig vom Inhalt des Objektes, z.B. ist 13 immer eine Zahl und true immer ein Wahrheitswert!

Name des ObjektesInhaltDatentyp
SchuelerIn_A13Zahl
11Zahl
truetrueboolescher Wert

Der Datentyp legt fest, welche Operationen mit dem Objekt durchgeführt werden können. Zahlen können z.B. miteinander addiert werden, Wörter hingegen nicht:

> SchuelerIn_A + 1 
[1] 14
> "Die erste Schüler_in hat die Note" + "sehr gut."
Error in "Die erste Schüler_in hat die Note" + "sehr gut." : 
  non-numeric argument for binary operator

Der Datentyp ist nicht nur für die Verwendung von Rechenoperatoren wichtig, sondern auch für Funktionen. Funktionen können nur auf bestimmte Datentypen angewandt werden:

# Nur Zahlen können mit round() gerundet werden.
> round(5/4)
[1] 1
> round("hello")
Error in round("hello") : non-numeric argument to mathematical function
# Nur Zeichenketten können mit strsplit() aufgeteilt werden.
> strsplit("hello", split = "")
[[1]]
[1] "h" "e" "l" "l" "o"
> strsplit(5/4, split = "")
Error in strsplit(5/4, split = "") : non-character argument

Wie kann ich den Datentyp eines Objektes ermitteln?

Es gibt in R mehrere Funktionen, um den Datentyp eines Objektes zu bestimmen. Alle verwenden leider minimal unterschiedliche Namen oder Einteilungen.

Funktion
Datentypmode()typeof()class()
Ganze Zahlnumericintegerinteger
Dezimalzahlnumericdoublenumeric
Zeichenkettencharactercharactercharacter
logischlogicallogicallogical
Listelistlistlist
Funktionfunctionclosurefunction

Im Folgenden verwenden wir die mode() und typeof() Funktion, um den Datentyp eines Objektes zu bestimmen. Oft wird der Begriff Datentyp synonym zu Klasse verwendet. In der Tabelle ist bereits erkennbar, dass hier eine große inhaltliche Schnittmenge herrscht. Um Verwirrung zu vermeiden, werden wir weiterhin nur von Datentypen sprechen.

numeric (Zahlen)

Zahlen haben den Datentyp numeric.

> mode(SchuelerIn_A) # Das Objekt "SchuelerIn_A" hat den Inhalt 13, also ein Zahl.
[1] "numeric"
> mode(23.5) # Bei 23.5 handelt es sich um eine Zahl. 
[1] "numeric"
> mode(pi) # "pi" ist die Kreiszahl und somit ebenfalls eine Zahl.
[1] "numeric"

double (Dezimalzahlen)

Numerics können sowohl integer (ganze Zahlen) als auch double (Dezimalzahlen) sein. Integer sind Zahlen, die ohne Nachkommastellen gespeichert werden, während double immer mit Nachkommastellen gespeichert werden:

> typeof(SchuelerIn_A)
[1] "double"
> typeof(23.5)
[1] "double"
> typeof(pi)
[1] "double"

integer (ganze Zahlen)

Diese Ausgabe ist auf den ersten Blick verwirrend, da SchuelerIn_A die Zahl 13 zugewiesen wurde und somit ein integer sein müsste. Technisch speichert R die 13 als 13.0. Damit eine Zahl jedoch von R als ganze Zahl behandelt wird, muss hinter ihr ein L stehen:

> typeof(13L)
[1] "integer"
> SchuelerIn_X <- 9L
> typeof(SchuelerIn_X)
[1] "integer"

Hinweis: Die Nachkommastellen einer Dezimalzahl wird immer durch einen Punkt . und nicht durch eine Komma , getrennt.

Character (Zeichenketten)

Character sind Zeichenketten (also meist Wörter), die in Anführungszeichen " " geschrieben werden müssen. Stehen Zeichenketten ohne Anführungszeichen in der R-Syntax, werden Zahlen als numeric und andere Zeichenketten als Objekte behandelt:

> SchuelerIn_Z <- "ausreichend"
> mode(SchuelerIn_Z)
[1] "character"
> mode(11)
[1] "numeric"
> mode("11")
[1] "character"
> mode(SchuelerIn_A)
[1] "numeric"
> mode("SchuelerIn_A")
[1] "character"

Der Output der typeof() Funktion ist identisch zu dem der mode() Funktion.

> typeof(SchuelerIn_Z)
[1] "character"
> typeof(11)
[1] "double"
> typeof("11")
[1] "character"
> typeof(SchuelerIn_A)
[1] "double"
> typeof("SchuelerIn_A")
[1] "character"

logical (logische Datentypen)

TRUE/FALSE (boolsche Variablen)

Die sogenannten booleschen Variablen (benannt nach dem Mathematiker George Boole) TRUE und FALSE sind das Ergebnis von logischen Vergleichsoperatoren (s.o.).

Boolesche Variablen können ebenfalls als Inhalte eines Objektes gespeichert werden. Z.B. speichern wir die Information, dass eine Lehrer*in ein naturwissenschaftliches Fach unterrichtet als TRUE und die gegenteilige Information als FALSE.

> LehrerIn_A <- TRUE
> LehrerIn_B <- FALSE
> LehrerIn_C <- TRUE
> LehrerIn_D <- FALSE

> LehrerIn_A == LehrerIn_C
[1] TRUE
> LehrerIn_A == LehrerIn_D
[1] FALSE
> LehrerIn_B < LehrerIn_A # TRUE ist immer größer als FALSE.
[1] TRUE

Der Datentyp boolescher Variablen ist logical:

> mode(LehrerIn_A)
[1] "logical"
> typeof(LehrerIn_A)
[1] "logical"

NA (Fehlende Werte)

Fehlende Werte sind in R ebenfalls ein Teil des Datentyps logical. Sie werden durch den Ausdruck NA ("not available") repräsentiert. Auch wenn die Ausprägung eines fehlenden Wertes unbekannt ist, kann sie dennoch der Inhalt eines Objektes sein.

> mode(NA)
[1] "logical"
> typeof(NA)
[1] "logical"

Um dies zu verdeutlichen, stellen wir uns vor, dass neben den Notenpunkten der Schüler*innen A bis C (13, 11 und 10) auch die Notenpunkte einer vierten Schüler*in Y erhoben worden sind. Schüler*in Y hat zwar an der Evaluation teilgenommen, jedoch wurde für ihre Note kein gültiger Wert erhoben. Dies könnte mehrere Gründe haben:

  • Sie hat die Angabe verweigert.

  • Sie erinnerte sich nicht mehr an ihre Note.

  • etc.

In diesem Fall wird dem Objekt SchuelerIn_Y der Wert NA zugewiesen:

> SchuelerIn_Y <- NA

Nun wollen wir die durchschnittliche Punktezahl der vier Schüler*innen (A, B, C und Y) ermitteln. Dafür werden alle Notenpunkte aufsummiert und durch die Anzahl der Schüler*innen dividiert:

> (SchuelerIn_A + SchuelerIn_B + SchuelerIn_C + SchuelerIn_Y) / 4
[1] NA

Da die Notenpunkte der Schüler*in Y unbekannt ist, könnten die Durchschnittsnotenpunkte eine beliebige Größe haben. Das Ergebnis der Rechnung ist also wiederum NA. (In diesem Beispiel könnten wir selbst eine Entscheidung darüber treffen, wie mit den Notenpunkten von Schüler*in Y umgegangen werden soll: Schließen wir sie aus der Berechnung aus?, Setzen wir für ihre Punktezahl einen konkreten Wert ein?, Rechnen wir mit einem Korrekturfaktor?...)

Um zu ermitteln, ob ein Objekt fehlende Werte beinhaltet, kann die Funktion is.na() genutzt werden:

> is.na(SchuelerIn_A)
[1] FALSE
> is.na(SchuelerIn_B)
[1] FALSE
> is.na(SchuelerIn_C)
[1] FALSE
> is.na(SchuelerIn_Y)
[1] TRUE

Viele Funktionen können mit einer Erweiterung definieren, wie mit fehlenden Werten umgegangen werden soll. Die Funktion min() berechnet den kleinsten Wert aus mehreren Argumenten. Wird der Erweiterung na.rm = der Wert TRUE zugeordnet, so werden fehlende Werte ignoriert:

> min(SchuelerIn_A, SchuelerIn_B, SchuelerIn_C, SchuelerIn_Y)
[1] NA
> min(SchuelerIn_A, SchuelerIn_B, SchuelerIn_C, SchuelerIn_Y, na.rm = TRUE)
[1] 10

Vektoren (Sequenzen mit Datenelementen)

Vektoren in R sind Sequenzen, die Datenelemente umfassen. Es wird zwischen atomic vectors, lists und factors unterschieden.

atomic vector (Sequenzen mit gleichartigen Datenelementen)

Ein atomic vector ist eine Sequenz, die gleichartige Datenelemente umfasst — alle Elemente haben also denselben Datentyp (z.B. ausschließlich double oder ausschließlich character).

Wir könnten uns vorstellen, dass wir die Notenpunkte der Schüler*innen A bis C in einer gemeinsamen Gruppe (Gruppe_1) zusammenfassen. Diese Objekten bilden dann einen Vektor. In R erlaubt es die Funktion c() einen atomic vector zu erzeugen. Die einzelnen Vektorelemente müssen dabei durch Kommata separiert werden:

> Gruppe_1 <- c(SchuelerIn_A, SchuelerIn_B, SchuelerIn_C)
> Gruppe_1
[1] 13 11 10
> mode(Gruppe_1)
[1] "numeric"
> typeof(Gruppe_1)
[1] "double"

Der Vektor Gruppe_1 umfasst nur Elemente mit dem Datentyp double, die Note der Schüler*in Z ist hingegen als character gespeichert worden. Wenn diese unterschiedlichen Datentypen in einem atomic vector zusammengefasst werden, speichert R alle Vektorelemente als gleichen Datentyp (in diesem Fall character):

> Gruppe_1_Z <- c(SchuelerIn_A, SchuelerIn_B, SchuelerIn_C, SchuelerIn_Z)
> Gruppe_1_Z
[1] "13"          "11"          "10"          "ausreichend"
> mode(Gruppe_1_Z)
[1] "character"

Jedes Vektorelement besitzt einen Index. Dieser beschreibt die Position des Elements im Vektor. SchuelerIn_B mit der Information 11 steht an der zweiten Position in dem Vektor Gruppe_1 und hat daher den Index 2. Der Index eines Vektorelements wird mit Vektorname[Index] angesprochen:

> Gruppe_1[2]
[1] 11

Mit Vektoren können verschiedene Berechnungen vereinfacht werden:

> Gruppe_1 + 2 # Jedes Element eines Vektors wird mit einer Zahl addiert.
[1] 15 13 12

> Gruppe_1 / 3 # Jedes Element eines Vektors wird durch eine Zahl dividiert.
[1] 4.333333 3.666667 3.333333

> sum(Gruppe_1) # Die Funktion sum() erstellt die Summe von Objekten.
[1] 34

> SchuelerIn_A # Berechnungen mit einem Vektor verändern nicht die Objekte, die er umfasst.
[1] 13

Die Datenstruktur eines Vektors kann mit der Funktion str() ausgegeben werden:

> str(Gruppe_1)
 num [1:3] 13 11 10

Ein Vektor kann mit der Funktion sort() sortiert werden — standardmäßig von der kleinsten zur größten Ausprägung:

> sort(Gruppe_1)
[1] 10 11 13

# Atomic vectors, die aus characters bestehen, werden alphabetisch sortiert (dabei sind Zahlen "kleiner" als Buchstaben):

> sort(Gruppe_1_Z)
[1] "10"          "11"          "13"          "ausreichend"

list (Sequenzen mit verschiedenartigen Datenelementen)

Im Gegensatz zu atomic vectors können lists auch Elemente mit verschiedenen Datentypen umfassen — also sowohl double und character, als auch andere wie atomic vectors, logicals, lists etc.

Lists werden in R mit der Funktion list() erzeugt. Auf diese Weise könnten wir eine Gruppe (Gruppe_2) mit den Schüler*innen A bis C und Schüler*in Z erstellen:

> Gruppe_2 <- list(SchuelerIn_A, SchuelerIn_B, SchuelerIn_C, SchuelerIn_Z)
> Gruppe_2
[[1]]
[1] 13

[[2]]
[1] 11

[[3]]
[1] 10

[[4]]
[1] "ausreichend"

> mode(Gruppe_2)
[1] "list"

> typeof(Gruppe_2)
[1] "list"

> str(Gruppe_2)
List of 4
 $ : num 13
 $ : num 11
 $ : num 10
 $ : chr "ausreichend"

Wie atomic vectors besitzen lists einen Index mit dem die einzelnen Elemente angesprochen werden können:

> Gruppe_2[3]
[[1]]
[1] 10

Allerdings kann mit lists nicht wie mit atomic vectors gerechnet werden:

> Gruppe_2 + 2
Error in Gruppe_2 + 2 : non-numeric argument to binary operator

> Gruppe_2 / 3
Error in Gruppe_2/3 : non-numeric argument to binary operator

> sum(Gruppe_2)
Error in sum(Gruppe_2) : invalid 'type' (list) of argument

> sort(Gruppe_2)
Error in sort.int(x, na.last = na.last, decreasing = decreasing, ...) : 
  'x' muss atomar sein

factor (gruppierte Vektoren)

Ein factor ist ein Vektor mit kategorialen Variablen. Das bedeutet, dass die Vektorelemente in eine logische Reihenfolge gebracht werden können. Ein Beispiel für eine kategoriale Variable sind die Monate eines Jahres; logischerweise beginnt ein Jahr im Januar und endet im Dezember.

Angenommen, wir kennen den Geburtsmonat von sechs verschiedenen Schüler*innen und speichern diese Information in einem atomic vector ("Geburtstage"):

SchuelerIn_D <- "Mai"
SchuelerIn_E <- "August"
SchuelerIn_F <- "Juli"
SchuelerIn_G <- "Mai"
SchuelerIn_H <- "September"
SchuelerIn_I <- "Februar"

Geburtstage <- c(SchuelerIn_D, SchuelerIn_E,
                 SchuelerIn_F, SchuelerIn_G,
                 SchuelerIn_G, SchuelerIn_I)

mode(Geburtstage)
[1] "character"

Wird die sort() Funktion auf den Vektor angewendet, werden die Informationen der Vektorelemente alphabetisch sortiert:

> sort(Geburtstage)
[1] "August"    "Februar"   "Juli"      "Mai"       "Mai"      
[6] "September"

Die Monate ihrer Reihefolge im Jahr nach zu sortieren, funktioniert nicht mit einem atomic vector und der sort() Funktion. Um dies zu erreichen, muss ein factor erstellt werden ("Geburtstage_factor"). Ein factor besteht immer aus einem Vektor und dessen levels, also den sortierten möglichen Merkmalsausprägungen des Vektors. Der Vektor, der in diesem Beispiel verwendet wird, ist Geburtstage. Die levels des factors sind die Monate des Jahres. Diese werden ebenfalls als ein atomic vector in dem Objekt Monate gespeichert:

# Erstellung der levels des factors. Diese sind die Monate des Jahres.

Monate <- c(
  "Januar", "Februar", "März",
  "April", "Mai", "Juni",
  "Juli", "August", "September",
  "Oktober", "November", "Dezember"
)

# Erzeugen des factors. Der Vektor sind die Geburtstage der Schüler\*innen und seine levels die Monate des Jahres.

> Geburtstage_factor <- factor(Geburtstage, levels = Monate)

# Die Reihenfolge der Elemente des Vektors bleibt erhalten, jedoch kennt R nun ihre levels.

> Geburtstage_factor
[1] Mai       August    Juli      Mai       September Februar  
12 Levels: Januar Februar März April Mai Juni Juli ... Dezember

# Die sort() Funktion kann die Monate in die korrekte Reihenfolge bringen.

> sort(Geburtstage_factor)
[1] Februar   Mai       Mai       Juli      August    September
12 Levels: Januar Februar März April Mai Juni Juli ... Dezember

# Der Datentyp des factors ist "integer". Für R sind nicht die Namen der levels relevant, sondern ihr Rang:
# "Januar" = 1, "Februar" = 2, ... , "Dezember" = 12

> typeof(Geburtstage_factor)
[1] "integer"

# Dies wird besonders deutlich, wenn die Struktur des factors betrachtet wird.
# Er verfügt über 12 Levels. Das erste Element des factors (SchuelerIn_D) hat das level 5 (also "Mai"),
# das zweite Element (SchuelerIn_E) hat das level 8 ("August"), usw.

> str(Geburtstage_factor)
 Factor w/ 12 levels "Januar","Februar",..: 5 8 7 5 9 2

Index eines Vektors

Jedes Vektorelement hat eine Position innerhalb des Vektors — der sogenannte Index. Dieser kann genutzt werden, um auf bestimmte Elemente zuzugreifen. Ein Vektor steht immer in eckigen Klammer [] hinter den angeordneten Elementen:

> c(1,8,4,2)[2] # Gibt das zweite Element des Vektor wieder.
[1] 8

> c(1,8,4,2)[-2] # Hat als Ergebnis alle Vektorelemente außer dem zweiten.
[1] 1 4 2

> c(1,8,4,2)[c(1,3)] # Sollen mehrere Elemente eines Vektor angesprochen werden, müssen diese im Index selbst in einem Vektor stehen.
[1] 1 4

> c(1,8,4,2)[1:3] # Im Index kann auch eine Spanneweite stehen. Diese schließt sowohl deren Anfang (erstes Element) als auch ihr Ende (drittes Element) ein.
[1] 1 8 4

Anhand der Beispiele können wir sehen, dass das erste Element eines Vektors immer den Index 1 hat. Das letzte Element eines Vektors entspricht immer der Länge des Vektors:

> length(c(1,8,4,2)) # Mit der length Function kann die Länge eines Vektors ermittelt werden.
[1] 4

> c(1,8,4,2)[length(c(1,8,4,2))] # Gibt das letzte Element des Vektor wieder. Dies ist besonders hilfreich bei Vektroren, die in einem Objekt gespeichert sind. 
[1] 2

> c(1,8,4,2)[5] # Es gibt kein fünftes Element, daher kann ist das Ergebnis ein fehlender Wert.
[1] NA

> c(1,8,4,2)[0] # Ein Vektor hat kein "nulltes" Element. Daher ist das Ergebnis eine Zahl der Länge 0.
numeric(0)

Als Beispiel wollen wir wissen, welche Notepunkte die zweite Schüler*in von Gruppe_1 bekommen hat:

> Gruppe_1[2]
[1] 11

data.frame (Datensätze)

Aufbau

In einem Datensatz werden Informationen von mehreren Untersuchungseinheiten (z.B. Schulklassen) tabellarisch organisiert. Datensätze können in R als data.frames gespeichert werden.

Jede Spalte eines data.frame ist ein gleichlanger atomic vector, der die Ausprägungen eines Merkmals für alle Untersuchungseinheiten umfasst (z.B. die Anzahl der Schüler*innen von verschiedenen Schulklassen). Jede Zeile eines data.frame ist eine gleichlange list, in der die Ausprägungen aller Merkmale für eine Untersuchungseinheit stehen (z.B. alle Merkmalsausprägungen der Klasse 9a).

Als Beispiel wollen wir die folgende Tabelle als data.frame erzeugen, die Informationen von fünf Schulklassen (9a, 9b, 9c, 9d, 9e) enthält:

KlasseAnzahl_SchuelerInnen KlassensprecherInBilingual
9a21SchuelerIn5Nein
9b18SchuelerIn4Ja
9c20SchuelerIn2Unbekannt
9d21SchuelerIn3Nein
9e28SchuelerIn1Ja

Der data.frame besteht aus vier atomic vectors (Klasse, Anzahl_SchuelerInnen, KlassensprecherIn und Bilingual) und fünf lists (die Merkmalsausprägungen der jeweiligen Klasse):

# Die Elemente der Vektoren müssen in der korrekten Reihenfolge angeordnet sein.

Klasse <-  c("9a", "9b", "9c", "9d", "9e")

Anzahl_SchuelerInnen <- c(21, 18, 20, 21, 28)

# Die Elemente des Vektors "KlassensprecherIn" sind characters!

KlassensprecherIn <- c("SchuelerIn5", "SchuelerIn4", "SchuelerIn2", "SchuelerIn3", "SchuelerIn1")

# Für das Merkmal "Bilingual" bietet es sich an, einen Vektor vom Datentyp logical zu erstellen.

Bilingual <- c(FALSE, TRUE, NA, FALSE, TRUE)

Mit der Funktion data.frame() können atomic vectors zu einem einzigen Datensatz zusammengefasst werden (hier "Schulklassen").

Schulklassen <- data.frame(Klasse,
                          Anzahl_SchuelerInnen,
                          KlassensprecherIn,
                          Bilingual
                          )

> Schulklassen
  Klasse Anzahl_SchuelerInnen KlassensprecherIn Bilingual
1     9a                   21       SchuelerIn5     FALSE
2     9b                   18       SchuelerIn4      TRUE
3     9c                   20       SchuelerIn2        NA
4     9d                   21       SchuelerIn3     FALSE
5     9e                   28       SchuelerIn1      TRUE

Wie bei Vektoren kann die Struktur eines data.frame mit der Funktion str() betrachtet werden:

> str(Schulklassen)
'data.frame':   5 obs. of  4 variables:
 $ Klasse              : chr  "9a" "9b" "9c" "9d" ...
 $ Anzahl_SchuelerInnen: num  21 18 20 21 28
 $ KlassensprecherIn   : chr  "SchuelerIn5" "SchuelerIn4" "SchuelerIn2" "SchuelerIn3" ...
 $ Bilingual           : logi  FALSE TRUE NA FALSE TRUE

Unserer Datensatz besteht aus fünf Beobachtungen (obs.) für jeweils vier verschiedene Variablen: zwei Variablen sind character (Klasse und KlassensprecherIn), eine ist numeric (Anzahl_SchuelerInnen) und eine logical (Bilingual).

Wie Vektoren, verfügen data.frames über einen Index. Dieser ist jedoch zweidimensional — es muss sowohl die Zeile als auch die Spalte angesprochen werden. Um dies zu gewährleisten, wird der Index [] durch ein Komma getrennt; [Zeilenindex,Spaltenindex]. Die erste Zahl im Index bezieht sich auf die Zeilen und die zweite auf die Spalten des data.frames:

# Wir wollen wissen, wie viele Schüler\*innen in Klasse 9c sind.

> Schulklassen[3, 2] # Die Daten der Klasse 9c befinden sich in der dritten Zeile. Die Anzahl der Schüler\*innen wird in der zweiten Spalte abgelesen.
[1] 20

# Es sollen nur die Daten der Klasse 9b ausgegeben werden.

> Schulklassen[2, ] # Die Daten der Klasse 9b befinden sich in der zweiten Zeile. Um alle Elemente einer Spalte auszuwählen, bleibt der Index leer.
  Klasse Anzahl_SchuelerInnen KlassensprecherIn Bilingual
2     9b                   18       SchuelerIn4      TRUE

# Es sollen die "Namen" der Klassensprecher\*innen von Klasse 9a und 9e ausgegeben werden.

> Schulklassen[c(1, 5), 3] # Um mehrere Elemente anzusprechen, werden diese in einem atomic vector geschrieben.
[1] "SchuelerIn5" "SchuelerIn1"

Data.frames können auf zwei Wegen modifiziert werden — entweder ihre Zeilen werden verändert oder ihre Spalten.

Jede Zeile eines data.frame umfasst die Merkmalsausprägungen einer Beobachtung in Form einer list. Als Beispiel soll der vorhandene Datensatz durch die Daten von zwei Schulklassen ergänzt werden. Dafür wird die Funktion rbind() genutzt, in der der data.frame und die lists, um die dieser ergänzt werden soll, angegeben werden müssen:

Schulklassen_Neu <- rbind(Schulklassen,
                          list("10a", 16, "SchuelerIn7", FALSE),
                          list("10b", 22, "SchuelerIn6", FALSE))

> Schulklassen_Neu
  Klasse Anzahl_SchuelerInnen KlassensprecherIn Bilingual
1     9a                   21       SchuelerIn5     FALSE
2     9b                   18       SchuelerIn4      TRUE
3     9c                   20       SchuelerIn2        NA
4     9d                   21       SchuelerIn3     FALSE
5     9e                   28       SchuelerIn1      TRUE
6    10a                   16       SchuelerIn7     FALSE
7    10b                   22       SchuelerIn6     FALSE

Achtung: In jeder list müssen Ausprägungen für alle Variablen angegeben werden:

# Hier fehlt die Ausprägung der Variable "Anzahl_SchuelerInnen".

> Schulklassen_Zeile_Fehler <- rbind(Schulklassen_Neu, list("10c", "SchuelerIn7", FALSE))

Error in xi[[j]] : subscript out of bounds

Wenn eine Zeile — und damit eine Beobachtung — gelöscht werden soll, muss diese mit einem negativen Vorzeichen im Index geschrieben werden:

# Löschen der dritten Zeile (Daten der Klasse 9c) des Datensatzes.

> Schulklassen_ohne_9c <- Schulklassen_Neu[-3, ]

> Schulklassen_ohne_9c
  Klasse Anzahl_SchuelerInnen KlassensprecherIn Bilingual
1     9a                   21       SchuelerIn5     FALSE
2     9b                   18       SchuelerIn4      TRUE
4     9d                   21       SchuelerIn3     FALSE
5     9e                   28       SchuelerIn1      TRUE
6    10a                   16       SchuelerIn7     FALSE
7    10b                   22       SchuelerIn6     FALSE

Jede Spalte eines data.frame umfasst die Merkmalsausprägungen einer Beobachtung in Form eines atomic vectors. Als Beispiel soll der vorhandene Datensatz mit dem Schulfach der jeweiligen Klassenlehrer*in ergänzt werden. Um dies zu erreichen, wird die Funktion cbind() genutzt. In dieser muss der data.frame und die atomic vectors stehen. Dem atomic vector muss zusätzlich ein Name gegeben werden mit Name = :

Schulklassen_Faecher <- cbind(Schulklassen_Neu, Faecher = c(
  "Mathe",
  "Deutsch",
  "Erdkunde",
  "Chemie",
  "Englisch",
  "Mathe",
  "Biologie"))

> Schulklassen_Faecher
  Klasse Anzahl_SchuelerInnen KlassensprecherIn Bilingual  Faecher
1     9a                   21       SchuelerIn5     FALSE    Mathe
2     9b                   18       SchuelerIn4      TRUE  Deutsch
3     9c                   20       SchuelerIn2        NA Erdkunde
4     9d                   21       SchuelerIn3     FALSE   Chemie
5     9e                   28       SchuelerIn1      TRUE Englisch
6    10a                   16       SchuelerIn7     FALSE    Mathe
7    10b                   22       SchuelerIn6     FALSE Biologie

Achtung: In jedem atomic vector müssen die Ausprägungen aller Untersuchungseinheiten angegeben werden:

# Hier werden nur sechs Ausprägung aufgelistet, obwohl unser Datensatz sieben Beobachtungen umfasst.

> Schulklassen_Spalte_Fehler <- cbind(Schulklassen_Neu, Durchschnittsnote = c(
  1.8,
  2.7,
  1.9,
  3.3,
  2.0,
  2.1))

Error in data.frame(..., check.names = FALSE) : 
  Argumente implizieren unterschiedliche Anzahl Zeilen: 7, 6

Wenn eine Spalte gelöscht werden soll, muss diese mit einem negativen Vorzeichen im Index geschrieben werden:

# Löschen der vierte Spalte des Datensatzes (Information, ob die Klasse bilingual unterrichtet wird).

> Schulklassen_ohne_Bilingual <- Schulklassen_Faecher[, -4]

> Schulklassen_ohne_Bilingual
  Klasse Anzahl_SchuelerInnen KlassensprecherIn  Faecher
1     9a                   21       SchuelerIn5    Mathe
2     9b                   18       SchuelerIn4  Deutsch
3     9c                   20       SchuelerIn2 Erdkunde
4     9d                   21       SchuelerIn3   Chemie
5     9e                   28       SchuelerIn1 Englisch
6    10a                   16       SchuelerIn7    Mathe
7    10b                   22       SchuelerIn6 Biologie

Weitere

Packages

R bietet seinen Nutzer*innen die Möglichkeit Funktionen zu nutzen, die nicht standardmäßig in R enthalten sind. Diese zusätzlichen Funktionen sind in nutzer*innengeschrieben Paketen enthalten und können von den CRAN Mirrors heruntergeladen werden.

Installation

Als Beispiel wird das Paket tidyverse installiert, das mehrere Pakete zur Analyse von Datensätzen umfasst. Ein neues Paket wird mit der Funktion install.packages() installiert, dabei muss Paket als character (also mit Anführungszeichen) angesprochen werden:

>install.packages("tidyverse")
Installing package into ‘D:/R/win-library/4.0’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.0/tidyverse_1.3.0.zip'
Content type 'application/zip' length 440077 bytes (429 KB)
downloaded 429 KB

package ‘tidyverse’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\AppData\Local\Temp\RtmpGiqR39\downloaded_packages

Das Paket ist nun erfolgreich auf dem eigenen Rechner installiert und seine integrierten Funktionen können in R verwendet werden. Um Funktionen eines Paketes nutzen zu können, muss dieses mit library() als Objekt geladen werden:

> library(tidyverse)

-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
v ggplot2 3.3.2     v purrr   0.3.4
v tibble  3.0.3     v dplyr   1.0.2
v tidyr   1.1.2     v stringr 1.4.0
v readr   1.3.1     v forcats 0.5.0

Hinweis: Pakete müssen bei jeder neuen R-Sitzung neu geladen werden (jedoch nicht installiert)!

Jetzt können Funktionen aus dem Paket tidyverse genutzt werden. Als Beispiel können nun mit drop_na() alle Zeilen eines Datensatzes gelöscht werden, in denen sich fehlende Werte befinden:

> drop_na(Schulklassen_Faecher, Bilingual)
  Klasse Anzahl_SchuelerInnen KlassensprecherIn Bilingual  Faecher
1     9a                   21       SchuelerIn5     FALSE    Mathe
2     9b                   18       SchuelerIn4      TRUE  Deutsch
3     9d                   21       SchuelerIn3     FALSE   Chemie
4     9e                   28       SchuelerIn1      TRUE Englisch
5    10a                   16       SchuelerIn7     FALSE    Mathe
6    10b                   22       SchuelerIn6     FALSE Biologie

# Der Wert der Klasse 9c für die Variable "Bilingual" war ein fehlender Wert, daher wurde die Zeile gelöscht.

Hilfe

Egal ob Einsteiger*in oder jahrelanger Profi, es ist völlig normal bei der Arbeit mit R Fehlermeldungen zu produzieren oder bei manchen Anweisen nicht weiterzukommen. Da niemand alle R-Funktionen bzw. -packages kennen kann, ist es wichtig zu wissen, wie und wo Hilfe zu suchen ist.

Fehlermeldungen in R

Ungültige Anweisungen im Code erzeugen Fehler. Sobald der R-interpreter eine fehlerhafte Anweisung berechnet, wird ein Fehlermeldung in der R-Console angezeigt — der übrige Code wird dennoch ausgeführt.

> SchuelerIn_A + 1 
[1] 14
> "Die erste Schüler_in hat die Note" + "sehr gut."
Error in "Die erste Schüler_in hat die Note" + "sehr gut." : 
  non-numeric argument for binary operator
Creative Commons Lizenzvertrag

Dieses Werk ist lizenziert unter einer Creative Commons Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz.

Autor*innen dieses Artikels

Diese Seite wurde zuletzt am 10.10.2022 aktualisiert.