Vektoren in R: Anwendungen

Grundlegend fĂŒr das VerstĂ€ndnis von Operationen, die mit Vektoren ausgefĂŒhrt werden können, sind die punktweise AusfĂŒhrung (eine Operation wird an die Komponenten weitergereicht) und der recycling-Mechanismus, der festlegt, wie Vektoren mit unterschiedlichen LĂ€ngen verknĂŒpft werden. Ausgehend hiervon werden zahlreiche Operationen vorgestellt, die mit Vektoren ausgefĂŒhrt werden können (wie zum Beispiel statistische Funktionen, Sortier-Algorithmen, Mengen-Operationen).
Noch keine Stimmen abgegeben
Noch keine Kommentare

Einordnung des Artikels

Dieses Kapitel setzt die Kenntnis der Eigenschaften von Vektoren voraus, die in Vektoren in R: der Datentyp vector erklĂ€rt wurden; lediglich Attribute sind fĂŒr einen ersten Durchgang unerheblich.

EinfĂŒhrung

Mit den bisher im Kapitel Vektoren in R: der Datentyp vector vorgestellten Funktionen und Operationen lassen sich:

  • Vektoren erzeugen,
  • auf Komponenten eines Vektors zugreifen,
  • Vektoren mit Diagnose-Funktionen untersuchen,
  • Attribute fĂŒr Vektor-Objekte definieren, verĂ€ndern und abfragen.

Es gibt aber noch eine Vielzahl weiterer Funktionen um:

  • Vektoren miteinander zu verknĂŒpfen,
  • Eigenschaften von Vektoren berechnen zu lassen.

Dabei ist insbesondere der in R verwendete recycling-Mechanismus bei Vektor-Operationen wichtig, um deren Verhalten richtig vorherzusagen. Gerade wer mit Mathematik besser vertraut ist als mit Programmierung, wird ĂŒberrascht sein, wie hier Vektor-Operationen in dem Fall definiert sind, dass die Vektoren aufgrund ihrer unterschiedlichen LĂ€nge eigentlich nicht verknĂŒpft werden dĂŒrfen.

Diesen recycling-Mechanismus und wie Operationen in R punktweise ausgefĂŒhrt werden, sollte man beim ersten Durcharbeiten dieses Kapitels unbedingt verstehen und genĂŒgend Zeit darauf verwenden, um damit vertraut zu werden — auf diese Eigenschaften von R wird im Folgenden immer wieder zurĂŒckgegriffen und man benötigt sie fĂŒr das VerstĂ€ndnis aller anderen zusammengesetzten Datentypen.

Dagegen reicht es bei den Funktionen fĂŒr Vektoren, sich vorerst einen groben Überblick zu verschaffen, welche Funktionen es gibt und wie sie eingesetzt werden. SpĂ€testens wenn Sie eigene Anwendungen mit den hier vorgestellten Funktionen schreiben, werden Sie diese Teile ausfĂŒhrlich durcharbeiten mĂŒssen.

Punktweise AusfĂŒhrung von Operationen und der recycling-Mechanismus

Überblick

Um einen ersten Eindruck zu gewinnen, wie in R Rechenoperationen ausgefĂŒhrt werden, wurden im Kapitel EinfĂŒhrung in R: Zahlen und Variablen zunĂ€chst die Grundrechenarten und Potenzen fĂŒr Zahlen eingefĂŒhrt. Um jetzt mit Vektoren besser vertraut zu werden, werden diese Operationen von Zahlen auf Vektoren verallgemeinert. Dabei sind zwei Punkte fĂŒr das VerstĂ€ndnis von Vektor-Operationen in R von entscheidender Bedeutung:

  • Operationen werden grundsĂ€tzlich punktweise ausgefĂŒhrt,
  • haben die verknĂŒpften Vektoren nicht die passende LĂ€nge, kommt der sogenannte recycling-Mechanismus zum Einsatz.

Die Diskussion wird dann auch zeigen, dass sich diese beide Punkte eigentlich nicht voneinander trennen lassen. Um dennoch schrittweise vorzugehen, werden zunĂ€chst nur solche FĂ€lle untersucht, bei denen der recycling-Mechanismus noch nicht eingesetzt wird. Erst wenn dafĂŒr die punktweise AusfĂŒhrung von Operationen erklĂ€rt ist, werden die FĂ€lle mit recycling-Mechanismus untersucht.

♩♩♩

Um dies gleich an einem typischen Beispiel aufzuzeigen:

Werden die Vektoren

u = (1, 2, 3, 4, 5) und v = (1, 1, 1, 1, 1)

addiert, so wird diese Addition komponentenweise (oder wie man auch sagt punktweise) ausgefĂŒhrt:

u + v = (1+1, 2+1, 3+1, 4+1, 5+1) = (2, 3, 4, 5, 6).

Doch was passiert, wenn man die Vektoren

u = (1, 2, 3, 4, 5) und w = (1, 0)

addieren möchte?

Wer die Vektor-Rechnung aus der Mathematik kennt, wird hier vermutlich erwarten:

Der Vektor w wird solange mit Nullen aufgefĂŒllt, bis er die LĂ€nge von u hat und dann wird wieder punktweise addiert, also

u + w = (1, 2, 3, 4, 5) + (1, 0, 0, 0, 0) = (2, 2, 3, 4, 5)

In R wird nicht so gerechnet! Der recycling-Mechanismus sorgt nĂ€mlich dafĂŒr, dass der Vektor w solange wiederholt (oder aneinandergehĂ€ngt) wird, bis er 5 Komponenten hat. In R lautet daher die Addition von u und w:

u + w = (1, 2, 3, 4, 5) + (1, 0, 1, 0, 1) = (2, 2, 4, 4, 6)

Mit diesem Beispiel sollte auch klar sein, dass man sehr genau Bescheid wissen muss, wann der recycling-Mechanismus eingesetzt wird und welche Konsequenzen er hat — andernfalls werden viele Berechnungen unerwartete Ergebnisse liefern.

Das folgende Skript zeigt obige Berechnung:

u <- (1:5)
w <- c(1, 0)

u + w
# [1] 2 2 4 4 6

Punktweise AusfĂŒhrung von Operationen

In R sind zahlreiche Operatoren fĂŒr Vektoren definiert, man muss dabei aber beachten, dass sie meist punktweise (oder komponentenweise) ausgefĂŒhrt werden; mit punktweise ist gemeint, dass zum Beispiel die Addition zweier Vektoren auf die einzelnen Komponenten ĂŒbertragen wird:

u <- (1:5)                  # 1 2 3 4 5
v <- rep(1, times = 5)      # 1 1 1 1 1

w <- u + v
w                           # 2 3 4 5 6

Dies gilt ebenso fĂŒr Subtraktion, Multiplikation, Division und Potenz:

u <- (1:5)                  # 1 2 3 4 5
v <- rep(1, times = 5)      # 1 1 1 1 1

w <- u - v                  # 0 1 2 3 4
w   <- u * v                # 1 2 3 4 5
w <- v / u                  # 1.00000 0.50000 0.33333 0.25000 0.20000
u^u                         # 1    4   27  256 3125

In der letzten Zeile wird also jeweils die Potenz einer Zahl n mit sich selbst genommen: nn, wobei n von 1 bis 5 lÀuft.

Im Kapitel EinfĂŒhrung in R: Zahlen und Variablen wurde ausfĂŒhrlich besprochen, dass es in R drei Operationen gibt, die mit der Division zusammenhĂ€ngen:

  1. Die Division, die bis auf Rundungsfehler den exakten Wert liefert.
  2. Die Ganzzahl-Division, die den ganzzahligen Anteil bei der Division durch eine ganze Zahl liefert.
  3. Der Rest der bei einer Ganzzahl-Division entsteht.

Die Operatoren fĂŒr diese drei Operationen sind:

Operation Operator-Symbol
Division /
Ganzzahl-Division %/%
Division mit Rest %%

Wie die Division werden auch die Ganzzahl-Division und die Berechnung des Restes punktweise ausgefĂŒhrt; das folgende Skript zeigt ein Beispiel:

u <- (1:6)                          # 1 2 3 4 5 6
v <- rep(x = 2, times = 6)          # 2 2 2 2 2 2

# Division:
u / v
# [1] 0.5 1.0 1.5 2.0 2.5 3.0

# Ganzzahl-Division:
u %/% v
# [1] 0 1 1 2 2 3

# Rest:
u %% v
# [1] 1 0 1 0 1 0

Der recycling-Mechanismus in R

Im letzten Unterabschnitt Punktweise AusfĂŒhrung von Operationen wurden die Vektoren stets von der LĂ€nge gewĂ€hlt, dass bei punktweiser AusfĂŒhrung einer Operation kein Zweifel besteht, wie diese Operation auszufĂŒhren ist. Im Beispiel im Unterabschnitt Überblick wurde schon gezeigt, wie der recycling-Mechanismus wirkt: haben die Vektoren nicht identische LĂ€nge, wird der kĂŒrzere Vektor so lange wiederholt bis die LĂ€ngen beider Vektoren ĂŒbereinstimmen. Bei der letzten Wiederholung wird eventuell nur ein Teil des kĂŒrzeren Vektors benötigt.

Hier nochmal einige Beispiele; das Skript zeigt auch die Fehlermeldung, die man dabei eventuell erhÀlt:

u <- (1:5) 
w <- c(1, 0)
x <- 2

u + w
# [1] 2 2 4 4 6
# Warning message:
#   In u + w : longer object length is not a multiple of shorter object length

u + x
# [1] 3 4 5 6 7

x / u
# [1] 2.0000000 1.0000000 0.6666667 0.5000000 0.4000000

Man erkennt an diesem Beispiel, dass es drei Möglichkeiten gibt, wie der recycling-Mechanismus ausgefĂŒhrt wird (die dritte Möglichkeit tritt hier noch nicht auf, ein Beispiel mit dem Skalarprodukt wird aber folgen):

  1. Die Operation wird mit dem recycling-Mechanismus ausgefĂŒhrt, aber es wird keine Warnung oder Fehlermeldung ausgegeben (Zeile 10 und 13).
  2. Die Operation wird mit dem recycling-Mechanismus ausgefĂŒhrt und zusĂ€tzlich wird eine Warnung auf der Konsole ausgegeben (Zeile 5).
  3. Die Operation kann nicht ausgefĂŒhrt werden und man erhĂ€lt die entsprechende Fehlermeldung (ein Beispiel folgt).

Der erste Fall tritt immer ein, wenn die LĂ€nge des lĂ€ngsten Vektors ein ganzzahliges Vielfaches der LĂ€nge des kĂŒrzeren Vektors ist (siehe Zeile 10 und 13).

Der zweite Fall tritt ein, wenn dies nicht gilt (Zeile 5).

Und manche Operationen (dritter Fall) sind derart abgesichert, dass sie nur mit Vektoren der richtigen LĂ€nge durchgefĂŒhrt werden können (etwa Skalarprodukt mit dem Operator %*% ).

Besonders interessant im obigen Beispiel ist die Addition u + x (Zeile 10): Die Zahl x = 2 wird zum Vektor x = (2, 2, 2, 2, 2) erweitert und so zu u addiert.

Man könnte diese Operation auch einfacher (dennoch gleichwertig) interpretieren: Die Zahl x = 2 wird zu jeder Komponente von u addiert.

Ein Vorteil des automatischen AneinaderhÀngens von Vektoren ist, dass man mehrere Formeln leicht zu einer Formel zusammenfassen kann; möchte man etwa

a1/2 = b ± 1

rechnen, so kann dies tatsÀchlich in einer Anweisung erledigt werden:

a <- b + c(-1, 1)

In diesem Fall ist a ein Vektor mit den beiden Komponenten b-1 und b+1.

Es fehlt noch die genauere ErklÀrung der Potenz:

Wird ein Vektor potenziert, so wird jede Komponente potenziert, wie das folgende Skript zeigt.

v <- (1:5)

v^2
# [1]  1  4  9 16 25

Ist die Potenz auch ein Vektor, mit identischer LĂ€nge wie die Basis, so wird wieder punktweise potenziert:

v <- (1:5)
p <- c(1, 2, 1, 2, 1)

v^p
# [1]  1  4  3 16  5

Stimmen die LĂ€ngen von Basis und Potenz nicht ĂŒberein, wird einer der beiden Vektoren durch den recycling-Mechanismus verlĂ€ngert. Das folgende Skript zeigt die beiden Möglichkeiten:

v <- (1:5)
p <- c(1, 2)

v^p             # p wird erweitert zu 1 2 1 2 1
# [1]  1  4  3 16  5
# Warning message:
#   In v^p : longer object length is not a multiple of shorter object length

p^v             # p wird erweitert zu 1 2 1 2 1
# [1]  1  4  1 16  1
# Warning message:
#   In p^v : longer object length is not a multiple of shorter object length

Man erkennt, dass der Vektor v unverÀndert verwendet wird, dagegen wird p immer zu (1, 2, 1, 2, 1) erweitert.

VerknĂŒpfung von Vektoren ungleicher LĂ€nge

Das folgende Beispiel soll zeigen, dass es nicht ratsam ist, Vektoren unterschiedlicher LĂ€nge miteinander zu verknĂŒpfen und darauf zu vertrauen, dass man den recycling-Mechanismus verstanden hat und das Ergebnis vorhersagen kann. Werden nĂ€mlich drei (oder mehr) Vektoren addiert, hĂ€ngt das Ergebnis von der Reihenfolge ab, in welcher die beiden Additionen durchgefĂŒhrt werden.

In der Mathematik ist es unerheblich, ob eine Summe

v = a + b + c

in der Reihenfolge

v = (a + b) + c

oder in der Reihenfolge

v = a + (b + c)

