Datenanalyse mit R, Teil 2 | heise online

Datenanalyse mit R, Teil 2

Datensammeln allein nutzt nichts, man muss das Gesammelte auch auswerten können. Die Sprache R bietet hierzu zahlreiche analytische und statistische Möglichkeiten. Wie sich Modelle bilden und für Prognosen nutzen lassen, zeigt dieser Artikel.

vorlesen Druckansicht 3 Kommentare lesen
Lesezeit: 21 Min.
Von
  • Ralf Ehret
  • Benjamin Graf
Inhaltsverzeichnis

Datensammeln allein nutzt nichts, man muss das Gesammelte auch auswerten können. Die Sprache R bietet hierzu zahlreiche analytische und statistische Möglichkeiten. Ob es sich nun um Biotechnologie, Finanzmarktanalysen oder das Kaufverhalten von Kunden handelt: In all diesen Gebieten entstehen ständig neue Data-Mining-Verfahren, die durch das Engagement der Open-Source-Community schnell ihren Weg in R finden. Um sie richtig nutzen zu können, wirft dieser Artikel einen Blick auf die Modellbildung, die Vorgehensweise bei der Analyse sowie Prognosen und Tests in der seit 1993 bestehenden Sprache.

Nachdem die Daten im ersten Teil eingelesen und konvertiert wurden, versucht man im nächsten Schritt, sie zu verstehen. Zunächst schaut man sich dazu die Verteilungen der einzelnen Attribute an. Um mehrere in einem Plot darzustellen, lassen sich die grafischen Ausgabeparameter mit dem Befehl par() ändern. Es lohnt sich, ihn in der Hilfe etwas näher anzuschauen. Hiernach ist der Parameter mfrow dafür geeignet, den Ausgabebereich des Fensters in eine Anzahl von Zeilen und Spalten zu teilen. Um nicht immer den ganzen Namen des Data Frame und das mit $ gekennzeichnete Attribut zu tippen, gibt es den Befehl attach(ObjectName), der auf den ersten Blick am ehesten mit einem setNamespace zu vergleichen ist. Aber Vorsicht: Eigentlich legt er nur eine Suchreihenfolge für Ausdrücke fest, die man sich über den Befehl search() anschauen kann. Um die Namen der Objekt-Attribute zu erfahren, ist names(Object) einzugeben:

> # Vorbereitungen
> par(mfrow=c(2,2)) # Teilt das Ausgabefenster in 4 Bereiche
> attach(SalesOrders) # nie in Scripten verwenden!
> names(SalesOrders) # Spaltennamen auslesen
[1] "BuyerRef" "DeliveryDate" "TotalPrice" "PaymentDuration"

Die Verteilung der Attribute lässt sich durch Eingabe des hist()-Befehls in Histogrammen ansehen. Hierbei werden der Wertebereich eines Attributes automatisch in äquidistante Bereiche, sogenannte Bins, unterteilt und die Häufigkeiten der Werte pro Bin bestimmt.

> # Eindimensionale Plots
> hist(BuyerRef) # Histogram für erste Spalte
> hist(DeliveryDate, "weeks")# spezielle hist() Fkt für Date Klasse
> hist(TotalPrice) # ...
> hist(PaymentDuration) # ...

Ein weiteres Hilfsmittel zum Begutachten von Daten sind Scatter-Plots, die eine Abhängigkeit von zwei Attributen zeigen können. Deshalb nennt man sie auch Korrelationsplots.

> # 2-dimensionale Korrelationsplots
> plot(BuyerRef, PaymentDuration)
> smoothScatter(BuyerRef, PaymentDuration)
> smoothScatter(TotalPrice, PaymentDuration)
> plot(TotalPrice, PaymentDuration, cex=0.3)

Das Ergebnis ist in Abbildung 1 zu sehen:

Ergebnisplots zur Visualisierung (Abb. 1)


