[1] "numeric"
[1] "numeric"
[1] "character"
[1] "logical"
[1] "list"
[1] "numeric"
[1] "numeric"
[1] "list"
In jeder Programmiersprache gibt es abstrakte Behälter, um verschiedene Arten von Daten zu repräsentieren und mit ihnen zu arbeiten. In klassischen 3GL-Programmiersprachen unterscheidet man fundamentale, zusammengesetzte und selbstdefinierte Datenstrukturen.
Fundamentale Datenstrukturen sind in der Programmiersprache vordefiniert. Typische Beispiele sind Behälter für logische Werte (TRUE
, FALSE
), ganze Zahlen (int8
), die z.B. die 256 Werte von -128 bis 127 repräsentieren, Gleitkommazahlen (single
, double
) mit unterschiedlicher Genauigkeit, Schriftzeichen (a
, b
), die oft in Anführungszeichen gesetzt werden. Mit diesen grundlegenden Datentypen sind typischerweise passende Operationen verknüpft, wie AND
/OR
für logische Werte, +
, -
für Ganzzahlen, +
, -
, *
und \
für Gleitkommazahlen und Konkatenation für Zeichen.
Zusammengesetzte Datenstrukturen sind ebenfalls vordefiniert und dienen dazu, mehrere Variablen gleichen Typs zusammenzufassen. Dazu zählen in R zum Beispiel Vektoren, Listen, Arrays, Matrizen und Dataframes, die in diesem Abschnitt behandelt werden. Auch für zusammengesetzte Strukturen existieren spezifische Operationen, wie die Vektorindizierung oder die Matrixmultiplikation.
Schließlich lassen sich in 3GL-Programmiersprachen auch selbstdefinierte Datenstrukturen erstellen. Sie ermöglichen die Anpassung der Programmumgebung an spezifische Anwendungsfälle und sind daher besonders praxisrelevant. In der Regel werden sie aus vordefinierten Strukturen zusammengesetzt und können im Rahmen objektorientierter Programmierung auch mit eigenen Operationen assoziiert sein.
Wenn man eine Programmiersprache erlernt ist ein erster fundamentaler Schritt, sich mit ihren Datenstrukturen zumindest rudimentär vertraut zu machen. Feinheiten in der Datenstrukturrepräsentation wird man dann in der täglichen praktischen Arbeit mit der Programmiersprache kennenlernen. Um sich mit den Datenstrukturen einer Programmiersprache vertraut zu machen bieten sich folgende Leitfragen an, denen wir in diesem Abschnitt folgen wollen:
Fundamentale Datenstrukturen
Zusammengesetzte Datenstrukturen
Selbstdefinierte Datenstrukturen
Als 4GL Sprache geht R in seiner Datenstruktur über die klassischen Datenstrukturen von 3GL Sprachen hinaus. In R ist zunächst erstmal alles ein Objekt. Egal, ob es sich um einen einzelnen Wert, einen Vektor, eine Funktion oder eine komplexe Datenstruktur handelt – alles wird von R als Objekt repräsentiert. Allgemein bezeichnet der Begriff des Objekts die Möglichkeit, in einer Sinneinheit sowohl Daten als auch Funktionalität zu repräsentieren. Wir sind hier allerding primär an der Datenrepräsentation interessiert. Jedes R Objekt lässt sich eindeutig beschreiben durch drei zentrale Eigenschaften: seinen Modus, seine Länge und optional durch weitere Attribute.
Der Modus eines Objekts gibt an, wie seine Komponenten strukturiert sind. Man unterscheidet dabei zwischen atomaren Objekten und rekursiven Objekten. Atomare Objekte bestehen aus Komponenten gleichen Datentyps. Typische Beispiele sind numerische Vektoren, logische Vektoren oder Zeichenketten. Rekursive Objekte hingegen können Komponenten unterschiedlichen Typs enthalten. Dazu gehören insbesondere Listen und Dataframes, die es erlauben, heterogene Daten zusammenzufassen.
Neben dem Modus besitzt jedes Objekt eine Länge, die angibt, wie viele Elemente es enthält. Bei einem Vektor ist die Länge zum Beispiel die Anzahl der enthaltenen Werte, bei einer Liste die Zahl ihrer Komponenten.
Darüber hinaus können Objekte in R mit zusätzlichen Attributen versehen sein. Attribute sind Metadaten, die zusätzliche Informationen über das Objekt bereitstellen, etwa Namen der Elemente (names
), Dimensionen (dim
) für Matrizen und Arrays oder Klasseninformationen (class
), die für das objektorientierte Programmieren in R relevant sind.
Modus, Typ und Klasse
Die Klassifizierung von Datenstrukturen ist etwas komplex, da nebeneinander die Begriffe des Modus, des Typs und der Klasse eines Objekts existieren. In der praktischen Anwendung sind die Feinheiten dieser Klassifizierung meist nicht von Belang, außerde sind der Modus, Typ, und die Klasse eines Objekts auch oft identisch,
Grob gesagt entspricht der Modus der grundlegenden Natur eines Objekts und ist inbesondere so gewählt, dass sich eine hohe Kompatibilität zum Datenstrukturklassifikationssystem von S (Becker et al. (1988)) besteht. Beispiele für Modi sind numeric
, character
logical
, oder list
. Der Modus eines Objektes kann mit der Funktion mode()
abgerufen werden, wie folgendes Beispiel zeigt.
[1] "numeric"
[1] "numeric"
[1] "character"
[1] "logical"
[1] "list"
[1] "numeric"
[1] "numeric"
[1] "list"
Etwas näher an der internen Repräsentation eines Objekts im Speicher und damit etwas technischerer Natur ist der Typ eines R Objekts. Dies wird insbesondere hinsichtlich Objekten von Modus numeric
deutlich. Hier gibt es die klassischen 3GL Typenunterscheidungen integer
oder double
. Ein anderes Beispiel ist der Modus Faktor. Wie wir an späterer Stelle sehen werden, sehen Faktoren in R für den Nutzer aus wie kategorische Daten, oft von Schriftzeichenart, ihr Modus ist allerdings numeric
und ihr Typ integer
. Dies hängt damit zusammen, dass Faktoren in R oft dazu genutzt werden auf der Benutzterebene experimentelle Bedingungen zu spezifizieren, die meist aussagekräftige Namen wie “Treamtent” oder “Kontrolle” haben, in der Datenanalyse aber durch mathematische Matrizen mit ganzzahligen Einträgen repräsentiert werden. Der Typ eines Objektes kann mit der Funktion typeof()
abgerufen werden, wie folgendes Beispiel zeigt. Man beachte die Gemeinsamkeiten und Unterschiede zu den oben aufgerufenen Modi der gleichen Objekte.
[1] "double"
[1] "integer"
[1] "character"
[1] "logical"
[1] "list"
[1] "integer"
[1] "double"
[1] "list"
Die Klasse eines Objektes schließlich spezifiziert die Art eines Objektes aus der Perspektive der objekt-orientierten Programmierung in R. Dabei ist es für ein Objekt insbesondere relevant, wie generische Funktionen wie z.B. print()
oder summary()
mit dem Objekt umgehen. Im Gegensatz zu Modi und Typen können Programmierende die Klasse von Objekten selbst festlegen und so generische Funktionen entwickeln, die auf viele Objektarten anwendbar sind und trotz ihres gleichen Namens mit unterschiedlichen Objekten unterschiedliche Operationen ausführen. Die Klasse eines Objektes kann mit der Funktion class()
abgerufen werden, wie folgendes Beispiel zeigt. Man beachte die Gemeinsamkeiten und Unterschiede zu den oben aufgerufenen Modi un d Typen der gleichen Objekte.
[1] "numeric"
[1] "integer"
[1] "character"
[1] "logical"
[1] "list"
[1] "factor"
[1] "Date"
[1] "lm"
Zusammengefasst lässt sich festhalten: Der Modus beschreibt die allgemeine Art eines Objekts, der Typ beschreibt seine interne, technische Speicherung und die Klasse definiert die Sichtweise von R für die funktionale Verarbeitung des Objekts. Für viele Objekte stimmen diese drei Begriffe weitgehend überein, aber bei speziellen Objekten wie Faktoren, Datumswerten oder benutzerdefinierten Objekten unterscheiden sie sich.
Atomare und rekursive Objekte
<!–Double und integer werden zusammen auch als numeric bezeichnet.
Viele weitere Typen, hier relevant sind logical, double, integer, character.
Übersicht der R Datentypen
Übersicht atomare Datenstrukturen in R
\(\Rightarrow\) Vektoren, Matrizen, Arrays
Übersicht rekursive Datenstrukturen in R