berechnet wird. Im ersten Fall wird zuerst die Addition (a + b) ausgefĂŒhrt und anschließend wird zum Ergebnis c addiert; man sagt kurz: die Addition wird von links nach rechts ausgefĂŒhrt. Im zweiten Fall wird die Addition von rechts nach links ausgefĂŒhrt.

Sind aber die drei Summanden Vektoren unterschiedlicher LĂ€nge, so lassen sich leicht Beispiele konstruieren, in denen die beiden Arten zu addieren, andere Ergebnisse liefern. Gibt man die Addition ohne Klammern ein, muss man wissen, in welcher Reihenfolge in R die Addition durchgefĂŒhrt wird. (Das Verhalten gilt in R fĂŒr alle Operationen, die gleichrangig sind.)

Das folgende Skript zeigt ein Beispiel mit unterschiedlichen Ergebnissen und es zeigt, dass in R von links nach rechts gerechnet wird:

a <- (1:5)
b <- c(1, 0, 1)
c <- c(1,2)

# Addition von links nach rechts:
(a + b) + c
# [1] 3 4 5 7 6
# Warning messages:
#   1: In a + b :
#   longer object length is not a multiple of shorter object length
# 2: In (a + b) + c :
#   longer object length is not a multiple of shorter object length

# Addition von rechts nach links:
 a + (b + c) 
# [1] 3 4 5 6 7
# Warning messages:
#   1: In b + c :
#   longer object length is not a multiple of shorter object length
# 2: In a + (b + c) :
#   longer object length is not a multiple of shorter object length

# Addition ohne Vorgabe der Reihenfolge:
a + b + c
# [1] 3 4 5 7 6
# Warning messages:
# 1: In a + b :
#   longer object length is not a multiple of shorter object length
# 2: In a + b + c :
#   longer object length is not a multiple of shorter object length

Test auf Gleichheit

Der Vergleichsoperator und die Funktion identical()

Schon bei Zahlen wurde kurz darauf hingewiesen, dass bei Vektoren ein deutlicher Unterschied besteht, ob man die Gleichheit zweier Vektoren mit Hilfe des Vergleichsoperators == oder der Funktion identical(x, y) testet. Das folgende Skript zeigt den Unterschied:

  • Der Vergleichsoperator == vergleicht die Vektoren komponentenweise und liefert als RĂŒckgabewert einen logischen Vektor, aus dem man fĂŒr jede einzelne Komponente das Ergebnis des Vergleichs ablesen kann.
  • Die Funktion identical(x, y) gibt einen logischen Wert zurĂŒck. Dieser ist TRUE, wenn die Vektor-LĂ€ngen von x und y ĂŒbereinstimmen und alle Komponenten identisch sind. Ist eine Bedingung nicht erfĂŒllt, wird FALSE zurĂŒckgegeben.
v <- (1:6)
w <- (1:6)
u <- c(v, v)  

v == w
# [1] TRUE TRUE TRUE TRUE TRUE TRUE

identical(x = v, y = w)
# [1] TRUE

v == u
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

identical(x = v, y = u)
# [1] FALSE
# hier gibt es keine Warnung

v == (1:10)
# [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
# Warning message:
#   In v == (1:10) :
#   longer object length is not a multiple of shorter object length

Zur ErklÀrung:

Zeile 1 bis 3: Die Vektoren v und w sind nach LĂ€nge und dem Wert aller Komponenten identisch. Wendet man bei einem Vergleich von v und u den recycling-Mechanismus an, so haben beide Vektoren die LĂ€nge 12 und stimmen in allen Komponenten ĂŒberein — es ist also nicht leicht vorherzusagen, welches Ergebnis ein Vergleich von v und u liefern wird.

Zeile 5 und 6: Der Vergleich von v und w mit dem Operator == liefert einen logischen Vektor mit 6 Komponenten, die alle gleich TRUE sind.

Zeile 8 und 9: Vergleich von v und w mit identical() liefert einen logischen Wert, nĂ€mlich TRUE — es gibt keine Eigenschaft, in der sich die Vektoren unterscheiden.

Zeile 11 und 12: Beim Vergleich von v und u mit dem Operator == wird durch den recycling-Mechanismus v zu einem Vektor mit 12 Komponenten ergĂ€nzt; dieser stimmt in jeder Komponente mit u ĂŒberein und deshalb erhĂ€lt man einen logischen Vektor mit 12 Komponenten (alle gleich TRUE). Es gibt hier keine Warnung bezĂŒglich unterschiedlicher Vektor-LĂ€ngen, da v bei Wiederholung in u passt (2*6 = 12).

Zeile 14 und 15: Beim Vergleich von v und u mit identical() erhÀlt man nur FALSE und keinerlei Warnung (die Vektoren haben unterschiedliche LÀnge und sind somit verschieden).

Zeile 18 bis 22: Vergleicht man dagegen v mit (1:10) mittels == , erhÀlt man eine logischen Vektor mit 10 Komponenten und zusÀtzlich die bekannte Warnung, wonach die Vektor-LÀngen kein Vielfaches voneinander sind.

Test auf nÀherungsweise Gleichheit: die Funktion all.equal()

In der Mathematik werden viele Entscheidungen, ob eine gewisse Eigenschaft vorliegt oder nicht, durch Kriterien der folgenden Art formuliert:

Falls x = 0 gilt die Aussage A, falls x ungleich null ist, gilt die Aussage A nicht.

Beispiele dafĂŒr sind etwa:

  • Die Entscheidung, ob ein Gleichungssystem eine eindeutige Lösung besitzt oder nicht; dazu wird geprĂŒft, ob die Determinante der Koeffizientenmatrix gleich null ist.
  • Die Entscheidung, ob eine waagrechte Tangente vorliegt; dazu wird untersucht, ob die Ableitungsfunktion an der betreffenden Stelle gleich null ist.

Die Liste lĂ€sst sich beliebig fortsetzen. Aber es sollte klar sein, dass sich solch scharf formulierte Kriterien in einem Programm niemals ĂŒberprĂŒfen lassen. Denn dadurch dass fĂŒr eine Gleitkommazahl nur endlich viel Speicherplatz zur VerfĂŒgung steht, wird es immer zu Rundungsfehlern kommen. Und ein Ergebnis der Art x = 2 · 10-10 ist zwar in der Mathematik eindeutig interpretierbar (x ist ungleich null), aber als Ergebnis einer Berechnung in einem Programm zweideutig:

  • entweder ist tatsĂ€chlich x ungleich null,
  • oder x wĂ€re bei exakter Rechnung gleich null und die Abweichung ist nur durch Rundungsfehler entstanden.

Da die in einem Programm durchgefĂŒhrten Berechnung nur in AusnahmefĂ€llen daraufhin nachvollziehbar sind, welcher der beiden FĂ€lle vorliegt, sollte man die Kriterien aus der Mathematik nur sehr vorsichtig anwenden.

Hat man die Möglichkeit abzuschĂ€tzen, in welcher GrĂ¶ĂŸenordnung die Rundungsfehler liegen, so kann man zumindest ĂŒberprĂŒfen, ob zwei Zahlen nĂ€herungsweise gleich sind; nĂ€herungsweise heisst hier: bis auf eine Differenz, die kleiner ist als eine vorgegebene Toleranz.

In R kann diese PrĂŒfung auf nĂ€herungsweise Gleichheit mit Hilfe der Funktion all.equal() durchgefĂŒhrt werden. Wie schon aus dem Namen zu schließen ist, lassen sich nicht nur einzelne Zahlen, sondern auch Objekte mit zusammengesetzten Datentypen vergleichen. Die Funktion ist generisch implementiert, das heißt, dass je nach Datentyp der Eingabewerte ein andere Implementierung aufgerufen wird.

Die Funktion all.equal() besitzt drei Eingabewerte (in Wirklichkeit weitere, die hier nicht besprochen werden):

  • target: ein R-Objekt, dessen Datentyp festlegt, welche Implementierung von all.equal() verwendet wird.
  • current: ein anderes R-Objekt, das mit target verglichen wird.
  • tolerance: Falls eine Differenz kleiner ist als diese tolerance, werden die verglichenen Objekte als gleich behandelt und es wird TRUE zurĂŒckgegeben. Falls eine Differenz grĂ¶ĂŸer ist als tolerance, erfolgt eine Ausgabe. Der default-Wert von tolerance betrĂ€gt etwa 1.5 · 10-8.

Der default-Wert von tolerance lÀsst sich abfragen:

# default-Wert der Toleranz:
sqrt(.Machine$double.eps)
# [1] 1.490116e-08

Es folgen einige Beispiele:

# Vergleich zweier Zahlen:
a <- 2
b <- 1.99

# Vergleich mit default-Wert von tolerance:
all.equal(target = a, current = b)
# [1] "Mean relative difference: 0.005"

# Vergleich mit tolerance = 0.1:
all.equal(target = a, current = b, tolerance = 0.1)
# [1] TRUE

# Vergleich mit tolerance = 0.001:
result <- all.equal(target = a, current = b, tolerance = 0.001)
# [1] "Mean relative difference: 0.005"

str(result)
# chr "Mean relative difference: 0.005"

# Vergleich zweier Vektoren:
x <- c(2, 2)
y <- c(1.95, 1.995)

all.equal(target = x, current = y, tolerance = 0.1)
# [1] TRUE

all.equal(target = x, current = y, tolerance = 0.01)
# [1] "Mean relative difference: 0.01375"

all.equal(target = x, current = y, tolerance = 0.001)
# [1] "Mean relative difference: 0.01375"

Folgende Eigenschaften der Funktion all.equal() sollen ausdrĂŒcklich betont werden:

  • Aus dem Namen der Funktion wird man schließen, dass der RĂŒckgabewert ein logischer Wert ist. Dies ist nur halb richtig:
    • Falls die (nĂ€herungsweise) Gleichheit festgestellt wird, wird TRUE zurĂŒckgegeben,
    • andernfalls ist der RĂŒckgabewert eine Zeichenkette, die die Abweichung beschreibt (siehe etwa Zeile 7, 15 und 18).
  • Wird eine Zeichenkette ausgegeben, so lĂ€sst sich nicht nachvollziehen, welcher Komponenten fĂŒr die zu große Abweichung verantwortlich waren (siehe etwa Zeile 27 und 30: in Zeile 27 ist nur die erste Komponente verantwortlich, in Zeile 30 sind es beide Komponenten).

Funktionen fĂŒr Vektoren

Versuch einer Einteilung

In R gibt es natĂŒrlich schon eine Vielzahl von Funktionen, die Vektoren verarbeiten. Und es ist immer besser, diese Funktionen einzusetzen als sie selber zu programmieren. Der Grund liegt darin, dass viele dieser Funktionen eine lange Liste von Eingabewerten haben und man durch Setzen der Eingabewerte sehr viele SpezialfĂ€lle abfangen kann, die einen hohen Programmier-Aufwand erfordern wĂŒrden.

Aufgrund ihrer Vielzahl fÀllt es aber schwer, die Funktionen sinnvoll in Gruppen einzuteilen:

  • Soll man nach Inhalten gruppieren, also etwa
    • statistische Funktionen,
    • geometrische Funktionen und so weiter.
  • Oder soll man nach formalen Gesichtspunkten gruppieren, also etwa:
    • Anzahl der Eingabewerte,
    • RĂŒckgabewert.

Hier wird grob folgende Einteilung der Funktionen vorgenommen:

  1. Funktionen, die man eigentlich als Eingabewert eine Zahl besitzen, denen in R aber auch ein Vektor ĂŒbergeben werden kann.
  2. Funktionen, die eigentlich dafĂŒr vorgesehen sind, einen Vektoren weiterzuverarbeiten.
  3. Funktionen, die eigentlich dafĂŒr vorgesehen sind, zwei oder mehrere Vektoren weiterzuverarbeiten.
  4. Funktionen, mit denen Vektoren gefiltert oder umgeordnet werden können oder Ă€hnliche Aufgaben erledigt werden können. Manche dieser Aufgaben lassen sich einfacher erledigen, wenn man mit Faktoren (anstelle von Vektoren) arbeitet — Faktoren werden in einem eigenen Kapitel vorgestellt.

Es wird sich allerdings zeigen, dass sich nicht alle Funktionen so eindeutig einer dieser Gruppen zuordnen lassen — eine bessere Übersicht ĂŒber die hier beschriebenen Funktionen liefert vielleicht die Zusammenfassung am Ende des Kapitels.

Die vier genannten Gruppen sollen sofort durch typische Beispiele veranschaulicht werden:

Beispiel: Wurzelfunktion

Die Wurzelfunktion ist in der Mathematik fĂŒr einen Eingabewert definiert. Da in R nicht zwischen Zahlen und Vektoren unterschieden wird, ist zu erwarten, dass man als Eingabewert auch einen Vektor verwenden darf. Das Beispiel der Potenz hat schon gezeigt, dass die Berechnung dann eben komponentenweise durchgefĂŒhrt wird.

Das folgende Skript zeigt die Anwendung der Wurzelfunktion auf einen Vektor:

v <- c(1, 4, 9, 16, 25)

w <- sqrt(v)
w
# [1] 1 2 3 4 5

Man kann diese verallgemeinerte Definition von Funktionen in R zum Beispiel dafĂŒr nutzen, um Wertetabellen zu erzeugen.

Beispiel: Mittelwert

In Zahlenbereiche und spezielle Werte in R (Inf, NaN, NA und NULL) wurde die Bedeutung vn NA (not available) diskutiert. Bei der Berechnung eines Mittelwertes eines Vektors kann es vorkommen, dass nicht alle Komponenten als Zahlen gegeben sind, sondern einige als NA gekennzeichnet sind. Bei vielen Funktionen in R lÀsst sich leicht bestimmen, wie mit den NA-Werten umgegangen werden soll.

Der Mittelwert eines Vektors wird in R mit Hilfe der Funktion mean() berechnet; das Beispiel unten zeigt, dass man in dieser Funktion zusÀtzlich bestimmen kann, ob NA-Werte im Eingabe-Vektor ignoriert werden oder nicht. Werden sie nicht ignoriert, ist auch der Mittelwert NA (not available):

