y = c(1, 2, 3.1415, -100)) (
[1] 1.0000 2.0000 3.1415 -100.0000
Der grundlegende (atomare) Datentyp in R ist der Vektor. Ein Vektor ist eine Datenstruktur, welche aus einem oder mehreren Elementen besteht. Demnach ist also auch eine Zahl (ein Skalar) wie z.B. 5
ein Vektor (mit einem Element).
Ein Vektor wird mit der Funktion c()
erzeugt (steht für combine oder concatenate). Im folgenden Beispiel erzeugen wir einen Vektor mit vier Elementen und weisen ihm den Namen y
zu:
y = c(1, 2, 3.1415, -100)) (
[1] 1.0000 2.0000 3.1415 -100.0000
Wenn man in R einen Befehl in Klammern setzt, dann wird der daraus resultierende Wert immer auch in der Console ausgegeben. Normalerweise ist das nämlich bei Zuweisungen nicht der Fall.
Das Beispiel von oben könnte man also auch in zwei Zeilen schreiben, was aber natürlich mehr Tipparbeit ist:
= c(1, 2, 3.1415, -100)
y y
Die Länge eines Vektors (also die Anzahl der Elemente des Vektors) kann mit der Funktion length()
bestimmt werden:
length(y)
[1] 4
Im folgenden Beispiel erzeugen wir einen Vektor a
mit einem einzigen Element – in diesem Fall muss man die Funktion c()
also gar nicht verwenden:
= 6
a length(a)
[1] 1
Mit c()
können also Vektoren beliebiger Längen miteinander kombiniert werden:
c(666, y, 666, c(23, 24))
[1] 666.0000 1.0000 2.0000 3.1415 -100.0000 666.0000 23.0000
[8] 24.0000
Ein Vektor besteht immer aus Elementen desselben Typs. Man nennt Vektoren daher homogene Datentypen. Bis jetzt haben wir numerische Vektoren kennengelernt, welche ausschließlich aus Zahlen bestehen. Es gibt aber auch Vektoren, die logische Elemente oder Zeichen/Buchstaben enthalten. Man unterscheidet in R daher grob zwischen folgenden Vektoren:
In einer der nächsten Einheiten werden wir dann noch Faktoren als vierten wichtigen Typ kennenlernen (grundsätzlich gibt es in R aber noch viele weitere Datentypen).
Numerische Vektoren sind vom Typ numeric
und beinhalten ausschließlich Zahlen, zum Beispiel:
c(2, 13, 15, 17)
[1] 2 13 15 17
Mit der Funktion class()
kann man den Typ (die Klasse) eines Objektes bestimmen. Beispiele:
class(2)
[1] "numeric"
= c(1.11, 2.33)
z class(z)
[1] "numeric"
class(c(3.1, 2.2, 10))
[1] "numeric"
Logische Vektoren bestehen ausschließlich aus den Werten TRUE
oder FALSE
(bitte auf die korrekte Schreibweise dieser Werte achten). Sie sind vom Typ logical
.
class(TRUE)
[1] "logical"
class(c(FALSE, FALSE, TRUE))
[1] "logical"
Es ist möglich, die Werte TRUE
und FALSE
mit T
und F
abzukürzen. In der Praxis sollte man auf diese Abkürzungen aufgrund der schlechteren Lesbarkeit aber verzichten.
Logische Vektoren entstehen unter anderem durch Vergleiche zweiter Vektoren:
= 5
x class(x)
[1] "numeric"
< 1 x
[1] FALSE
class(x < 1)
[1] "logical"
In R gibt es folgende Vergleichsoperatoren: >
, >=
, <
, <=
, ==
und !=
. Vergleiche (bzw. logische Vektoren) können mit |
(oder) und &
(und) verknüpft und mit !
negiert werden. Gruppierungen durch Klammersetzung sind ebenfalls möglich.
!TRUE
[1] FALSE
!FALSE
[1] TRUE
3 > 5) & (4 == 4) (
[1] FALSE
TRUE == TRUE) | (TRUE == FALSE) (
[1] TRUE
111 >= 111) | !(TRUE)) & ((4 + 1) == 5) ((
[1] TRUE
Der Gleichheitsoperator lautet ==
(also zwei Gleichheitszeichen) und nicht =
(ein einziges Gleichheitszeichen).
Zeichenkettenvektoren (Typ character
) bestehen aus Zeichen, welche innerhalb von Anführungszeichen eingegeben werden. Es können sowohl einfache '
als auch doppelte "
Anführungszeichen verwendet werden. Eine Zeichenkette kann aus Buchstaben, Ziffern und Sonderzeichen bestehen.
"Hello!"
[1] "Hello!"
'Hello!'
[1] "Hello!"
class("Hello!")
[1] "character"
s = c("What's", 'your', "name?")) (
[1] "What's" "your" "name?"
class(s)
[1] "character"
Die Funktion length()
gibt die Länge des Vektors (d.h. die Anzahl der Elemente) und nicht die Anzahl der Zeichen einer Zeichenkette zurück. Dafür kann man die Funktion nchar()
verwenden:
= c('Hello!', 'world')
s length(s)
[1] 2
nchar(s)
[1] 6 5
Vektoren sind homogene Datentypen, d.h. sie enthalten nur Elemente desselben Typs. Wenn man versucht, einen Vektor mit Elementen mit unterschiedlichen Typen zu erstellen, wird dieser automatisch in einen Typ “gezwungen”, welcher alle Elemente abbilden kann. Wenn man also Zahlen mit Zeichenketten mischt, werden alle Elemente in Zeichenketten umgewandelt (da Zeichenketten im allgemeinen nicht als Zahlen dargestellt werden können, umgekehrt können aber Zahlen als Zeichenketten sehr wohl dargestellt werden).
x = c(1, 2.14, "5", 6)) (
[1] "1" "2.14" "5" "6"
class(x)
[1] "character"
Rechnen kann man mit dem Vektor im obigen Beispiel nicht mehr, da die Elemente nun Zeichenketten und keine Zahlen mehr sind.
Man kann mit folgenden Funktionen auch explizit eine Umwandlung in einen gewünschten Typ durchführen:
as.numeric()
as.logical()
as.character()
Folgendes Beispiel wandelt einen Zeichenketten-Vektor in einen numerischen Vektor um (dies funktioniert, weil im Beispiel alle Zeichenketten als Zahlen interpretiert werden können):
as.numeric(c("1", "2.12", "66"))
[1] 1.00 2.12 66.00
Wenn das nicht geht, wird eine Warnung ausgegeben und NA
(steht für “Not Available”, also ein fehlender Wert) für das Element, welches sich nicht umwandeln lässt, angenommen:
as.numeric(c("1", "2.12", "X"))
Warning: NAs introduced by coercion
[1] 1.00 2.12 NA
Mit numerischen Vektoren kann man Rechenoperationen durchführen – diese werden stets elementweise angewendet:
y = c(1, 2, 3, 4)) (
[1] 1 2 3 4
* 100 + 2 # Berechnung wird für jedes der 4 Elemente separat durchgeführt y
[1] 102 202 302 402
Wie wir bereits wissen, gibt es die üblichen Operatoren +
, -
, *
, und /
für die Addition, Subtraktion, Multiplikation und Division. Das Zeichen ^
oder **
steht für “hoch” (berechnet also die Potenz von einer Basis zum Exponenten). Der Operator %/%
berechnet die ganzzahlige Division und %%
berechnet den Rest. Weitere praktische Funktionen sind abs()
für den Betrag und sqrt()
für die Quadratwurzel einer Zahl. Die Funktionen log()
bzw. exp()
berechnen den (natürlichen) Logarithmus bzw. die Exponentialfunktion. Mit sin()
bzw. cos()
kann man den Sinus bzw. Cosinus berechnen.
Wenn zwei Vektoren in einer Berechnung unterschiedlich lang sind, dann wiederholt R die Werte des kürzeren Vektors, sodass dieser dann gleich viele Elemente hat wie der längere Vektor. Man bezeichnet dies als Recycling. Dies ist z.B. auch schon der Fall, wenn man einen Vektor mit vier Elementen mit einem Skalar (Vektor mit einem Element) multipliziert, wie im folgenden Beispiel:
c(1, 2, 3, 4) * 2
[1] 2 4 6 8
Der skalare Vektor 2
wird automatisch auf den Vektor c(2, 2, 2, 2)
erweitert, daher entspricht die obige Operation eigentlich folgender elementweisen Berechnung:
c(1, 2, 3, 4) * c(2, 2, 2, 2)
[1] 2 4 6 8
Weiteres Beispiel:
c(1, 2, 3, 4) + c(0, 10)
[1] 1 12 3 14
Der kürzere Vektor c(0, 10)
wird verdoppelt und die Berechnung wird elementweise durchgeführt:
c(1, 2, 3, 4) + c(0, 10, 0, 10)
[1] 1 12 3 14
Wenn sich das Recycling nicht genau ausgeht, d.h. wenn die Länge des längeren Vektors kein ganzzahliges Vielfaches des kürzeren Vektors ist, dann funktioniert das Recycling zwar grundsätzlich trotzdem, aber es wird eine Warnung ausgegeben:
c(1, 2, 3, 4) + c(0, 10, 8)
Warning in c(1, 2, 3, 4) + c(0, 10, 8): longer object length is not a multiple
of shorter object length
[1] 1 12 11 4
Die Berechnung entspricht daher folgender Operation:
c(1, 2, 3, 4) + c(0, 10, 8, 0)
[1] 1 12 11 4
Vektoren mit definierten Zahlenfolgen erstellt man mit :
oder mit seq()
. Bei der ersten Option ist die Schrittweite immer 1, bei der zweiten Option kann diese beliebig angepasst werden.
1:20
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
:10 pi
[1] 3.141593 4.141593 5.141593 6.141593 7.141593 8.141593 9.141593
9:2
[1] 9 8 7 6 5 4 3 2
seq(1, 20) # äquivalent zu 1:20
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
seq(20, 1) # äquivalent zu 20:1
[1] 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
seq(0, 5, by=0.5) # Schrittweite 0.5
[1] 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
seq(5, 0, by=-0.5) # negative Schrittweite notwendig!
[1] 5.0 4.5 4.0 3.5 3.0 2.5 2.0 1.5 1.0 0.5 0.0
seq(0, 20, 2) # gerade Zahlen
[1] 0 2 4 6 8 10 12 14 16 18 20
seq(1, 20, 2) # ungerade Zahlen
[1] 1 3 5 7 9 11 13 15 17 19
seq(1, 3, length.out=10) # Gesamtlänge des Ergebnisses soll 10 sein
[1] 1.000000 1.222222 1.444444 1.666667 1.888889 2.111111 2.333333 2.555556
[9] 2.777778 3.000000
Mit seq()
kann man also Zahlenfolgen mit bestimmter Schrittweite (Argument by
) oder mit bestimmter Gesamtlänge (Argument length.out
) erzeugen.
Die Funktion rep()
wiederholt gegebene Werte:
rep(0, 90) # erzeuge einen Vektor mit 90 Nullen
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[39] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[77] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Hier kann man auch die Bedeutung der Werte in eckigen Klammern erkennen, die vor jeder Ausgabezeile stehen: sie geben den Index des ersten Elements der Zeile an (also im Beispiel [1]
für die erste Zeile, [39]
für die zweite Zeile und [77]
für die dritte Zeile).
Beachten Sie auch die unterschiedlichen Ergebnisse durch Verwendung der Argumente times
bzw. each
:
rep(c(0, 1, 2), times=10)
[1] 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2
rep(c(0, 1, 2), each=10)
[1] 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
rep(c(0, 1, 2), times=c(10, 10, 10)) # gleiches Ergebnis wie mit each
[1] 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
Vektoren können indiziert werden, d.h. einzelne Elemente können herausgegriffen werden. Im Gegensatz zu vielen anderen Programmiersprachen beginnt R mit 1 zu zählen (d.h. das erste Element entspricht dem Index 1). Man verwendet dazu eckige Klammern, innerhalb derer die gewünschten Elemente angegeben werden.
Betrachten wir in den folgenden Beispielen den Vektor x
, welcher aus 11 Elementen besteht:
x = seq(10, 110, 10)) (
[1] 10 20 30 40 50 60 70 80 90 100 110
length(x)
[1] 11
Nun erzeugen wir durch Indizieren neue Untermengen des bestehenden Vektors:
1] # 1. Element x[
[1] 10
4] # 4. Element x[
[1] 40
1:5] # Elemente 1-5 x[
[1] 10 20 30 40 50
c(1, 4, 8)] # Elemente 1, 4 und 8 x[
[1] 10 40 80
Negative Indizes bedeuten “alle Elemente außer die angegebenen”:
c(-1, -10)] x[
[1] 20 30 40 50 60 70 80 90 110
-c(1, 10)] x[
[1] 20 30 40 50 60 70 80 90 110
Man kann auch mit logischen Vektoren indizieren. Dazu erstellt man zuerst einen logischen Vektor (z.B. durch einen Vergleich) und verwendet diesen dann als Index innerhalb der eckigen Klammern (dies kann direkt in einem Schritt gemacht werden). Dabei werden jene Elemente herausgegriffen, für die der Indexvektor TRUE
ist.
x
[1] 10 20 30 40 50 60 70 80 90 100 110
c(TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE)] x[
[1] 10 30 90
Das folgende Beispiel illustriert die Erstellung des logischen Indexvektors durch einen Vergleich:
> 40 x
[1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> 40] x[x
[1] 50 60 70 80 90 100 110
Idealerweise ist der logische Indexvektor gleich lang wie der zu indizierende Vektor. Falls der Indexvektor kürzer ist, findet wieder Recycling statt:
c(FALSE, TRUE)] x[
[1] 20 40 60 80 100
Vektoren können auch Elemente mit Namen enthalten. So kann man auch mit den Elementnamen anstatt mit der Position indizieren.
vect = c(a=11, b=2, c=NA)) # Argumentnamen werden als Elementnamen verwendet (
a b c
11 2 NA
2] vect[
b
2
"b"] vect[
b
2
Die Funktion names()
gibt die Namen der Elemente zurück:
names(vect)
[1] "a" "b" "c"
Mit dieser Funktion kann man die Elementnamen eines Vektors auch nachträglich setzen:
= 1:3
x names(x)
NULL
names(x) = c("test", "value", "x")
x
test value x
1 2 3
In R können fehlende Werte mit dem speziellen Wert NA
(Not Available) codiert werden.
vect = c(15, 1.12, NA, 12, NA, 33.22)) (
[1] 15.00 1.12 NA 12.00 NA 33.22
Mit der Funktion is.na()
können die fehlenden Werte bestimmt werden. So kann man einfach alle Werte aus einem Vektor extrahieren, die nicht NA
sind.
is.na(vect) # die fehlenden Werte
[1] FALSE FALSE TRUE FALSE TRUE FALSE
!is.na(vect) # ! invertiert einen logischen Vektor
[1] TRUE TRUE FALSE TRUE FALSE TRUE
!is.na(vect)] vect[
[1] 15.00 1.12 12.00 33.22
Berechnen Sie die Oberfläche (Grundflächen plus Mantelfläche) sowie das Volumen eines Zylinders mit Radius 5 und Höhe 9. Erzeugen Sie dafür die Variablen r
und h
. Speichern Sie die Ergebnisse in den Variablen A
(Fläche) bzw. V
(Volumen) ab. Wie lauten die Ergebnisse (also die Werte beider Variablen)?
Erstellen Sie einen Vektor x
mit den Elementen 4, 18, -7, 16, 4 und -44. Erstellen Sie danach einen Vektor y
, welcher die quadrierten Elemente aus x
enthält (nutzen Sie dazu die Eigenschaft, dass R Rechenoperationen elementweise durchführt). Zum Schluss erstellen Sie einen Vektor z
, indem Sie x
und y
aneinanderhängen. Mit welcher Funktion können Sie die Anzahl der Elemente in z
bestimmen?
Gegeben sei folgender Vektor:
= c(44, 23, -56, 98, 99, 32, 45, 22) x
Welche Elemente aus x
sind gerade? Welche Elemente sind ungerade? Erstellen Sie zwei entsprechende logische Vektoren, welche Sie dann zum Indizieren der geraden bzw. ungeraden Elemente von x
verwenden können.
Hinweis: Erstellen Sie die logischen Indexvektoren mit einem Vergleich und nicht händisch (d.h. für die geraden Zahlen in diesem Beispiel wäre der gesuchte logische Indexvektor c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE)
, dies sollen Sie aber nicht so eingeben). Verwenden Sie stattdessen die Eigenschaft, dass gerade Zahlen einen Rest von 0 ergeben wenn man sie durch 2 dividiert. Ungerade Zahlen ergeben hier einen Rest von 1. Verwenden Sie daher den Operator %%
für den Rest einer Division. Erstellen Sie dann mit einem Vergleich jeweils einen logischen Indexvektor (für die geraden Zahlen vergleichen Sie ob der Rest 0 ist, für die ungeraden Zahlen ob der Rest 1 ist), welchen Sie dann zum Indizieren verwenden können.
Erstellen Sie folgende Vektoren und geben Sie sie am Bildschirm aus:
Erstellen Sie einen Zeichenketten-Vektor mit folgenden Einträgen: zuerst 10 mal "Placebo"
, dann 10 mal "Group 1"
und schließlich 10 mal "Group 2"
(d.h. das Ergebnis soll 30 Elemente haben).
Erstellen Sie einen Vektor k
mit den geraden Zahlen von 0 bis 20 (am besten mit der Funktion seq()
und der entsprechenden Schrittweite). Geben Sie dann durch Indizieren die folgenden Elemente dieses Vektors am Bildschirm aus:
Erstellen Sie folgenden Vektor:
= c(10, 20, NA, 30, 40) t
Berechnen Sie dann mit der Funktion mean()
den Mittelwert von t
. Was bewirkt der fehlende Wert NA
? Sehen Sie in der Hilfe zum Befehl mean()
nach, wie Sie fehlende Werte bei der Berechnung ignorieren können (welches optionale Argument müssen Sie setzen?) und führen Sie diese Berechnung durch.
Alternativ könnten Sie mit is.na()
alle fehlenden Werte aus t
identifizieren und dann die Funktion mean()
auf alle nicht fehlenden Werte aus t
anwenden (so wie in den Unterlagen gezeigt).
Gegeben seien folgende Standardabweichungen von fünf Messgrößen in einem Vektor s
:
= c(1, 11.3, 7.8, 3.4, 6) s
Wie können Sie daraus in einem Schritt die fünf Varianzen berechnen?