Auf der linken Seite der Abbildung sind die eindimensionalen Histogramme der einzelnen Attribute zu sehen. Während die ersten drei Histogramme kaum auffällig sind, erkennt man bei der PaymentDuration einen schmalen Peak bei etwa 5 und einen breiten Peak bei etwa 19 – das erste Anzeichen dafür, dass es ein unterschiedliches Zahlungsverhalten gibt.

Der rechte Teil von Abbildung 1 zeigt die Abhängigkeit des Attributs PaymentDuration von BuyerRef und TotalPrice. Für das Attribut BuyerRef wurde der Scatterplot mit zwei verschiedenen Methoden erzeugt: Das erste Diagramm zeigt den mit plot() entstandenen Standard-Scatterplot. Hierbei wird aus jeder Zeile der Daten ein Punkt des Werte-Paares (BuyerRef, PaymentDuration) erzeugt. Ein Nachteil von plot ist, dass sich bei einer großen Anzahl von Punkten kaum etwas erkennen lässt und alle einzeln gezeichnet werden müssen, was bei einer Milliarde Punkten etwas länger dauert. Die Methode smoothScatter() hingegen berechnet die Dichte der Punkte für unterschiedliche Bereiche und zeigt sie an. Enger besetzte Gebiete erscheinen dunkler. Durch die Verwendung der Funktion smoothScatter() geht allerdings Information verloren. Eine weitere Möglichkeit zur Visualisierung ist, die Punktgröße im Standart-Plot mit dem Parameter cex in der plot()-Funktion zu reduzieren. Beim Attribut TotalPrice (letzter Plot) erkennt man jetzt deutlich, dass es sich bei PaymentDuration um eine Integer-Größe handelt.

Eine Möglichkeit, die obigen Daten in nur einem Bild darzustellen, ist die Verwendung der Funktion scatterplotMatrix() aus dem Paket car:

> scatterplotMatrix(SalesOrders, diagonal="histogram", cex=0.5,
+ smooth=FALSE, reg.line=FALSE)

Visualisierung der Daten mit scatterplotMatrix() (Abb. 2)


Das Package car (Companion to Applied Regression) ist ein Zusatzpaket für Regressionsmodelle. Die Funktion scatterplotMatrix() ist die zentrale Plot-Methode des Pakets und führt im Hintergrund eigentlich noch Glättungsalgorythmen (density für die Diagonalelemente und LOESS für die Nichtdiagonalelemente) aus. Für das gezeigte Diagramm wurden diese Standardparameter ausgeschaltet beziehungsweise überschrieben.

Beim Erstellen eines statistischen Modells ist es wichtig, sich im Vorhinein darüber klar zu sein, welche Aufgabe man mit dem Modell lösen möchte. In vorliegenden Fall könnte sie folgendermaßen aussehen:

  1. Erstelle aus den historischen Verkaufsaufträgen der Kunden und den einzelnen Zeitdifferenzen von Rechnungsausgang und Zahlungseingang (PaymentDuration) Kundenprofile.
  2. Ordne die Kunden den Profilen zu.
  3. Sage für einen neuen Verkaufsauftrag eines Kunden vorher, was der wahrscheinlichste Termin für den Geldeingang ist.

Zur Analyse stehen die vier Attribute aus unserem Datenobjekt SalesOrders zur Verfügung:

  • BuyerRef, eine Kundennummer;
  • DeliveryDate, das Auslieferungsdatum (und damit das Rechnungsdatum);
  • TotalPrice, der Bruttopreis der bestellten Waren;
  • PaymentDuration, die Anzahl Tage ab dem Auslieferungsdatum bis die Zahlung erfolgte.