v <- (1:5)
v <- c(v, NA)

length(v)
# [1] 6

v
# [1]  1  2  3  4  5 NA

mean(v, na.rm = TRUE)
# [1] 3

mean(v, na.rm = FALSE)
# [1] NA

mean(v)
# [1] NA

Beispiel: Berechnung des Korrelationskoeffizienten

FĂŒr typische Aufgaben aus der Mathematik — insbesondere aus der Statistik — sind in R geeignete Funktionen implementiert. Hier wird ein Beispiel gezeigt, wie zu zwei Vektoren der Korrelationskoeffizient berechnet wird:

v <- (1:6)
w <- -2 * v + 3

c <- cor(x = v, y = w)
c
# [1] -1

Beispiel: Auswahl eines Teilvektors

Im folgenden Beispiel werden aus einem Vektor v diejenigen Komponenten ausgewĂ€hlt, die grĂ¶ĂŸer sind als der Mittelwert von v. Der Teilvektor wird unter w abgespeichert. Die Auswahl erfolgt dadurch, dass die Bedingung formuliert wird, die die Komponenten des Teilvektors erfĂŒllen mĂŒssen.

v <- (1:9)
w <- v[v > mean(v)]

w
# [1] 6 7 8 9

Wissenschaftliche Funktionen

Im Abschnitt Wissenschaftliche Funktionen im Kapitel EinfĂŒhrung in R: Zahlen und Variablen wurden zahlreiche wissenschaftliche Funktionen vorgestellt, die in R implementiert sind. In der Mathematik werden sie ĂŒblicherweise mit einem Eingabewert und einem RĂŒckgabewert definiert. Da in R Zahlen nur SpezialfĂ€lle von Vektoren sind, werden diese Funktionen in R so implementiert, dass der Eingabewert ein beliebiger Vektor sein kann. Die Funktion wird dann komponentenweise auf die Eingabewerte angewendet und der RĂŒckgabewert ist wieder ein Vektor (dessen LĂ€nge mit der des Eingabe-Vektors ĂŒbereinstimmt).

Bei den Beispielen oben wurde dies fĂŒr die Wurzelfunktion bereits demonstriert. Eine wichtige Anwendung dieser Implementierung der wissenschaftlichen Funktionen ist, dass man sehr leicht Wertetabellen erstellen kann. Das folgende Beispiel zeigt dies; zusĂ€tzlich wird ein Plot erstellt, was hier aber noch nicht nĂ€her erklĂ€rt wird.

v <- (0:24)
x <- pi * v / 12

y.sin <- sin(x)
print(x = y.sin, digits = 3)

y.cos <- cos(x)
print(x = y.cos, digits = 3)

plot(x, y.sin, "p")
plot(x, y.cos, "p")

Die x-Werte laufen von 0 bis 2 π im Abstand von π/12 (Zeile 1 und 2).

Die Ausgabe der y-Werte ist hier weniger spannend (Zeile 5 und 8); aussagekrÀftiger sind die Plots, die in Zeile 10 und 11 aus den berechneten Werten erzeugt werden und unten wiedergegeben sind.

Abbildung 1: Die erste Periode der Sinusfunktion berechnet an den oben definierten StĂŒtzstellen (Vektor x).Abbildung 1: Die erste Periode der Sinusfunktion berechnet an den oben definierten StĂŒtzstellen (Vektor x).

Abbildung 2: Die erste Periode der Kosinusfunktion berechnet an den oben definierten StĂŒtzstellen (Vektor x).Abbildung 2: Die erste Periode der Kosinusfunktion berechnet an den oben definierten StĂŒtzstellen (Vektor x).

Funktionen eines Vektors

In R sind zahlreiche Funktionen fĂŒr Vektoren aufrufbar, ohne weitere Pakete laden zu mĂŒssen. Die meisten dieser Funktionen erklĂ€ren sich selbst durch ihren Namen. Manche von ihnen berechnen einen einzigen Wert, manche einen Vektor (meist mit der LĂ€nge des Eingabe-Vektors).

Das folgende Skript zeigt die wichtigsten Beispiele:

v <- (1:5)          # 1 2 3 4 5

length(v)           # 5         LĂ€nge des Vektors

sum(v)              # 15        Summe der Komponenten
mean(v)             # 3         Mittelwert
var(v)              # 2.5       Varianz
sd(v)               # 1.5811    Standard-Abweichung (Wurzel aus der Varianz)

prod(v)             # 120       Produkt der Komponenten

diff(v)             # 1 1 1 1       Differenzen zwischen aufeinanderfolgenden Komponenten von v (die LĂ€nge von diff(v) ist um 1 kleiner als die von v)

cumsum(v)           #  1  3  6 10 15            Vektor, der die kumulierten Summen von v enthÀlt
cumprod(v)          #  1   2   6  24 120        Vektor, der die kumulierten Produkte von v enthÀlt
cummax(v)           #  1 2 3 4 5                Vektor, der die kumulierten Maxima von v enthÀlt
cummin(v)           #  1 1 1 1 1                Vektor, der die kumulierten Minima von v enthÀlt

min(v)              # 1     Minimum von v
max(v)              # 5     Maximum von v

Es lÀsst sich leicht feststellen, ob die oben berechnete Varianz die empirische Varianz ist oder nicht:

v <- (1:5)                      # 1 2 3 4 5
w <- (v - mean(v))^2            # 4 1 0 1 4

# Varianz:
sum(w)/length(v)                # 2

# empirische Varianz:
sum(w)/(length(v) - 1)          # 2.5

Mit var() wird also die empirische Varianz berechnet.

Das Skript, in dem die verschiedenen Funktionen zur Auswertung eines Vektors vorgestellt wurden, ist an einigen Stellen vielleicht nicht eindeutig, da mit einem sehr speziellen Vektor v <- (1:5) gearbeitet wurde. Daher wird das Skript nochmals fĂŒr einen unregelmĂ€ĂŸigen Vektor ausgefĂŒhrt:

v <- c(3, 8, 1, 3, 7, 5, 2, 8, 9, 6)            # 3 8 1 3 7 5 2 8 9 6

length(v)           # 10            LĂ€nge des Vektors

sum(v)              # 52            Summe der Komponenten
mean(v)             # 5.2           Mittelwert
var(v)              # 7.955556      empirische Varianz
sd(v)               # 2.820559      Standard-Abweichung (Wurzel aus der empirischen Varianz)

prod(v)             # 2177280       Produkt der Komponenten

diff(v)             # 5 -7  2  4 -2 -3  6  1 -3     Differenzen zwischen aufeinanderfolgenden Komponenten von v (die LĂ€nge von diff(v) ist um 1 kleiner als die von v)

cumsum(v)           #  3 11 12 15 22 27 29 37 46 52         Vektor, der die kumulierten Summen von v enthÀlt
cumprod(v)          #  3      24      24      72     504    2520    5040   40320  362880 2177280        Vektor, der die kumulierten Produkte von v enthÀlt
cummax(v)           #  3 8 8 8 8 8 8 8 9 9              Vektor, der die kumulierten Maxima von v enthÀlt
cummin(v)           #  3 3 1 1 1 1 1 1 1 1              Vektor, der die kumulierten Minima von v enthÀlt

min(v)              # 1     Minimum von v
max(v)              # 9     Maximum von v

Die Funktion diff() berechnet fĂŒr jeweils aufeinanderfolgende Komponenten die Differenz — aus dem Vektor v mit 10 Komponenten wird somit ein Vektor mit 9 Differenzen. Diese Funktion besitzt noch zwei weitere Argumente: lag (lag = Verzögerung, Zeitunterschied) und differences, die kurz erklĂ€rt werden sollen.

Der default-Wert fĂŒr lag ist gleich 1: es werden Differenzen direkter Nachbarn im Eingabe-Vektor berechnet — der Eingabe-Vektor wird dadurch um 1 verkĂŒrzt. Setzt man lag gleich 2, werden die Differenzen von ĂŒbernĂ€chsten Nachbarn genommen — jetzt wird der Eingabe-Vektor um 2 verkĂŒrzt. Und so weiter:

v <- c(3, 8, 1, 3, 7, 5, 2, 8, 9, 6)            # 3 8 1 3 7 5 2 8 9 6

diff(x = v)                         # 5 -7  2  4 -2 -3  6  1 -3
diff(x = v, lag = 2)                # -2 -5  6  2 -5  3  7 -2
diff(x = v, lag = 3)                # 0 -1  4 -1  1  4  4

Das Argument differences besitzt ebenfalls den default-Wert 1; differences gibt an, wie oft die Operation Differenzen bilden ausgefĂŒhrt werden soll. Ist also differences = 2 , so wird die Operation diff(v) zweimal nacheinander ausgefĂŒhrt:

v <- c(3, 8, 1, 3, 7, 5, 2, 8, 9, 6)            # 3 8 1 3 7 5 2 8 9 6

diff(x = v)                             # 5 -7  2  4 -2 -3  6  1 -3

diff(v, differences = 2)                # -12   9   2  -6  -1   9  -5  -4
diff(diff(v))                           # -12   9   2  -6  -1   9  -5  -4

diff(v, differences = 3)                # 21  -7  -8   5  10 -14   1
diff(diff(diff(v)))                     # 21  -7  -8   5  10 -14   1

Bei den hier vorgestellten Funktionen wurde suggeriert, dass sie in der Form f(x) angewendet werden mĂŒssen, wobei x ein Vektor ist. Dies ist zwar die Form, wie sie meist angewendet werden, aber viele Funktionen können allgemeiner verwendet werden, nĂ€mlich indem anstelle eines Vektors x beliebig viele Vektoren als Eingabewerte gesetzt werden. Dies wird durch die dot-dot-dot-Notation f(...) ausgedrĂŒckt. Wie diese Notation genau zu lesen ist und wie diese Funktionen dann angewendet werden, wird weiter unten am Beispiel der Funktionen all() und any() ausfĂŒhrlich erklĂ€rt. Ebenso ist in der Zusammenfassung unten eindeutig zu erkennen, welche Funktionen nur einen Vektor als Eingabewert haben und fĂŒr welche die dot-dot-dot-Notation zutrifft.

NĂ€here Betrachtung der Funktion mean()

Wegen ihrer Wichtigkeit soll die Funktion mean() etwas genauer vorgestellt werden. Diese Betrachtung soll zugleich zeigen:

  • Es lohnt sich immer einen Blick in die Dokumentation zu werfen, da viele Funktionen neben den hier besprochenen Eingabewerten noch weitere Argumente besitzen.
  • In den meisten FĂ€llen benötigt man diese zusĂ€tzlichen Argumente nicht — falls doch, ist es sehr aufwendig die zugehörige FunktionalitĂ€t selbst zu programmieren.

In der einfachsten Version wird mean() mit einem Argument x aufgerufen: x ist dabei ein Vektor, von dessen Komponenten der Mittelwert berechnet wird. Es wÀre falsch, die einzelnen Komponenten als einzelne Argumente einzugeben, wie das folgende Beispiel zeigt:

mean(1, 3)          # syntaktisch korrekt
# [1] 1             # aber das Ergebnis ist unerwartet

mean(c(1, 3))
# [1] 2

Der Funktionsaufruf in Zeile 1 ist zwar syntaktisch korrekt, fĂŒhrt aber nicht zu dem erwarteten Ergebnis. In der Dokumentation ist nachzulesen, wie mean() aufgerufen werden muss, nĂ€mlich mit:

mean(x, ...)

Dabei ist x das Objekt, von dem der Mittelwert berechnet werden soll — meist ein Vektor. Und hinter ... verbergen sich weitere Argumente, die man an mean() ĂŒbergeben kann — welche das sind, wird sofort erklĂ€rt.

Beim Aufruf mean(1, 3) wird die 1 interpretiert als x = 1 , woraus sich der Mittelwert 1 ergibt.

Dagegen zeigt Zeile 3 den — syntaktisch und semantisch — korrekten Aufruf von mean(): Der Mittelwert wird aus einem Vektor berechnet; um dies deutlicher auszudrĂŒcken, sollte man besser schreiben:

mean(x = c(1, 3))

Eine Funktion wie mean() könnte man leicht auf die Funktionen sum() und length() zurĂŒckfĂŒhren oder sogar in wenigen Rechenschritten selbst implementieren. Wenn möglich, sollte man aber immer auf die vordefinierten Funktionen zurĂŒckgreifen. Denn mean() besitzt — wie viele andere Funktionen — ein weiteres Argument na.rm, mit dem angeben kann, wie nicht vorhandene Werte (NA, also not available) behandelt werden sollen. Das folgende Beispiel zeigt dies fĂŒr mean():

v <- (1:5)
v <- c(v, NA)

length(v)
# [1] 6

v
# [1]  1  2  3  4  5 NA

mean(x = v, na.rm = TRUE)
# [1] 3

mean(x = v, na.rm = FALSE)
# [1] NA

mean(x = v)
# [1] NA

Werden nicht zugÀngliche Werte (NA) in die Berechnung mit aufgenommen, ist der Mittelwert nicht eindeutig definiert und wird dann auch mit NA angegeben (Zeile 13 und 14). Mit dem Argument na.rm lÀsst sich dies steuern; man sieht auch, dass der default-Wert von na.rm gleich FALSE ist (Zeile 16 und 17).

Die Funktion mean() besitzt noch ein weiteres Argument, das nĂŒtzlich sein kann, um auszuwertende Daten aufzubereiten: Oft enthalten lange Messreihen sogenannte Ausreisser, die man nicht in die Auswertung aufnehmen möchte. Mit dem Argument trim lĂ€sst sich steuern, welcher Prozentsatz an Daten an beiden Seiten aus dem Vektor x entfernt werden. Besitzt x etwa 10 Komponenten und wird trim = 0.1 gesetzt, so wird der kleinste und grĂ¶ĂŸte Wert von x beseitigt und dann erst der Mittelwert berechnet:

v <- (1:8)

mean(x = v)
# [1] 4.5

w <- c(0, v, 10)

mean(x = w)
# [1] 4.6

mean(x = w, trim = 0.1)
# [1] 4.5

mean(x = w, trim = 0.09)
# [1] 4.6

Zur ErklÀrung:

Zeile 3 und 4: Der Mittelwert des Vektors v ist (1 + 2 + ... 8) / 8 = 4.5. Die Messwerte liegen symmetrisch um den Mittelwert.

Zeile 6 bis 9: Der Vektor w erweitert den Vektor um die Zahlen 0 und 10; die Messwerte liegen jetzt nicht mehr symmetrisch um den Mittelwert — der Mittelwert ist (0 +1 + 2 + ... 8 + 10) / 10 = 4.6.

Zeile 11 und 12: Durch die Angabe von trim = 0.1 werden 0 und 10 aus w entfernt; der Mittelwert stimmt wieder mit dem Mittelwert von v ĂŒberein.

Zeile 14 und 15: Ist trim kleiner als 0.1, wird keine Komponente aus w entfernt; der Mittelwert ist wieder gleich 4.6.

Funktionen von zwei oder mehreren Vektoren

Bisher wurden Funktionen besprochen, die einen Vektor verarbeiten — und zusĂ€tzliche Argumente haben können. In diesem Unterabschnitt werden einige Funktionen vorgestellt, die zwei oder beliebig viele Vektoren verarbeiten — und wiederum zusĂ€tzliche Eingabewerte haben können:

  1. Die Funktionen pmin() und pmax(); dabei steht p fĂŒr parallel.
  2. Das Skalarprodukt zweier Vektoren
  3. Kovarianz und Korrelationskoeffizient
  4. Mengen-Operationen.

Die Funktionen pmin() und pmax()

Die Funktionen pmin() und pmax() berechnen das parallele Minimum oder Maximum mehrerer Vektoren; mit parallel ist gemeint, dass fĂŒr jede Komponente alle Eingabe-Vektoren untersucht werden und aus allen entsprechenden Komponenten das Minimum beziehungsweise Maximum ausgewĂ€hlt wird:

v <- (1:9)
w <- (9:1)

pmin(v, w)          # 1 2 3 4 5 4 3 2 1
pmax(v, w)          # 9 8 7 6 5 6 7 8 9

Stimmen die Vektoren in ihrer LĂ€nge nicht ĂŒberein, werden die kĂŒrzeren Vektoren solange wiederholt bis die LĂ€nge des lĂ€ngsten Vektors erreicht ist:

v <- 1:3
w <- 9:1

pmin(v, w)          # 1 2 3 1 2 3 1 2 1
pmax(v, w)          # 9 8 7 6 5 4 3 2 3

Dass man pmin() und pmax() mit beliebig vielen Vektoren aufrufen kann, zeigt das folgende Skript:

u <- rep(4, times = 9)
v <- 1:9
w <- 9:1

pmin(u, v, w)               # 1 2 3 4 4 4 3 2 1
pmax(u, v, w)               # 9 8 7 6 5 6 7 8 9

Das Skalarprodukt zweier Vektoren

Eine der am hĂ€ufigsten benötigten Operationen im Zusammenhang mit Vektoren ist das Skalarprodukt (oder inneres Produkt). Abbildung 3 zeigt die Formel fĂŒr zwei n-dimensionale Vektoren.

Abbildung 3: Formel zur Berechnung des Skalarproduktes fĂŒr zwei n-dimensionale Vektoren.Abbildung 3: Formel zur Berechnung des Skalarproduktes fĂŒr zwei n-dimensionale Vektoren.

Mit Hilfe von R kann es mit Hilfe der punktweisen Multiplikation zweier Vektoren und anschließender Addition der Komponenten realisiert werden — hier ein Beispiel fĂŒr den Fall von 3 Dimensionen:

u <- c(1, 3, 5) v <- c(2, 0, -2)

sum(u * v) # -8

Diese Art der Berechnung des Skalarproduktes kann aber leicht zu unerwarteten Ergebnissen fĂŒhren: Stimmen die LĂ€ngen der Vektoren nicht ĂŒberein, wird der kĂŒrzere Vektor solange wiederholt bis beide LĂ€nge ĂŒbereinstimmen (recycling-Mechanismus). Die Berechnung des Skalarproduktes mittels sum(u * v) liefert dann ein anderes Ergebnis als man in der Mathematik erwartet: dort wĂŒrde man das Skalarprodukt als nicht definiert betrachten oder den kĂŒrzeren Vektor mit Nullen auffĂŒllen.

Im Zusammenhang mit der Matrizenmultiplikation (siehe Matrizen in R: der Datentyp matrix) wird eine weitere Möglichkeit vorgestellt, das Skalarprodukt zweier Vektoren zu berechnen. Es nutzt die Matrizenmultiplikation %*% (das Skalarprodukt ist ja lediglich ein Spezialfall davon) und testet damit automatisch, ob die LĂ€ngen der Vektoren ĂŒbereinstimmen.

u <- c(1, 3, 5)
v <- c(2, 0, -2)

u %*% v         # -8

w <- rep(x = 1, times = 2)

u %*% w         # Fehlermeldung
# Error in u %*% w : non-conformable arguments

Der Nachteil dieser Art der Berechnung des Skalarproduktes ist, dass der RĂŒckgabewert von u %*% w eine Matrix ist — hier der Spezialfall einer 1 × 1-Matrix, also eigentlich einer Zahl.

Man kann daher folgende Empfehlungen aussprechen:

  • Das Skalarprodukt sollte man nur mit Hilfe von sum(u * v) zu berechnen, wenn man sich sicher ist, dass die beiden Vektoren u und v identische LĂ€ngen haben.
  • Mit u %*% w sollte man das Skalarprodukt berechnen, wenn man ein wenig mit Matrizen vertraut.

Kovarianz und Korrelationskoeffizient

Die Berechnung der Kovarianz und des Korrelationskoeffizienten wird hier nur kurz vorgefĂŒhrt; ausfĂŒhrliche ErlĂ€uterungen finden sich in der Dokumentation im Paket stats unter cor.

Im folgenden Beispiel werden drei Vektoren definiert, wobei der zweite und dritte Vektor eindeutig aus dem ersten hervorgehen:

  • v1 hĂ€ngt linear von v ab — der Korrelationskoeffizient zwischen v und v1 muss 1 oder -1 betragen,
  • v2 hĂ€ngt quadratisch von v ab — der Korrelationskoeffizient zwischen v und v2 kann nicht gleich 1 oder -1 sein.
v <- (1:6)

v1 <- -2 * v + 3
v1
# [1]  1 -1 -3 -5 -7 -9

v2 <- v^2
v2
# [1]  1  4  9 16 25 36

# Zusammenhang zwischen v und v1:
cov(x = v, y = v1)
# [1] -7
cor(x = v, y = v1)
# [1] -1

# Zusammenhang zwischen v und v2:

cov(x = v, y = v2)
# [1] 24.5
cor(x = v, y = v2)
# [1] 0.9789173

Mengen-Operationen

Im Paket base unter sets sind die in R verfĂŒgbaren Mengen-Operationen beschrieben. Welche Aufgaben diese Funktionen erfĂŒllen, sollten sich sofort aus ihrem Namen erschließen — sie werden hier nicht sehr ausfĂŒhrlich erklĂ€rt:

Funktion Beschreibung
is.element(el, set) Testet, ob el in der Menge set enthalten ist
setequal(x, y) Testet, ob die beiden Mengen x und y identisch sind
union(x, y) Berechnet die Vereinigungsmenge der Mengen x und y
intersect(x, y) Berechnet die Durchschnittsmenge der Mengen x und y
setdiff(x, y) Berechnet die Differenz der Mengen x und y (Beachte: die Operation ist nicht symmetrisch bei Vertauschung der Argumente)

Um diese Funktionen anwenden zu können, muss man nur wissen, wie Vektoren als Mengen interpretiert werden:

  1. Man muss keine eigene Operation anwenden, um in eine der beschriebenen Funktionen eine Menge einzugeben.
  2. Es reicht, Mengen als Vektoren einzugeben, denn Vektoren werden bei der Weiterverarbeitung als Mengen interpretiert.
  3. Da in R nicht zwischen Zahlen und Vektoren unterschieden wird, gibt es auch keine Unterscheidung zwischen Element und Menge.

Der zweite Punkt bedeutet, dass mehrfach vorkommende Elemente ignoriert werden und man nicht auf die Reihenfolge der Elemente achten muss. Allerdings kann sich bei der Ausgabe dann eine ungewöhnliche Reihenfolge ergeben (und man selbst sortieren sollte).

Das folgende Beispiel zeigt dies:

setequal(x = c(1, 2, 1), y = (1:2))
# [1] TRUE

setequal(x = c(1, 2, 1), y = (2:1))
# [1] TRUE

m <- union(x = c(1, 3, 5), y = c(2, 4, 6))
m
# [1] 1 3 5 2 4 6
# Die Ausgabe erfolgt unsortiert

m <- union(x = c(1, 3, 5, 1), y = c(2, 4, 6))
m
# [1] 1 3 5 2 4 6
# Aber doppelte Komponenten werden unterdrĂŒckt

Man erkennt:

  • Das erste Argument in setequal() enthĂ€lt das Element 1 doppelt: fĂŒr die Gleichheit der Mengen ist dies unerheblich (Zeile 1).
  • Das zweite Argument in setequal() wird mit unterschiedlichen Reihenfolgen definiert: auch dies ist unerheblich (Zeile 1 und 4).
  • Eine Ergebnismenge ist nicht sortiert (Zeile 7 bis 9).
  • Aber in der Ergebnismenge werden doppelte Komponenten unterdrĂŒckt (Zeile 12 bis 14).

Den dritten Punkt oben kann man an der Funktion is.element() erlĂ€utern: Die Eingabewerte der Funktion is.element(el, set) suggerieren, dass getestet wird, ob ein Element el in der Menge set enthalten ist. Man kann hier fĂŒr el aber auch wieder einen Vektor eingeben und es wird fĂŒr jede Komponente getestet, ob sie in set enthalten ist. Der RĂŒckgabewert ist dann ein logischer Vektor mit der LĂ€nge von el:

m <- (1:6)
u <- c(1, 3, 5)

is.element(el = 1, set = u)
# [1] TRUE

is.element(el = 2, set = u)
# [1] FALSE

is.element(el = u, set = m)
# [1] TRUE TRUE TRUE

Funktionen zum Sortieren von Vektoren und verwandte Funktionen

Ein zentrales Thema beim Umgang mit Vektoren ist immer das Sortieren von Vektoren. Wer vor etwa 40 Jahren gelernt hat zu programmieren, hat vermutlich die meiste Zeit damit verbracht, Sortier-Algorithmen zu implementieren. Heute ist dies nicht mehr nötig, da zu jeder Programmiersprache umfangreiche Bibliotheken mit Sortier-Algorithmen existieren. In diesem Unterabschnitt werden einige Funktionen vorgestellt, mit denen Vektoren sortiert oder verwandte Aufgaben erledigt werden können. Vorgestellt werden die Funktionen, die in der folgenden Tabelle aufgelistet sind:

Funktion Beschreibung
rev(x) Erzeugt einen Vektor mit umgekehrter Anordnung der Komponenten wie im Vektor x (rev = reverse)
sort(x, decreasing = FALSE, na.last) Sortieren eines Vektors (besitzt zahlreiche Zusatz-FunktionalitÀten)
is.unsorted(x, na.rm = FALSE, strictly = FALSE) Abfragen, ob ein Vektors x noch nicht sortiert ist.
unique(x) Entfernt mehrfach vorkommende Komponenten aus einem Vektor x
duplicated(x) Untersucht alle Komponenten von x und gibt an, ob ihr Wert schon einmal im Vektor vorgekommen ist.
order( ... , na.last = TRUE, decreasing = FALSE) Gibt die Indizes der sortierten Komponenten an (wo steht die kleinste Komponente, wo steht die zweit-kleinste Komponente und so weiter)
rank(x) Angabe der Rangfolge: zu jeder Komponente wird angegeben, welche Rangfolge sie im Vektor x hat, wenn man ihn sortieren wĂŒrde.

Die Funktion rev()

Die Funktion rev(x) sorgt dafĂŒr, dass ein eingegebener Vektor x umgedreht wird; die AbkĂŒrzung rev steht natĂŒrlich fĂŒr reverse.

v <- (1:9)
v
# [1] 1 2 3 4 5 6 7 8 9

v.rev <- rev(x = v)
v.rev
# [1] 9 8 7 6 5 4 3 2 1

Die Funktion sort()

Beim Sortieren eines Vektors greift man auf Komponenten des Vektors zu: sie werden entweder aufsteigend oder absteigend angeordnet — allerdings gibt es noch weitere Spitzfindigkeiten. Das folgende Skript zeigt die einfachsten Anwendungen der Funktion sort():

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

v.default <- sort(x = v)
v.default
# [1] 1 1 2 2 3 3 4 5 6 6

v.decr <- sort(x = v, decreasing = TRUE)
v.decr
# # [1] 6 6 5 4 3 3 2 2 1 1

v.asc <- sort(x = v, decreasing = FALSE)
v.asc
# [1] 1 1 2 2 3 3 4 5 6 6

Zur ErklÀrung:

Zeile 1: Ein unregelmĂ€ĂŸiger Vektor wird als v abgespeichert.

Zeile 3: Um das default-Verhalten von sort() zu untersuchen, wird nur der Vektor v ĂŒbergeben.

Zeile 4 und 5: Die Ausgabe zeigt, dass per default aufsteigend sortiert wird.

Zeile 7: Das Argument decreasing erwartet einen logischen Wert und bestimmt ausdrĂŒcklich die Sortier-Reihenfolge. In v.decr wird v absteigend sortiert.

Zeile 11: In v.asc wird v aufsteigend sortiert. Da dies das default-Wert ist, kann man decreasing = FALSE auch weglassen.

Die Funktion sort() besitzt ein weiteres Argument, das einen logischen Wert erwartet: na.last. Damit lĂ€sst sich bestimmen, ob NA-Werte am Anfang oder am Ende des sortierten Vektors gestellt werden — ihre Anzahl bleibt unverĂ€ndert.

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

v.default <- sort(x = v)
v.default
# [1] 1 1 2 2 3 3 4 5 6 6

v.last <- sort(x = v, na.last = TRUE)
v.last
# [1]  1  1  2  2  3  3  4  5  6  6 NA NA NA

v.first <- sort(x = v, na.last = FALSE)
v.first
# [1] NA NA NA  1  1  2  2  3  3  4  5  6  6

Man erkennt: wenn das Argument na.last nicht gesetzt wird (also selbst gleich NA ist), werden NA-Werte aus dem zu sortierenden Vektor entfernt.

Bisher wurden nur Zahlen sortiert. Da logische Werte intern als Zahlen gespeichert werden und auch fĂŒr Zeichen eine lexikographische Anordnung existiert, erwartet man, dass auch Vektoren mit logischen Werten beziehungsweise Zeichen sortiert werden können:

v <- c(TRUE, FALSE, TRUE, FALSE)
v.log <- sort(v)
v.log
# [1] FALSE FALSE  TRUE  TRUE

v <- c('a', 'c', 'b')
v.char <- sort(v)
v.char
# [1] "a" "b" "c"

Man erkennt, dass per default wieder aufsteigend sortiert wird.

Die Sortierung von Zeichenketten kann zu zahlreichen Problemen fĂŒhren (Behandlung von Sonderzeichen, Verwendung unterschiedlicher Kodierungen). Mehr zu diesem Thema findet man im Paket base unter Comparison.

Bekanntlich gibt es mehrere Sortier-Algorithmen, die je nach Anwendung ihre Vor- und Nachteil haben (kurzer oder langer Vektor, weitgehend vorsortierter Vektor) und sich deutlich in der Rechenzeit unterscheiden können. In R sind mehrere Sortier-Algorithmen implementiert und die Funktion sort() erlaubt mit Hilfe des Argumentes method einen oder mehrere davon auszuwĂ€hlen. Dieses Thema soll hier aber nicht vertieft werden; eine ausfĂŒhrliche Beschreibung findet man in der Dokumentation zu sort().

---

Bei vielen Anwendungen muss man nur feststellen, ob ein Vektor v sortiert ist oder nicht. Da das Sortieren bei langen Vektoren viel Rechenzeit beansprucht, wĂ€re es unsinnig, dazu v zuerst zu sortieren und dann zu vergleichen, ob der sortierte Vektor mit v ĂŒbereinstimmt.

Sehr viel weniger Rechenzeit beansprucht die Funktion is.unsorted(); die Funktion besitzt drei Argumente:

  • x: der Vektor, der untersucht werden soll.
  • na.rm: ein logischer Wert, der angibt, ob NA-Werte vor der Untersuchung beseitigt werden sollen. Der default-Wert ist na.rm = FALSE .
  • strictly: ein logischer Wert, der angibt, ob auf strikte Anordnung untersucht werden soll. Der default-Wert ist strictly = FALSE .

Der RĂŒckgabewert von is.unsorted() ist ein logischer Wert.

Das folgende Skript zeigt einige Anwendungen von is.unsorted():

v <- c(1, 1, 2, NA, 3)

is.unsorted(x = v)
# [1] NA

is.unsorted(x = v, na.rm = TRUE)
# [1] FALSE

is.unsorted(x = v, strictly = TRUE)
# [1] NA

is.unsorted(x = v, na.rm = TRUE, strictly =  TRUE)
# [1] TRUE

Die Funktion is.unsorted() besitzt kein Argument, das die Sortier-Reihenfolge festlegt, das heißt man kann mit ihr nur die aufsteigende Sortierung untersuchen (fĂŒr absteigende Sortierung muss man die Funktion rev() einsetzen).

Die Funktion unique()

Um besser zu sehen, welche Elemente in einem Vektor enthalten sind, kann man sich aus einem gegebenen Vektor v alle mehrfach vorkommenden Elemente entfernen lassen; dies geschieht mit Hilfe der Funktion unique():

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

v.uni <- unique(v)
v.uni
# [1] 1 5 2 4 6 3

sort(v.uni)
# [1] 1 2 3 4 5 6
  • Oben wird ein Vektor v erzeugt, der etwa das Ergebnis beim 10-maligen WĂŒrfeln sein könnte. (Zeile 1).
  • Mit unique(v) wird ein Vektor erzeugt, aus dem alle Elemente entfernt werden, sobald sie zum zweiten Mal auftreten (Zeile 3 bis 5) .
  • LĂ€sst man sich diesen Vektor sortiert ausgeben, so sieht man auf einen Blick, dass tatsĂ€chlich alle möglichen Zahlen gewĂŒrfelt wurden (Zeile 7; man hĂ€tte dies auch mit length() feststellen können, aber dann sieht man nicht welche Zahl fehlt, falls length(v.uni) < 6 ).

Man kann die Wirkung von unique() auch anders interpretieren. In einem Vektor darf jeder Wert beliebig oft vorkommen; dagegen darf es bei der Angabe der Elemente einer Menge keine Wiederholungen geben. In diesem Sinne verwandelt unique() einen Vektor in eine Menge; aber erst ihre sortierte Ausgabe zeigt die typische Anordnung der Elemente.

Die Funktion duplicated()

Verwandt mit der Funktion unique() ist die Funktion duplicated(): sie erhĂ€lt als Eingabewert einen Vektor x und erzeugt einen logischen Vektor, der fĂŒr jede Komponente von x angibt, ob sie schon einmal im Vektor x vorgekommen ist.

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

v.dupl <- duplicated(x = v)
v.dupl
# [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

Die Funktion order()

Bei manchen Anwendungen möchte man nicht den sortierten Vektor bekommen, sondern man möchte wissen, an welcher Stelle (Index) der kleinste, der zweit-kleinste Wert und so weiter steht. Diese Information liefert die Funktion order():

v <- c(1, 5, 3)

v.ord <- order(v)
v.ord
# [1] 1 3 2

Die kleinste Zahl 1 in v steht an erster Stelle, die nĂ€chst grĂ¶ĂŸere Zahl 3 steht an dritter Stelle, die grĂ¶ĂŸte Zahl 5 steht an zweiter Stelle; der Aufruf von order(v) liefert daher den Vektor (1, 3, 2).

Um zu sehen, wie order() bei einer Folge mit Wiederholungen arbeitet, wird das Beispiel von oben verwendet:

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

v.ord <- order(v)
v.ord
# [1]  1  5  3 10  7  8  4  2  6  9
  • Die kleinste Zahl ist 1: sie steht an 1. und 5. Stelle. Der Vektor order(v) startet mit 1 und 5.
  • Die Zahl 2 steht an 3. und 10. Stelle. Nach 1 und 5 folgen 3 und 10.
  • Die Zahl 3 steht an 7. und 8. Stelle, und so weiter. Die nĂ€chsten EintrĂ€ge sind 7 und 8.

Man kann den Vektor v.ord , also (1, 5, 3, 10, 7, 8, 4, 2, 6, 9), auch so lesen: Nimmt man aus dem Vektor v nacheinander

  • die 1. Komponente
  • die 5. Komponente,
  • die 3. Komponente
  • die 10. Komponente und so weiter,

so erhÀlt man den ausfsteigend sortierten Vektor zu v, also (1, 1, 2, 2, 3, 3, 4, 5, 6, 6).

Mit dem weiteren Argument decreasing = TRUE kann man die Sortier-Reihenfolge umdrehen und dafĂŒr die Indizes erzeugen:

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

v.ord.dec <- order(v, decreasing = TRUE)
v.ord.dec
# [1]  6  9  2  4  7  8  3 10  1  5
  • Im Vektor v ist 6 die grĂ¶ĂŸte Zahl, sie steht an 6. und 9. Stelle.
  • Die zweit-grĂ¶ĂŸte Zahl ist 5 an 2. Stelle und so weiter.

Man kann die Funktion order() daher auch folgendermaßen beschreiben: Der Vektor der Indizes einer Zahlenfolge, also ein Vektor der Form (1:n) wird derart neu geordnet, wie es die Anordnung in der Zahlenfolge vorschreibt (ansteigende Anordnung beim default-Wert decreasing = FALSE und absteigende Anordnung bei decreasing = TRUE ). Somit erzeugt order() eine spezielle Permutation des Index-Vektors.

Die Funktion rank()

Verwandt mit der Funktion order() ist rank(): mit dieser Funktion lÀsst sich feststellen, welche Rangfolge eine Komponente in einem Vektor einnimmt, wenn der Vektor sortiert wird. Im Fall, dass jeder Wert in den Komponenten des Vektors nur einmal vorkommt, ist die Rangfolge eindeutig bestimmt; kommen Wiederholungen vor (in der Dokumentation werden sie als ties bezeichnet), kann man eine aus mehreren Strategien auswÀhlen, wie die Rangfolge bestimmt wird. Die Strategie wird mit Hilfe des Argumentes ties.method ausgewÀhlt.

Die Funktion rank() wird fĂŒr das Beispiel oben mit dem Vektor (1, 5, 2, 4, 1, 6, 3, 3, 6, 2) erklĂ€rt, fĂŒr den eine Rangfolge gebildet werden soll. Bei aufsteigender Sortierung ist 1 der kleinste Wert; und da 1 zweimal vorkommt, belegt die 1 den 1. und 2. Rang. Die 2 kommt ebenfalls zweimal vor, belegt also den 3. und 4. Rang. Die folgende Tabelle zeigt das Ergebnis der Rangfolgen-Bildung:

Plazierung Wert der Komponente mittlerer Rang
Rang 1 1 1.5
Rang 2 1 1.5
Rang 3 2 3.5
Rang 4 2 3.5
Rang 5 3 5.5
Rang 6 3 5.5
Rang 7 4 4.0
Rang 8 5 8.0
Rang 9 6 9.5
Rang 10 6 9.5

Die Tabelle zeigt die Strategie "average", die bei Wiederholungen den Mittelwert der Rangfolge berechnet. Das folgende Skript zeigt, wie der Vektor der Rangfolgen berechnet wird; die Strategie "average" muss dabei nicht angegeben werden, da sie der default-Wert fĂŒr ties.method ist:

v <- c(1, 5, 2, 4, 1, 6, 3, 3, 6, 2)
  
v.r <- rank(x = v)
v.r
# [1] 1.5 8.0 3.5 7.0 1.5 9.5 5.5 5.5 9.5 3.5

v.r.min <- rank(x = v, ties.method = "min")
v.r.min
# [1] 1 8 3 7 1 9 5 5 9 3

In Zeile 7 wurde als Strategie "min" ausgewĂ€hlt — der Unterschied zur Strategie "average" ist leicht festzustellen.

Es gibt kein Argument, das zwischen auf- und absteigender Sortier-Reihenfolge unterscheiden kann. Weitere Informationen, insbesondere zu weiteren Strategien und zur Behandlung von NA finden sich in der Dokumentation.

Vektoren und BedingungsprĂŒfungen

Im Abschnitt Ausblick auf Anwendungen mit Vektoren im Kapitel EinfĂŒhrung in R: Logische Werte wurde schon ein Beispiel gezeigt, das erahnen lĂ€sst, dass sich durch die Kombination von Vektoren und logischen Werten wichtige Funktionen zur Analyse von Vektoren bilden lassen. Hier wird gezeigt, wie die dort angedeuteten Funktionen realisiert werden.

Folgende Funktionen werden in diesem Unterabschnitt besprochen:

  1. subset(x, subset) : Auswahl eines Teilvektors aus einem Vektor x; ausgewĂ€hlt werden diejenigen Komponenten, die eine Bedingung subset erfĂŒllen. Der RĂŒckgabewert ist ein Vektor (Modus wie x).
  2. which(x) : Untersucht den logischen Vektor x und gibt die Indizes der Komponenten mit Wert TRUE an. RĂŒckgabewert ist ein Vektor von ganzen Zahlen.
  3. all(x) und any(x) : Gibt an, ob alle Komponenten im logischen Vektor x gleich TRUE sind beziehungsweise ob es mindestens eine Komponente gibt, die gleich TRUE ist. RĂŒckgabewert ist jeweils ein logischer Wert.

Die Funktion subset()

Oft mĂŒssen aus einem Vektor nur bestimmte Komponenten ausgewĂ€hlt werden, wobei durch einen logischen Ausdruck festgelegt wird, welche Komponenten dies sind; die Funktion subset() erledigt diese Aufgabe.

Sie erwartet zwei Argumente:

  • den Vektor x, von dem ein Teilvektor gebildet werden soll, und
  • einen logischen Ausdruck subset, der beschreibt, welche Komponenten ausgewĂ€hlt werden sollen.

Der RĂŒckgabewert ist ein (meist verkĂŒrzter) Vektor, in dem alle Komponenten die Bedingung subset erfĂŒllen.

Damit verhÀlt sich subset() wie der direkte Zugriff auf Komponenten eines Vektors mit einem logischen Ausdruck (was oben besprochen wurde, etwa wie v[v < 5] ). Der Aufruf von subset() ist aber deutlich leichter zu lesen.

Ein Beispiel, bei dem aus dem Vektor v diejenigen Komponenten ausgewĂ€hlt werden, die grĂ¶ĂŸer sind als drei und zugleich ungerade sind (Division durch 2 ergibt Rest 1):