In der Visualisierung der Daten ließ sich erkennen, dass es keine Auffälligkeiten für die Attribute DeliverDate und TotalPrice gibt, sondern nur in der PaymentDuration. So lässt sich allerdings noch nichts über den Zusammenhang zu den einzelnen Kunden aussagen. Um Daten auf Kundenebene zu aggregieren, besteht eine Möglichkeit darin, zunächst Zeitreihenobjekte für jeden Kunden zu erzeugen. Zeitreihen sind Wertepaare aus einer diskreten Messgröße und des Zeitpunkts der Messung. Diese können in konstanten Abständen (äquidistant) oder zufällig verteilt sein. Im vorliegenden Fall entspricht die Zahlungsdauer (PaymentDuration) der Messung und das Datum der Rechnungsstellung (DeliveryDate) dem Zeitpunkt. Die Liste aller Werte-Zeit-Paare eines Kunden entspricht seiner Zahlungshistorie.

Um eine solche Zeitreihe für jeden einzelnen Kunden zu erzeugen, sind Methoden zur Datenmanipulation (aggregieren, zusammenführen, ableiten von neuen aus alten Attributen) nötig. R besitzt hierfür eine Reihe von Möglichkeiten, wobei spezielle Pakete das Verwenden anderer Sprachen, zum Beispiel SQL (Package sqldf), erlauben.

Ein erster Schritt ist, alle Zahlungsdauern eines Kunden in ein TimeSeries-Objekt zu packen und in einem neuen Data Frame zu speichern, beispielsweise mit aggregate(). Die Funktion arbeitet den Data Frame zeilenweise ab, aggregiert alle Einträge nach einer Spalte, die durch den Parameter by angegeben ist, und führt danach die in FUN angegebene Aggregationsfunktion ts (create Time Services) durch. Anschließend setzt die eingegebene Sequenz den Namen der Spalten des Objekts Pd.ts.

Pd.ts     <- aggregate(x=SalesOrders$PaymentDuration,
by=list(Customer=SalesOrders$BuyerRef), FUN=ts)
names(Pd.ts) <- c("Customer", "TimeSeries")

Das resultierende Objekt lässt sich mit der bekannten str()-Funktion untersuchen:

> str(Pd.ts[1:3,])
'data.frame': 3 obs. of 2 variables:
$ Customer: int 1001 1002 1003
$ TimeSeries:List of 5
..$ 0: Time-Series from 1 to 7: 14 15 16 16 15 19 17
..$ 1: Time-Series from 1 to 16: 23 15 15 19 11 18 19 23 19 12 ...
..$ 2: Time-Series from 1 to 20: 26 29 24 25 24 21 28 20 19 20 ...
>

Alle Werte des Attributs PaymentDuration sind jetzt in einem Time-Series-Objekt abgelegt. Auf dem neuen Data Frame Pd.ts lässt sich mit sapply() die Funktion mean() zur Berechnung des Mittelwerts der PaymentDurations für einen Kunden anwenden:

# Mean value of time series
Pd.mean <- sapply(Pd.ts[, "TimeSeries"], FUN=mean)

Als Nächstes sind der Vektor Pd.mean und das Data Frame Pd.ts mit cbind() zu einem neuen Data Frame Pd zusammenzufügen.

Pd <- cbind(Pd.ts, Mean=Pd.mean)

Beide Befehle lassen sich kombinieren, indem man beispielsweise eine Standardabweichung hinzufügt. Das anfänglich erstellte Histogramm des Attributs PaymentDuration hatte zwei Peaks, einen schmalen und einen breiten. Dies legt nahe, dass es zwei Verteilungen mit unterschiedlichen Breiten (Standardabweichungen) gibt.

Pd <- cbind(Pd, StdDev=sapply(Pd.ts[, "TimeSeries"], FUN=sd))

Bisher wurden die Aggregation (aggregate()), das Anwenden einer Funktion auf eine Spalte (sapply() ), sowie das Erweitern von data.frames durch das Hinzufügen von Vektoren mit cbind() vorgestellt. Was jetzt noch fehlt ist das Zusammenfügen (Mergen) von zwei Datenobjekten. Dafür sind für die hier beschriebenen Zwecke eine Aggregation der Kunden durchzuführen und diesen die Anzahl der Verkaufsaufträge zuzuordnen (könnte analog zu den Beispielen durch sapply(..., FUN = length)
geschehen):