v <- (1:9)              # 1 2 3 4 5 6 7 8 9

w <- subset(x = v, subset = (v > 3) & (v %% 2 == 1))            #  5 7 9

Die Klammern im zweiten Argument von subset() dienen lediglich dazu, den logischen Ausdruck leichter lesbar zu machen und könnten weggelassen werden.

Nachdem oben Beispiele wie

v <- (1:9)
v1 <- v[v < 5]          # 1 2 3 4

diskutiert wurden, sollte klar sein, wie bei einem Aufruf von subset(x, subset) die Auswahl der Komponenten eines Vektors x mit Hilfe einer BedingungsprĂŒfung erfolgt:

  • FĂŒr jede Komponente von x wird ĂŒberprĂŒft, ob sie die Bedingung subset erfĂŒllt,
  • falls ja, verbleibt sie im Vektor, falls nein, wird sie aus dem Vektor entfernt,
  • der so neu gebildete Vektor ist der RĂŒckgabewert; der Vektor x bleibt durch diese Operation unverĂ€ndert.

Die Funktion which()

Mit der Funktion which() kann mit Hilfe einer BedingungsprĂŒfung auf die Indizes eines Vektors zugegriffen werden — also nicht auf die Komponenten selbst. Der RĂŒckgabewert ist dann ein Vektor mit denjenigen Indizes, fĂŒr die die Bedingung erfĂŒllt ist.

Das folgende Beispiel demonstriert den Unterschied zwischen dem Zugriff auf die Komponenten und den Zugriff auf die Indizes:

vec <- c(1, 2, 1, 0, 1)
vec_1 <- vec[vec == 1]          # Zugriff auf die Komponenten von vec
vec_1                           # 1 1 1

ind_1 <- which(vec == 1)        # Zugriff auf die Indizes von vec
ind_1                           # 1 3 5

Zeile 2 und 3: Der Vektor vec_1 entsteht aus dem Vektor vec, indem alle Komponenten weggelassen werden, die ungleich 1 sind; vec_1 ist also kĂŒrzer als vec und besitzt nur die EintrĂ€ge 1.

Zeile 5 und 6: Der Vektor ind_1 besitzt dieselbe LÀnge wie vec_1; seine EintrÀge sind aber die Indizes des Vektors vec, an denen dieser den Eintrag 1 besitzt.

Vektoren wie ind_1 aus dem Skript oben werden als Indexvektoren bezeichnet; im Kapitel Matrizen in R: der Datentyp matrix werden sie detaillierter vorgestellt.

Die Funktionen all() und any()

In der einfachsten Version untersuchen die Funktionen all() und any() einen logischen Vektor. Im Allgemeinen kann man mit ihnen:

  • durch geschickten Einsatz einer BedingungsprĂŒfung Vektoren von beliebigem Modus untersuchen,
  • beliebig viele logische Vektoren gleichzeitig untersuchen.

ZunÀchst der einfachste Fall:

Ein logischer Vektor besteht aus den logischen Werten TRUE und FALSE.

FĂŒr die Funktion all() gilt:

Sind alle Komponenten eines logischen Vektors v.log gleich TRUE, so gibt all(v.log) den Wert TRUE zurĂŒck, andernfalls FALSE.

FĂŒr die Funktion any() gilt:

Ist eine oder sind mehrere Komponenten eines logischen Vektors v.log gleich TRUE, so gibt any(v.log) den Wert TRUE zurĂŒck, andernfalls FALSE.

Das folgende Beispiel zeigt, wie dies aussehen kann:

v1 <- vector(mode = "logical", length = 3)
v1[] <- FALSE

v2 <- !v1

v3 <- v1
v3[1] <- TRUE

v4 <- !v3

v1
# [1] FALSE FALSE FALSE

v2
# [1] TRUE TRUE TRUE

v3
# [1]  TRUE FALSE FALSE

v4
# [1] FALSE  TRUE  TRUE

all(v1)         # FALSE
all(v2)         # TRUE
all(v3)         # FALSE
all(v4)         # FALSE

any(v1)         # FALSE
any(v2)         # TRUE
any(v3)         # TRUE
any(v4)         # TRUE

---

Hat man einen Vektor mit beliebigem Modus gegeben, so kann man mit Hilfe einer BedingungsprĂŒfung, die auf jede Komponente angewendet wird, einen logischen Vektor erzeugen; dieser logische Vektor gibt dann an, welche Komponente die Bedingung erfĂŒllt und welche nicht.

Mit all() kann man untersuchen, ob die Bedingung fĂŒr alle Komponenten eines Vektors erfĂŒllt ist.

Mit any() kann man untersuchen, ob es eine Komponente (oder mehrere Komponenten) eines Vektors gibt, die die Bedingung erfĂŒllt.

v <- (1:5)
w <- (5:1)

v > w
# [1] FALSE FALSE FALSE  TRUE  TRUE

all(v > w)  
# [1] FALSE

any(v > w)
# [1] TRUE

Zur ErklÀrung:

Zeile 4: Sorgt dafĂŒr, dass ein logischer Vektor erzeugt wird, der komponentenweise angibt, ob die Bedingung v > w erfĂŒllt ist oder nicht. Dieser Vektor wird nicht abgespeichert, um ausdrĂŒcklich zu zeigen:

  • Man untersucht einen (oder mehrere) Vektor mit beliebigem Modus (hier Vektoren im Modus "numeric").
  • Der Vektor, auf den all() und any() angewendet werden, ist ein logischer Vektor.

Es ensteht somit ein logischer Vektor mit 5 Komponenten, der mit den Funktionen all() und any() untersucht wird (Zeile 7 und 10).

Zeile 7: Die untersuchte Bedingung ist nicht fĂŒr alle Komponenten gleichzeitig erfĂŒllt, daher liefert all() den Wert FALSE.

Zeile 10: Es gibt mindestens eine Komponente, die die angegebene Bedingung erfĂŒllt, also liefert any() den Wert TRUE.

---

Ein Blick in die Dokumentation von all() und any() zeigt, dass die bisherige Darstellung dieser beiden Funktionen nicht ganz richtig ist: Es wurde suggeriert, dass beide Funktionen einen Vektor als Eingabewert erhalten. In der Dokumentation steht aber:

all(..., na.rm = FALSE)
any(..., na.rm = FALSE)
  1. Das Argument na.rm mit dem default-Wert FALSE wird hier nicht noch einmal erklÀrt (siehe die Diskussion der Funktion mean() weiter oben).
  2. Das Argument ... bedeutet: Den Funktionen all() und any() können beliebig viele logische Vektoren ĂŒbergeben werden; sie werden aneinandergehĂ€ngt und darauf wird all() beziehungsweise any() angewendet.

Das folgende Beispiel zeigt dies fĂŒr zwei Eingabe-Vektoren:

v <- (1:5)
w <- -(5:1)

all(v > 0, w > 0)
# [1] FALSE

any(v > 0, w > 0)
# [1] TRUE

Der Index-Vektor

Das Problem, auf eine oder mehrere Komponenten eines Vektors zugreifen zu mĂŒssen, ist bei der Verarbeitung von Daten, die als Vektoren gespeichert sind, allgegenwĂ€rtig. Sowohl bei der Beschreibung von Vektoren im letzten Kapitel und bei den hier beschriebenen Anwendungen von Vektoren wurden dafĂŒr mehrere Möglichkeiten vorgestellt. Das Problem, von einem Vektor eine gewisse Teilmenge seiner Komponenten auszuwĂ€hlen, soll hier nochmal etwas abstrakter unter Zuhilfenahme des Begriffs des Index-Vektors geschehen. Die Beschreibung weiterer zusammengesetzter Datentypen wird zeigen, dass das Konzept des Index-Vektors nicht nur auf Vektoren beschrĂ€nkt ist.

Allgemein versteht man unter einem Index-Vektor einen Vektor, mit dem man auf eine Teilmenge der Komponenten eines Vektors -v zugreifen kann. Da der Vektor v indiziert ist mit den Indizes 1, 2,..., length(v), entspricht einer Teilmenge der Komponenten von v einer Teilmenge der Indizes.

In R gibt es vier Möglichkeiten, wie man einen Index-Vektor zu einem Vektor v bilden kann:

  1. Vektor der betreffenden Indizes; die Indizes sind positive, ganze Zahlen mit den möglichen Werten 1, 2,..., length(v).
  2. Vektor mit negativen Indizes: die Komponenten mit den entsprechenden Indizes werden aus dem Vektor v entfernt.
  3. Ein logischer Vektor mit der LĂ€nge von v: TRUE steht dafĂŒr, dass die Komponente ĂŒbernommen wird und FALSE dafĂŒr, dass sie verworfen wird; ist der logische Vektor kĂŒrzer als v, wird der recycling-Mechanismus angewendet.
  4. Ist im Vektor das Attribut names gesetzt, kann auch ĂŒber Vektoren von Zeichenketten auf die Komponenten von v zugegriffen werden (anstelle des Index wird hier der Name zum Zugriff verwendet).

Diese Kurzbeschreibung der vier Möglichkeiten, wie man einen Index-Vektors bildet, sollte eigentlich genĂŒgen — alle vier Möglichkeiten wurden bereits vorgestellt, sie wurden nur nicht unter ihrem gemeinsamen Aspekt betrachtet, nĂ€mlich eine Teilmenge aus den Komponenten eines Vektors auszuwĂ€hlen. Unter diesem Aspekt werden die vier Möglichkeiten nochmals kurz beschrieben.

1. Vektor der betreffenden Indizes

Im folgenden Skript ist der Vektor v = (1, 0, 1, 0) gegeben und es wird ein Index-Vektor gebildet, der diejenigen Komponenten von v auswÀhlt, die gleich 0 sind. Dazu gibt es mehrere Möglichkeiten.

Kennt man die Indizes, bei denen v == 0 , so kann man sie mit Hilfe der Funktion c() zum Index-Vektor iv.0 zusammenfassen:

v <- c(1, 0, 1, 0)

iv.0 <- c(2, 4)

v[iv.0]
# [1] 0 0

Zeile 1 und 3 sollten klar sein.

Zeile 5: Entscheidend zum VerstĂ€ndnis des Konzeptes Index-Vektor ist der Zugriff auf die Komponenten von v mit Hilfe des Index-Vektors iv.0. In den eckigen Klammern erwartet man vermutlich einen Index des Vektors v; ebenso kann ein Index-Vektor in die eckigen Klammern geschrieben werden. Der Vektor v wird an allen Komponenten ausgewertet, die der Index-Vektor iv.0 enthĂ€lt — und so wie der Vektor iv.0 definiert war (Zeile 3), ist v dort immer gleich null. Da iv.0 zwei Komponenten hat, wird die 0 zweimal ausgegeben (Zeile 6). Oder abstrakter formuliert: Ein Index-Vektor besteht aus einer Teilmenge der Indizes eines Vektors v und man kann damit auf die zugehörige Teilmenge der Komponenten von v zugreifen.

Kennt man die betreffenden Indizes nicht, kann man andere Funktionen zuhilfe nehmen, um die Indizes zu bestimmen — zum Beispiel die Funktion which(), wie das folgende Skript zeigt:

v <- c(1, 0, 1, 0)

iv.0 <- which(v == 0)
iv.0
# [1] 2 4

str(iv.0)
# int [1:2] 2 4

v[iv.0]
# [1] 0 0

Zur ErklÀrung:

Zeile 3 bis 5: Da v ein numerischer Vektor mit 4 Komponenten ist, verbirgt sich hinter v == 0 ein logischer Vektor mit (ebenfalls) 4 Komponenten. Der Vektor iv.0 gibt diejenigen Komponenten in v an, die den Wert 0 besitzen, also die zweite und vierte Komponente (siehe Ausgabe von iv.0 in Zeile 5). Die Werte von iv.0 sind also eine Teilmenge der Indizes des Vektors v.

Zeile 7 und 8: Die Ausgabe der Struktur von iv.0 zeigt, dass es sich um einen Vektor mit 2 Komponenten und den Werten 2 und 4 handelt.

Zeile 10 und 11: Der Zugriff auf v mit dem Index-Vektor iv.0 liefert zweimal die Ausgabe 0 — die ErklĂ€rung ist identisch wie zum Skript oben.

2. Vektor mit negativen Indizes

Den Index-Vektor iv.0 kann man auch bilden, indem man die erste und dritte Komponente streicht; dies geschieht mit negativen Indizes, wie im folgenden Skript zu sehen ist:

v <- c(1, 0, 1, 0)

iv.0 <- c(-1, -3)
iv.0
# [1] -1 -3

v[iv.0]
# [1] 0 0

Möchte man dies wie oben mit der Funktion which() erledigen, könnte dies folgendermaßen geschehen:

v <- c(1, 0, 1, 0)

iv.0 <- - which(v != 0)
iv.0
# [1] -1 -3

v[iv.0]
# [1] 0 0

Zeile 3: Es werden zunÀchst mit which() alle Indizes ausgewÀhlt, wo die Komponenten von v ungleich 0 sind; diese Indizes werden mit -1 multipliziert und dann im Vektor iv.0 abgespeichert.

Zeile 7: Greift man auf die durch den Index-Vektor iv.0 definierten Komponenten von v zu, erhÀlt man wieder zweimal die 0.

Logischer Vektor als Index-Vektor

Diese Möglichkeit, einen Index-Vektor zu definieren, ist schon in iv.0 <- which(v == 0) enthalten. Denn mit v == 0 wird ein logischer Vektor definiert, nÀmlich (FALSE, TRUE, FALSE, TRUE). Es ist jetzt gar nicht nötig, mit Hilfe der Funktion which() die Indizes von v in einem numerischen Vektor abzuspeichern; man kann sofort den logischen Vektor verwenden (Zeile 3):

v <- c(1, 0, 1, 0)

iv.0 <- v == 0
iv.0
# [1] FALSE  TRUE FALSE  TRUE

str(iv.0)
# logi [1:4] FALSE TRUE FALSE TRUE

v[iv.0]
# [1] 0 0

Da auf der rechten Seite von Zeile 3 ein logischer Vergleich steht (fĂŒr einen Vektor mit 4 Komponenten), ist iv.0 hier ein logischer Vektor. Die Ausgabe seiner Struktur bestĂ€tigt dies (Zeile 7). Auch der logische Vektor kann zum Zugriff auf die Komponenten von v verwendet werden (Zeile 10).

4. Indexvektor, der aus Zeichenketten gebildet wird

Die bisher genannten Möglichkeiten einen Index-Vektor zu bilden, können immer angewendet werden. Die letzte Möglichkeit setzt voraus, dass das Attribut names gesetzt ist.

v <- c(x1 = 1, x2 = 0, x3 = 1, x4 = 0)
v
# x1 x2 x3 x4 
# 1  0  1  0 

str(v)
# Named num [1:4] 1 0 1 0
# - attr(*, "names")= chr [1:4] "x1" "x2" "x3" "x4"

iv.0 <- c("x2", "x4")
iv.0
# [1] "x2" "x4"

str(iv.0)
# chr [1:2] "x2" "x4"

v[iv.0]
# x2 x4 
# 0  0

Zur ErklÀrung:

Zeile 1: Die Funktion c() wird in der Form angewendet, die es erlaubt sofort names zu setzen.

Zeile 2 bis 8: An der Ausgabe von v und dessen Struktur erkennt man das Attribut names.

Zeile 10: Es wird ein character-Vektor iv.0 gebildet (aus den Namen der zweiten und vierten Komponente von v).

Zeile 17: Auch dieser character-Vektor kann zum Zugriff auf die Komponenten von v verwendet werden. Anders ist jetzt nur die Ausgabe, da die Namen der Komponenten zusÀtzlich zu ihren Werten ausgegeben werden (Zeile 18).

Anwendung: Auswertung einer Zufallsfolge

EinfĂŒhrung

Die folgenden Aufgaben sollen zeigen, wie man die fĂŒr Vektoren erlĂ€uterten Konzepte in der Praxis einsetzen kann. Als Beispiel wird eine Folge von Zufallszahlen ausgewertet. Wenn zusĂ€tzlich gezeigt wird, wie man eigene Funktionen schreiben kann und wie man Programmier-Konzepte (wie BedingungsprĂŒfungen und Schleifen) einsetzen kann, lassen sich die Quelltexte deutlich vereinfachen und so schreiben, dass sie wiederverwendbar sind.

Die Zufallsfolge v, die im Folgenden ausgewertet wird, lautet:

v <- c(32, 37, 25, 30, 34, 31, 36, 30, 29, 29, 28, 35, 30, 33, 29, 31, 36, 34, 30, 32, 27, 40, 24, 35, 35, 27, 29, 36, 29, 30, 24, 32, 31, 27,
24, 33, 30, 32, 28, 30, 35, 33, 37, 24, 33, 32, 35, 27, 31, 25, 35, 32, 24, 35, 36, 34, 38, 36, 32, 31, 33, 28, 30, 28, 31, 24, 27, 33,
35, 34, 30, 28, 25, 32, 26, 38, 32, 36, 30, 27, 40, 30, 33, 33, 32, 30, 33, 32, 32, 28, 30, 31, 31, 29, 28, 29, 39, 30, 31, 41, 36, 30,
33, 33, 34, 33, 30, 26, 29, 20, 34, 35, 31, 34, 37, 34, 31, 33, 33, 38, 32, 33, 39, 37, 30, 38, 38, 33)

Um sie leichter lesbar zu machen, wird eine sortierte Version erzeugt:

# sortierte Ausgabe von v

v_sort <- sort(v)
v_sort

Die Ausgabe von v_sort ergibt:

[1] 20 24 24 24 24 24 24 25 25 25 26 26 27 27 27 27 27 27 28 28 28 28 28 28 28 29 29 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
[49] 30 30 31 31 31 31 31 31 31 31 31 31 31 32 32 32 32 32 32 32 32 32 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34
[97] 34 34 35 35 35 35 35 35 35 35 35 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 38 39 39 40 40 41

Enthaltene Zahlenwerte

An der sortierten Ausgabe erkennt man zwar sofort, dass die Zahlenfolge von 20 bis 41 lĂ€uft, es ist aber mĂŒhsam zu erkennen:

  • Sind alle Zahlen zwischen 20 und 41 enthalten?
  • Welche Zahlen sind enthalten?
  • Welche Zahlen fehlen?

Das folgende Skript zeigt wie man diese Fragen leicht beantworten kann:

min_v <- min(v)         # 20
max_v <- max(v)         # 41

v_uni <- sort(unique(v))
v_uni
# [1] 20 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

length(v_uni)
# [1] 19

v_missing <- setdiff(x = (min_v:max_v), y = v_uni)
v_missing
# [1] 21 22 23

Statistische Eigenschaften der Zufallsfolge

Die wichtigsten Eigenschaften der Zufallsfolge v können durch folgendes Skript abgefragt werden, zudem wird ein Histogramm gezeichnet:

min_v <- min(v)         # 20
max_v <- max(v)         # 41

hist(x = v, breaks = (min_v:max_v))

options(digits = 4)

length(v)           # 128
mean(v)             # 31.66
var(v)              # 15.53
sd(v)               # 3.941

summary(v)
# Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
# 20.0    29.0    32.0    31.7    34.0    41.0

Abbildung 4: Histogramm fĂŒr die Zufallsfolge v.Abbildung 4: Histogramm fĂŒr die Zufallsfolge v.

Zur ErklÀrung:

Zeile 4: Das Histogramm wird mit Hilfe der Funktion hist() erzeugt, die hier nur kurz vorgestellt wird:

  • Auf der x-Achse werden die breaks vom Minimum bis zum Maximum von v gesetzt; dadurch wird fĂŒr jede ganze Zahl ein Rechteck gezeichnet.
  • Auf der y-Achse sind die absoluten HĂ€ufigkeiten der Zahlen 20, 21, ..., 41 in der Zufallsfolge v aufgetragen; dazu muss nur dem Argument x die Zahlenfolge v ĂŒbergeben werden.

NÀhere ErklÀrungen zu hist() finden sich in der Dokumentation im Paket graphics unter hist.

Zeile 9 bis 11: FĂŒr die statistische Auswertung werden die oben erlĂ€uterten statistischen Funktionen eingesetzt.

Zeile 13 bis 15: Einen schnellen Überblick ĂŒber die statistischen Eigenschaften liefert auch die Funktion summary().

Spezielle statistische Eigenschaften der Zufallsfolge

Oben wurde festgestellt, dass der Mittelwert der Zufallsfolge knapp unterhalb 32 liegt. Man kann sich jetzt fragen, wie oft die Zahl 32 in der Zufallsfolge enthalten ist und bei welchen Indizes die 32 angenommen wird. Das folgende Skript erzeugt die entsprechenden Ausgaben:

h_32 <- length(subset(v, v == 32))          # 13
ind_32 <- which(v == 32)            #  1  20  32  38  46  52  59  74  77  85  88  89 121

An diesem Beispiel erkennt man:

Durch die Vielzahl von Funktionen, die R bereitstellt, gibt es meist mehrere Lösungen zu einem Problem. Die HÀufigkeit, wie oft die Zahl 32 in der Zufallsfolge v vorkommt, hÀtte man auch aus der LÀnge von ind_32 bestimmen können.

Es gibt sogar eine noch einfachere Möglichkeit, die HÀufigkeit der Zahl 32 in v festzustellen:

h_32 <- sum(v == 32)            # 13

Denn bei jeder Komponente von v die gleich 32 ist, ist die Bedingung v == 32 gleich TRUE und somit gleich 1. Werden nun diese Einsen aufaddiert, ergibt sich die Anzahl der 32 in v.

Die zwei Zeilen oben verlangen natĂŒrlich nach einer Verallgemeinerung: warum soll man die die Fragen nur fĂŒr die Zahl 32 stellen? SpĂ€ter wird man dafĂŒr eine Funktion schreiben, die einen Wert der Zahlenfolge als Eingabewert erhĂ€lt und die die HĂ€ufigkeit dieser Zahl beziehungsweise die Indizes in v zurĂŒckgibt.

Die Frage nach der HĂ€ufigkeit der Zahl 32 in der Zufallsfolge lĂ€sst sich auch folgendermaßen verallgemeinern: Wie groß ist die relative HĂ€ufigkeit der Zahlen im Intervall [ ÎŒ - σ, ÎŒ + σ ] = [ 27.71; 35.60]? Dabei ist ÎŒ der Mittelwert der Zahlenfolge mean(v) und σ die Standard-Abweichung sd(v).

m <- mean(v)
sigma <- sd(v)

length(which(v < m + sigma & v > m - sigma)) / length(v)            # 0.6953

Zusammenfassung

Der recycling-Mechanismus

Abbildung 5 zeigt das Beispiel, mit dem oben der recycling-Mechanismus erklĂ€rt wurde (Der recycling-Mechanismus in R), in der ĂŒblichen mathematischen Schreibweise mit Spaltenvektoren.

Abbildung 5: recycling-Mechanismus in mathematischer Schreibweise. Gleichung 1 zeigt die Addition zweier Vektoren gleicher LĂ€nge (sie wird komponentenweise ausgefĂŒhrt und sollte keine  Mehrdeutigkeiten zulassen). Gleichung 2 zeigt zwei Vektoren unterschiedlicher LĂ€nge. Wie werden sie addiert? In der Mathematik wĂŒrde man sagen: Entweder die Addition ist nicht definiert. Oder der kĂŒrzere Vektor wird in den Raum des lĂ€ngeren Vektors eingebettet, indem er so lange mit Nullen aufgefĂŒllt wird, bis die LĂ€ngen ĂŒbereinstimmen. Man erhĂ€lt dann die Addition in Gleichung 3. In R wird auf den kĂŒrzeren Vektor der recycling-Mechanismus angewendet: er wird solange wiederholt, bis die beiden Vektoren gleich lang sind. Dann wird die Addition durchgefĂŒhrt (Gleichung 4); sie wird im Allgemeinen ein anderes Ergebnis liefern als nach Gleichung 3.Abbildung 5: recycling-Mechanismus in mathematischer Schreibweise. Gleichung 1 zeigt die Addition zweier Vektoren gleicher LĂ€nge (sie wird komponentenweise ausgefĂŒhrt und sollte keine Mehrdeutigkeiten zulassen). Gleichung 2 zeigt zwei Vektoren unterschiedlicher LĂ€nge. Wie werden sie addiert? In der Mathematik wĂŒrde man sagen: Entweder die Addition ist nicht definiert. Oder der kĂŒrzere Vektor wird in den Raum des lĂ€ngeren Vektors eingebettet, indem er so lange mit Nullen aufgefĂŒllt wird, bis die LĂ€ngen ĂŒbereinstimmen. Man erhĂ€lt dann die Addition in Gleichung 3. In R wird auf den kĂŒrzeren Vektor der recycling-Mechanismus angewendet: er wird solange wiederholt, bis die beiden Vektoren gleich lang sind. Dann wird die Addition durchgefĂŒhrt (Gleichung 4); sie wird im Allgemeinen ein anderes Ergebnis liefern als nach Gleichung 3.

Test auf Gleichheit von Vektoren

Die folgende Tabelle zeigt Funktionen, mit denen Vektoren auf Gleichheit getestet werden; selbstverstĂ€ndlich können diese Vektoren auch die LĂ€nge 1 besitzen. Nur bei der Funktion all.equal() mĂŒssen die zu vergleichenden Vektoren numerischen Typ besitzen.

Funktion Beschreibung
x == y Der Operator == ist der Vergleichsoperator: alle Komponenten der Vektoren x und y werden verglichen und fĂŒr jeden Vergleich wird ein logischer Wert erzeugt; bei unterschiedlichen Vektor-LĂ€ngen wird der recycling-Mechanismus angewendet.
identical(x, y) Gleichheit zweier Vektoren x und y kann nur bestehen, wenn sie identische Vektor-LĂ€ngen haben. Das Ergebnis des Vergleichs wird in einem logischen Wert abgelegt: Falls die Vektor-LĂ€ngen ĂŒbereinstimmt und alle Komponenten identisch sind, wird TRUE zurĂŒckgegeben, andernfalls FALSE.
all.equal(target, current, tolerance) Vergleicht, ob die beiden numerischen Vektoren target und current nĂ€herungsweise — also bis auf die gegebene tolerance — ĂŒbereinstimmen.

Die folgende Tabelle beschreibt die RĂŒckgabewerte der Funktionen und ihre Datentypen:

Funktion RĂŒckgabewert Datentyp
x == y Logischer Vektor mit der LÀnge des lÀngeren der beiden Vektoren x und y: jede Komponente gibt an, ob die entsprechenden Komponenten in x und y identisch sind (eventuell recycling-Mechanismus). logischer Vektor
identical(x, y) Ein logischer Wert, der angibt, ob gleichzeitig alle Komponenten von x und y Übereinstimmen (also TRUE, falls alle Komponenten ĂŒbereinstimmen; FALSE, falls eine oder mehr Komponenten verschieden sind). Kein recycling-Mechanismus: FALSE bei unterschiedlichen Vektor-LĂ€ngen. logischer Wert
all.equal(target, current, tolerance) TRUE, falls sich alle Komponenten von target und current um weniger als tolerance unterscheiden; eine Zeichenkette mit einer Beschreibung der Abweichung, falls eine oder mehr Komponenten sich um mehr als tolerance unterscheiden. der logische Wert TRUE oder eine Zeichenkette

Wissenschaftliche Funktionen