# example for more attributes and merge
Pd.nr <- aggregate(x=SalesOrders$PaymentDuration,
by=list(Customer=SalesOrders$BuyerRef), FUN=length)
names(Pd.nr) <- c("Customer", "NrDel")
Pd <- merge(Pd, Pd.nr)

Bei dem Befehl merge() ist darauf zu achten, dass die zusammzuführenden Spalten der Objekte gleiche Namen besitzen. Ist das nicht der Fall oder ist es nicht eindeutig, lassen sie sich mit den Parametern by.x und by.y setzen.

Ein Umsortieren der Spalten des Objekts Pd lässt die Time-Series-Objekte zum Schluss erscheinen:

> Pd <- Pd[, c(1,3,4,5,2)]
> str(Pd[1:3,])
'data.frame': 3 obs. of 5 variables:
$ Customer : int 1001 1002 1003
$ Mean : num 16 17.8 24.1
$ StdDev : num 1.63 4.42 3.56
$ NrDel : int 7 16 20
$ TimeSeries:List of 3
..$ 0: Time-Series from 1 to 7: 14 15 16 16 15 19 17
..$ 1: Time-Series from 1 to 16: 23 15 15 19 11 18 19 23 19 12 ...
..$ 2: Time-Series from 1 to 20: 26 29 24 25 24 21 28 20 19 20 ...
>

Die Modellannahmen besagen also, dass es die "Skonto"-Zahler, die innerhalb von 7 Tagen zahlen (da sie das Skonto nutzen möchten) und deshalb eine schmale Verteilung besitzen, und die "ich warte bis zum Zahlungsziel"-Zahler gibt, die ihre Rechnungen erst am Ende der Zahlungsfrist von 21 Tagen bezahlen.

Die zugrunde gelegten Annahmen lassen sich durch eine Clusteranalyse überprüfen. Der Standard-Algorithmus für Clustering ist wohl der k-means-Algorithmus, der auf Ideen von Hugo Steinhaus von 1957 [1] basiert. Neuere Algorithmen sind meist in kurzer Zeit in R als Paket verfügbar – so auch der MCLUST- Algorithmus von Fraley and Raftery [2] [3]. Um ihn zu nutzen, wird das Paket mclust benötigt, das sich, wie bereits erwähnt, mit dem Button "Install Packages" auf der Registerkarte Packages im rechten unteren Hilfe-Bereich von RStudio installieren lässt. Die Ausführung der Analyse ist recht einfach: Man muss nur die zu clusternden Daten angeben, und der Befehl Mclust( data ) führt den Algorithmus aus. Zu beachten ist, dass nicht das zu clusternde Attribut BuyerRef Verwendung findet. Hierfür soll sich schließlich die Zuordnung bestimmen lassen.

# find customer clusters
cl.m <- Mclust(Pd[,2:4])

Das erzeugte Objekt cl.m besitzt viele einzelne Komponenten, die das verwendete Modell, die Cluster- Zentren, die Wahrscheinlichkeit der Zugehörigkeit der Datensätze zu jedem Cluster, und vieles mehr beschreibt. Wichtige Informationen stecken beispielsweise in den einzelnen Cluster-Zentren:

> cl.m$parameters$mean
[,1] [,2] [,3]
Mean 18.140297 6.0060369 25.054981
StdDev 4.138271 0.9696506 3.232709
NrDel 14.705898 33.3333333 28.571594

Der Algorithmus findet nicht zwei, sondern drei Kunden-Cluster, was sich wieder visuell darstellen lässt. Hierzu ruft man die plot()-Funktion für ein Objekt der Klasse Mclust auf:

plot(cl.m, Pd[,2:4], what=c("classification"))

Das Resultat ist in Abbildung 3 gezeigt. Auf der rechten Seite sind die bekannten Scatterplots der drei Attribute Mean, StdDev und NrDel zu sehen, in denen jeweils die einem Cluster zugeordneten Datenpunkte unterschiedlich eingefärbt wurden: Cluster 1 ist blau, Cluster 2 rot und Cluster 3 grün. Man erkennt weiterhin, dass die Cluster am besten in den Variablen Mean und StdDev getrennt werden können. Für sie ist rechts daneben der Scatterplot beider Attribute samt der Cluster-Zentren und der zugehörigen Fehlerellipsen dargestellt.

Ergebnis der Clusteranalyse mit Mclust() (Abb. 3)

Neben den beiden erwarteten Gruppen der "Skonto"-Zahler (rot) und der "ich warte bis zum Zahlungsziel"-Kunden (blau) gibt es wohl eine dritte Gruppe (grün), die "ich warte auf die Mahnung"-Kunden. Allein dieses Wissen kann für eine Firma viel Wert sein.

Um das Zahlverhalten eines Kunden aufgrund seiner Zahlungshistorie vorherzusagen, ist eine sogenannte Prädiktor-Funktion von Nöten. Als Input dienen die Attribute des Verkaufsauftrags (in unserem Fall der Kunde und das DeliveryDate). Intern benutzt sie die abgeleiteten Attribute (Datenobjekt Pd). Eine einfache Prädiktor-Funktion ergibt sich beispielsweise aus den zuvor berechneten Mittelwerten der Zeitreihen der einzelnen Kunden.

Um eine Funktion in R zu definieren findet der Befehl function(arg1,arg2,...) Verwendung. Die angestrebte Funktion sollte als Input-Argument die Kunden-ID verwenden und als Ergebnis die wahrscheinlichste Dauer bis zum Zahlungseingang zurückgeben. Um die Vorhersage aussagekräftiger zu gestalten, soll außerdem die Standardabweichung erscheinen, da die Aussage, der Kunde zahlt innerhalb von 21 Tagen, nicht viel Wert ist, wenn die Vorhersage zwischen sieben Tagen und einem Jahr schwankt. Aus diesen Voraussetzungen ergäbe sich die folgende Prädiktor-Funktion:

# define predictor
predict.payDur <- function(ID) {
i <- match(ID, Pd$Customer, nomatch = 0)
if(i==0) {
# unknown customer, best guess:
# return mean value and standard deviation of
# all historical PaymentDuration
payDur.mean <- mean(unlist(Pd[,"TimeSeries"]))
payDur.sd <- sd(unlist(Pd[,"TimeSeries"]))
} else {
payDur.mean <- Pd[Pd$Customer == Pd$Customer[i], "Mean"]
payDur.sd <- Pd[Pd$Customer == Pd$Customer[i], "StdDev"]
}
return(c(payDur.mean, payDur.sd))
}

In der ersten Zeile bestimmt das Skript mit dem Befehl match(), ob die übergebene ID einem bereits bekannten Kunden zuzuordnen ist. Ist dem so, werden seine mittlere Zahlungsdauer und die Standardabweichung aus dem Modell PD zurückgeliefert. Ist es ein unbekannter Kunde, gibt die Funktion den Mittelwert und die Standardabweichung aller Zahlungen zurück.

Mit der definierten Prädiktor-Funktion lässt sich das Modell jetzt testen. Dafür sind nur Daten zu nutzen, die bei der Modellerstellung nicht berücksichtigt wurden. Würde ein Modell auf den gleichen Daten getestet, die man auch für die Modellerstellung verwendet, würde der Test immer die Modellannahmen bestätigen, da sie ja aus diesen Trainingsdaten hervorgegangen sind. Das folgende Beispiel (in der Datei createTestData.R abzuspeichern) generiert deshalb einige Testdaten:

# create some sample SalesOrders for testing
set.seed(1234) # set seed for random number generation
d0 <- as.Date("1970-01-01") # set constant: begin of date
date.min <- as.Date("2012-07-01") # earliest date for SalesOrder
date.max <- as.Date("2012-08-31") # latest date for SalesOrder
nr <- 1000 # create 1000 SalesOrders
# select 1000 customer IDs randomly
cust.test <- round(runif(nr, min=1001, max=1100))
# create 1000 dates randomly between earliest and latest date
date.test <- d0 + round(runif(nr, min = date.min-d0,
max = date.max-d0))
# create 1000 total prices randomly
total.test <- 10000+round(rnorm(nr, mean=10000, sd=5000))
# combine all data into a data.frame
SO.test <- data.frame(Customer=cust.test,
DeliveryDate=date.test,
TotalPrice=total.test)

Soll die Prädiktor-Funktion auf die so erzeugten Daten angewendet werden, ergibt sich:

# apply predictor 
cust.pred <- t(sapply(SO.test$Customer, FUN=predict.payDur))
# enhance sample SalesOrder with predicted attributes
SO.test <- cbind(SO.test,
predict.pd.mean=cust.pred[,1],
predict.pd.sd=cust.pred[,2],
predict.date=SO.test$DeliveryDate+cust.pred[,1]
)

Da die Funktion predict.payDur() einen Vektor mit zwei Elementen zurückliefert und sapply() sie 1000-mal aufruft (für jeden einzelnen Verkaufsauftrag aus dem Data Frame SO.test), entsteht als Ergebnis eine 2x1000-Matrix. Sie lässt sich mit dem Befehl t() transponieren.

Um nun zu ermitteln, wie viele Einnahmen über die nächsten Monate aus bestehenden Forderungen an Kunden zu erwarten sind, addiert man beispielsweise alle vermuteten Zahlungen pro Woche auf und plottet das Ergebnis. Dafür ist zunächst die Woche aus dem vorhergesagten Zahlungsdatum zu bestimmen und dem Testdatensatz mit format() hinzuzufügen:

SO.test$predict.week <- as.numeric(format(SO.test[,6], "%W"))

Anschließend summiert aggregate() alle Preise einer bestimmten Woche auf:

# plot sum per week
sum.week <- aggregate(x=SO.test$TotalPrice,
by=list(SO.test$predict.week), FUN=sum)
names(sum.week) <- c("predicted.week","TotalSum")
plot(sum.week, type="b"))

Das Resultat lässt sich in Abb. 4 betrachten.

Erwartete Einnahmen pro Woche (Abb. 4)

Die Kurve zeigt in Schwarz die Vorhersage der Einnahmen pro Kalenderwoche für die offenen Aufträge. In Blau und in Rot sind alte Abschätzungen für die minimale und maximale Zahlungsdauer gezeigt. Der Darstellung lässt sich entnehmen, dass in KW 28 circa 500.000 Euro eingenommen werden. Nach der früheren minimalen Abschätzung (in Blau), sollen laut Modell bereits Einnahmen in Höhe von 2,5 Millionen Euro vorliegen. Ein Unterschied von 2 Millionen Euro! Das maximale Modell sagt in KW 28 dagegen überhaupt keine Einnahmen voraus.

Dieses Ergebnis soll hier genügen. In der Realität fehlen jedoch ein paar Dinge: Zum einen wurde keine Fehlerbetrachtung der Abschätzung durchgeführt, zum anderen benötigt man noch einige Funktionen zur Ermittlung der Güte des vorliegenden Modells. Außerdem flossen nur drei Parameter in die Modellerstellung ein. Typischerweise unterscheiden sich die Kunden aber viel stärker. Es wird länderspezifische Zahlungsverhalten ebenso geben wie Abhängigkeiten anderer Merkmale, wie ob es sich um einen Großkonzern, Mittelständler oder sogar einen Privatkunden handelt. Zuletzt sei noch angemerkt, dass ein konstantes Zahlverhalten (wie in der durchgeführten Analyse) der Kunden in der Regel nicht zugrunde zu legen ist.