Im Kapitel EinfĂŒhrung in R: Zahlen und Variablen wurden die wissenschaftlichen Funktionen vorgestellt als hĂ€tten sie einen Eingabewert; in der Mathematik werden sie ĂŒblicherweise so definiert. In R kann man stattdessen einen Vektor von Zahlen eingeben und erhĂ€lt als RĂŒckgabewert wiederum einen Vektor: die Funktion wird auf jede Komponente des Eingabe-Vektors angewendet.

Da dies die einzige Neuerung gegenĂŒber der Darstellung in EinfĂŒhrung in R: Zahlen und Variablen ist, werden die wissenschaftlichen Funktionen hier nicht nochmals aufgefĂŒhrt.

Funktionen eines Vektors

Die folgende Tabelle zeigt eine Kurzbeschreibung der im Abschnitt Funktionen eines Vektors vorgestellten Funktionen. Man beachte dabei aber, dass die gezeigten Argumente meist nicht die komplette Liste der Eingabewerte darstellt. Es werden immer nur diejenigen Eingabewerte gezeigt, die hier auch besprochen wurden. FĂŒr die allgemeine Verwendung der Funktionen ist es erforderlich die Dokumentation zu Rate zu ziehen.

Man beachte, dass die Überschrift Funktionen eines Vektors nicht ganz richtig ist: manche der vorgestellten Funktionen können beliebig viele Vektoren als Eingabewerte aufnehmen, was durch das Argument ... ausgedrĂŒckt wird (dot-dot-dot-Notation); die Vektoren werden dann aneinandergehĂ€ngt und als ein Vektor weiterverarbeitet. In der Praxis wendet man diese Funktionen meist mit einem Eingabe-Vektor an.

Funktion Beschreibung
length(x) Gibt die LĂ€nge eines Vektors an; ist nicht nur fĂŒr Vektoren sondern fĂŒr jedes Objekt definiert.
min( ..., na.rm = FALSE) Berechnet das Minimum der eingegebenen Werte (meist ein Vektor)
max( ..., na.rm = FALSE) Berechnet das Maximum der eingegebenen Werte (meist ein Vektor)
sum(..., na.rm = FALSE) Berechnet die Summe der eingegebenen Werte (meist ein Vektor)
prod(..., na.rm = FALSE) Berechnet das Produkt der eingegebenen Werte (meist ein Vektor)
diff(x, lag = 1, differences = 1) Berechnet die Differenzen zwischen aufeinanderfolgenden Komponenten von x fĂŒr lag = 1 (mit lag wird festgelegt, wie groß der Abstand zwischen den Komponenten ist, deren Differenzen gebildet werden); differences gibt an, wie oft die Funktion diff() rekursiv aufgerufen wird.
cumsum(x) Kumulierte Summen des Vektors x
cumprod(x) Kumulierte Produkte des Vektors x
cummin(x) Kumuliertes Minimum des Vektors x
cummax(x) Kumuliertes Maximum des Vektors x
mean(x, trim = 0, na.rm = FALSE) Mittelwert des Vektors x; trim beschreibt den Bruchteil der Komponenten, die bei der Berechnung weggelassen werden (weggelassen werden die Komponenten ausgehend vom Minimum und Maximum)
var(x, na.rm = FALSE) Berechnet die empirische Varianz von x
sd(x, na.rm = FALSE) Berechnet die empirische Standard-Abweichung von x (Wurzel aus der empirischen Varianz)
?Extremes Weitere Informationen zu min(), max(),

Die folgende Tabelle beschreibt die RĂŒckgabewerte der Funktionen und ihre Datentypen; ist als Typ des RĂŒckgabewertes Zahl angegeben, so ist damit eigentlich ein numerischer Vektor der LĂ€nge 1 gemeint:

Funktion RĂŒckgabewert Datentyp
length(x) LĂ€nge von x (ist fĂŒr jedes Objekt x definiert) Zahl
min( ..., na.rm = FALSE) Minimum der eingegebenen Werte Zahl
max( ..., na.rm = FALSE) Maximum der eingegebenen Werte Zahl
sum(..., na.rm = FALSE) Summe der eingegebenen Werte Zahl
prod(..., na.rm = FALSE) Produkt der eingegebenen Werte Zahl
diff(x, lag = 1, differences = 1) Differenzen zwischen aufeinanderfolgenden Komponenten von x fĂŒr lag = 1 (mit lag wird festgelegt, wie groß der Abstand zwischen den Komponenten ist, deren Differenzen gebildet werden); differences gibt an, wie oft die Funktion diff() rekursiv aufgerufen wird. Vektor mit verringerter Anzahl von Komponenten (jeder rekursive Aufruf verringert die Anzahl um 1)
cumsum(x) Kumulierte Summen des Vektors x Vektor mit der LĂ€nge von x
cumprod(x) Kumulierte Produkte des Vektors x Vektor mit der LĂ€nge von x
cummin(x) Kumuliertes Minimum des Vektors x Vektor mit der LĂ€nge von x
cummax(x) Kumuliertes Maximum des Vektors x Vektor mit der LĂ€nge von x
mean(x, trim = 0, na.rm = FALSE) Mittelwert des Vektors x; trim beschreibt den Bruchteil der Komponenten, die bei der Berechnung weggelassen werden (weggelassen werden die Komponenten ausgehend vom Minimum und Maximum) Zahl
var(x, na.rm = FALSE) Berechnet die empirische Varianz von x Zahl
sd(x, na.rm = FALSE) Berechnet die empirische Standard-Abweichung von x (Wurzel aus der empirischen Varianz) Zahl

Funktionen von zwei oder mehreren Vektoren

Die folgende Tabelle zeigt eine Kurzbeschreibung von Funktionen, die zwei oder mehrere Vektoren als Eingabewert haben. Inhaltlich sind sie sehr verschieden und können folgenden Gruppen zugeordnet werden:

  1. Paralleles Minimum/Maximum
  2. Skalarprodukt
  3. Statistische Funktionen
  4. Mengen-Operationen
Funktion Beschreibung
pmin(..., na.rm = FALSE) Berechnet das parallele Minimum der eingegebenen Vektoren
pmax(..., na.rm = FALSE) Berechnet das parallele Maximum der eingegebenen Vektoren
?Extremes Weitere Informationen zu pmin(), pmax()
sum(u * v) Berechnet das Skalarprodukt der Vektoren u und v (kann bei unterschiedlichen Vektor-LĂ€ngen zu unerwarteten Ergebnissen fĂŒhren)
u %*% v Berechnet das Skalarprodukt der Vektoren u und v (liefert bei unterschiedlichen Vektor-LĂ€ngen eine Fehlermeldung); der Operator %*% fĂŒhrt im Allgemeinen die Matrizenmultiplikation aus.
cov(x, y) Berechnet die Kovarianz der Vektoren x und y
cor(x, y) Berechnet den Korrelationskoeffizienten der Vektoren x und y
?cor Weitere Informationen zu Kovarianz und Korrelationskoeffizient im Paket stats unter cor
is.element(el, set) Testet fĂŒr jede Komponente von el, ob sie in der Menge set enthalten ist
setequal(x, y) Testet, ob die beiden Mengen x und y identisch sind
union(x, y) Berechnet die Vereinigungsmenge der Mengen x und y
intersect(x, y) Berechnet die Durchschnittsmenge der Mengen x und y
setdiff(x, y) Berechnet die Differenz der Mengen x und y (Beachte: die Operation ist nicht symmetrisch bei Vertauschung der Argumente)
?sets Weitere Informationen zu Mengen-Operationen

Die folgende Tabelle beschreibt die RĂŒckgabewerte der Funktionen und ihre Datentypen:

Funktion RĂŒckgabewert Datentyp
pmin(..., na.rm = FALSE) Paralleles Minimum der eingegebenen Vektoren Vektor mit der LÀnge des lÀngsten Vektors
pmax(..., na.rm = FALSE) Paralleles Maximum der eingegebenen Vektoren Vektor mit der LÀnge des lÀngsten Vektors
sum(u * v) Berechnet das Skalarprodukt der Vektoren u und v (kann bei unterschiedlichen Vektor-LĂ€ngen zu unerwarteten Ergebnissen fĂŒhren) Zahl
u %*% v Berechnet das Skalarprodukt der Vektoren u und v (liefert bei unterschiedlichen Vektor-LĂ€ngen eine Fehlermeldung); der Operator %*% fĂŒhrt im Allgemeinen die Matrizenmultiplikation aus. 1 × 1-Matrix
cov(x, y) Kovarianz der Vektoren x und y Zahl
cor(x, y) Korrelationskoeffizient der Vektoren x und y Zahl zwischen -1 und 1
is.element(el, set) logischer Vektor, der fĂŒr jede Komponente angibt, ob die entsprechende Komponente von el in der Menge set enthalten ist logischer Vektor mit der LĂ€nge von el
setequal(x, y) Testet, ob die beiden Mengen x und y identisch sind logischer Wert
union(x, y) Vereinigungsmenge der Mengen x und y Vektor (enthÀlt keine doppelten Komponenten, im Allgemeinen nicht sortiert)
intersect(x, y) Durchschnittsmenge der Mengen x und y Vektor (enthÀlt keine doppelten Komponenten, im Allgemeinen nicht sortiert)
setdiff(x, y) Differenz der Mengen x und y (Beachte: die Operation ist nicht symmetrisch bei Vertauschung der Argumente) Vektor (enthÀlt keine doppelten Komponenten, im Allgemeinen nicht sortiert)

Funktionen zum Sortieren von Vektoren

Die folgende Tabelle zeigt Funktionen, mit denen Vektoren sortiert oder damit verwandte Aufgaben erledigt werden können:

Funktion Beschreibung
rev(x) Erzeugt einen Vektor mit umgekehrter Anordnung der Komponenten wie im Vektor x (rev = reverse)
sort(x, decreasing = FALSE, na.last) Sortieren eines Vektors (besitzt zahlreiche Zusatz-FunktionalitÀten)
is.unsorted(x, na.rm = FALSE, strictly = FALSE) Abfragen, ob ein Vektors x noch nicht sortiert ist.
unique(x) Entfernt mehrfach vorkommende Komponenten aus einem Vektor x
duplicated(x) Untersucht alle Komponenten von x und gibt an, ob ihr Wert schon einmal im Vektor vorgekommen ist.
order( ... , na.last = TRUE, decreasing = FALSE) Gibt die Indizes der sortierten Komponenten an (wo steht die kleinste Komponente, wo steht die zweit-kleinste Komponente und so weiter)
rank(x) Angabe der Rangfolge: zu jeder Komponente wird angegeben, welche Rangfolge sie im Vektor x hat, wenn man ihn sortieren wĂŒrde.

Die folgende Tabelle beschreibt die RĂŒckgabewerte der Funktionen und ihre Datentypen:

Funktion RĂŒckgabewert Datentyp
rev(x) Vektor mit umgekehrter Anordnung der Komponenten wie im Vektor x Vektor
sort(x, decreasing = FALSE, na.last) Sortierte Version des Vektors x (mit decreasing wird die Sortier-Reihenfolge festgelegt, mit na.last wird festgelegt, ob NA-Werte am Anfang oder am Ende stehen) Vektor
is.unsorted(x, na.rm = FALSE, strictly = FALSE) Abfragen, ob ein Vektors x noch nicht sortiert ist. logischer Wert
unique(x) Vektor, der mit x ĂŒbereinstimmt, aber keine Komponenten mehrfach enthĂ€lt Vektor
duplicated(x) Logischer Vektor mit der LĂ€nge von x: FALSE fĂŒr jeden Wert, der zum ersten Mal in x vorkommt, TRUE bei Wiederholungen logischer Vektor
order( ... , na.last = TRUE, decreasing = FALSE) Gibt die Indizes der sortierten Komponenten an (wo steht die kleinste Komponente, wo steht die zweit-kleinste Komponente und so weiter) Vektor
rank(x) Vektor mit den Rangfolgen der Komponenten von x Vektor

Vektoren und BedingungsprĂŒfungen

Die folgende Tabelle zeigt Funktionen, die auf Vektoren operieren und mit einer (oder mehreren) BedingungsprĂŒfung verbunden sind:

Funktion Beschreibung
subset(x, subset) Auswahl eines Teilvektors aus einem Vektor x; ausgewĂ€hlt werden diejenigen Komponenten, die eine Bedingung subset erfĂŒllen.
which(x) Untersucht den logischen Vektor x und gibt diejenigen Indizes an, fĂŒr die x den Wert TRUE hat.
all(..., na.rm = FALSE) Mehrere logischen Vektoren Vektoren werden aneinandergehÀngt und es wird untersucht, ob alle Komponenten gleich TRUE sind.
any(..., na.rm = FALSE) Mehrere logischen Vektoren Vektoren werden aneinandergehÀngt und es wird untersucht, ob eine oder mehr Komponenten gleich TRUE sind.

Die folgende Tabelle beschreibt die RĂŒckgabewerte der Funktionen und ihre Datentypen:

Funktion RĂŒckgabewert Datentyp
subset(x, subset) Teilvektor von x; nur diejenigen Komponenten werden ĂŒbernommen, die eine Bedingung subset erfĂŒllen. Vektor (LĂ€nge ist kleiner oder gleich der LĂ€nge von x)
which(x) Untersucht den logischen Vektor x und gibt diejenigen Indizes an, fĂŒr die x den Wert TRUE hat. Vektor von Indizes (Speichermodus "integer"; LĂ€nge ist kleiner oder gleich der LĂ€nge von x)
all(..., na.rm = FALSE) Mehrere logischen Vektoren Vektoren werden aneinandergehÀngt und es wird untersucht, ob alle Komponenten gleich TRUE sind. logischer Wert
any(..., na.rm = FALSE) Mehrere logischen Vektoren Vektoren werden aneinandergehÀngt und es wird untersucht, ob eine oder mehr Komponenten gleich TRUE sind. logischer Wert