Die analytischen und statistischen Möglichkeiten, die die Sprache R bietet, sind sehr umfangreich und werden durch eine aktive Community ständig erweitert. Neue Algorithmen im Bereich Data Mining werden häufig als erstes in R implementiert, was die Sprache besonders interessant macht. Sie ist frei verfügbar und hilft sowohl bei der Bildung von Modellen als auch bei deren Auswertung.

Dr. Ralf Ehret
arbeitete von 1991 bis 1998 am europäischen Teilchenforschungszentrum CERN an Datenanalysen bevor er zur SAP AG wechselte. Dort beschäftigte er sich unter anderem mit dem Thema Predicitve Analytics für die HANA-In-Memory-Technik.

Benjamin Graf
entwickelt als Data Scientist bei der SAP AG statistische Algorithmen und Prognosemodelle auf der HANA-Plattform. Vor seiner Tätigkeit bei SAP beschäftigte er sich an der Universität von Edinburgh mit automatischer Übersetzung und maschinellem Lernen.

  1. H. Steinhaus; Sur la division des corps matériels en parties; Bull. Acad. Polon. Sci.. 4, p. 801-804, 1957
  2. C. Fraley, A. E. Raftery; MCLUST Version 3 for R: Normal Mixture Modeling and Model-Based Clustering; Technical Report no. 504, 2006, revised 2010
  3. C. Fraley, A. E. Raftery; Model-based clustering, discriminant analysis, and density estimation; Journal of the American Statistical Association 97, pp. 611-631, 2002
  4. R. I. Kabacoff ; R in Action – Data analysis and graphics with R; Manning, 2011
  5. S. P. Lloyd; Least squares quantization in PCM; IEEE Transactions on Information Theory. 28, p. 129-137, 1982
  6. S. P. Lloyd; Least square quantization in PCM ,1957
  7. J. Adler; R in a Nutshell – A Desktop Quick Reference; O'Reilly, 2010
  8. R-Manual: An Introduction to R

Der größte Vorteil von R gegenüber kommerziellen Statistik-Angeboten ist die freie Verfügbarkeit von zusätzlichen Paketen. Sie lassen sich von der Konsole aus mit dem Befehl install.package("Paketname") installieren. Liegt bei der Installation des ersten Paketes keine ausreichende Berechtigung im Standardinstallationsverzeichnis vor, kann man sich während der Installation ein eigenes Nutzerverzeichnis erstellen lassen. Bei der Installation werden Abhängigkeiten zu anderen Paketen berücksichtigt. In RStudio geht die Installation noch einfacher: Im rechten unteren Fenster die Registerkarte Packages auswählen und dort auf "Install Packages" klicken.

Nach der Installation lassen sich die Pakete mit dem Befehl library(Paketname) laden. Neben den im Text genannten Paketen könnten auch die folgenden von Interesse sein (eine vollständige Liste findet man auf der CRAN Homepage unter dem Link Packages):

  • quantmod: Quantitative Finanzmodelle – mit recht einfachen Mitteln lassen sich Finanzdaten online von Yahoo und Google Finance herunterladen und analysieren. Mit den Befehlen > DAX <- getSymbols("^GDAXI", auto.assign = FALSE) > plot(DAX$GDAXI.Close) liest man zum Beispiel alle Kurse des DAX seit 2007 und plottet die Schlusskurse.
  • bigmemory: Sollten die Daten nicht in den Hauptspeicher passen.
  • XML: Tools zum Parsen und Erzeugen von XML in R.
  • sqldf: SQL auf Data
  • DBI: Datenbank Interface

(jul)