Wann immer ich etwas "map" py in R machen möchte, versuche ich normalerweise, eine Funktion in der apply
Familie zu verwenden.
Ich habe jedoch die Unterschiede zwischen ihnen nie ganz verstanden - wie { sapply
, lapply
usw.} die Funktion auf die Eingabe / gruppierte Eingabe anwenden, wie die Ausgabe aussehen wird oder sogar wie die Eingabe sein kann - so habe ich es oft getan Gehen Sie sie einfach alle durch, bis ich das bekomme, was ich will.
Kann jemand erklären, wie man welches wann benutzt?
Mein aktuelles (wahrscheinlich falsches / unvollständiges) Verständnis ist ...
sapply(vec, f)
: Eingabe ist ein Vektor. Die Ausgabe ist ein Vektor / eine Matrix, wobei sich das Elementi
befindet.f(vec[i])
Wenn Sie einef
Ausgabe mit mehreren Elementen haben , erhalten Sie eine Matrixlapply(vec, f)
: wiesapply
, aber Ausgabe ist eine Liste?apply(matrix, 1/2, f)
: Eingabe ist eine Matrix. Ausgabe ist ein Vektor, wobei Elementi
f ist (Zeile / Spalte i der Matrix)tapply(vector, grouping, f)
: output ist eine Matrix / ein Array, wobei ein Element in der Matrix / dem Array der Wertf
einer Gruppierungg
des Vektors ist undg
in die Zeilen- / Spaltennamen verschoben wirdby(dataframe, grouping, f)
: Seig
eine Gruppierung. geltenf
für jede Spalte der Gruppe / des Datenrahmens. Drucken Sie die Gruppierung und den Wertf
jeder Spalte hübsch aus .aggregate(matrix, grouping, f)
: Ähnlich wieby
, aber anstatt die Ausgabe hübsch zu drucken, steckt das Aggregat alles in einen Datenrahmen.
Nebenfrage: Ich habe Plyr noch nicht gelernt oder umgeformt - würde plyr
oder würde ich reshape
all dies komplett ersetzen?
*apply()
undby
. plyr (zumindest für mich) scheint viel konsistenter zu sein, da ich immer genau weiß, welches Datenformat es erwartet und was es genau ausspucken wird. Das erspart mir viel Ärger.doBy
und die Auswahl- und Anwendungsfunktionen vondata.table
.sapply
ist nurlapply
mit der Hinzufügung vonsimplify2array
auf dem Ausgang.apply
Zwingt zum Atomvektor, aber die Ausgabe kann ein Vektor oder eine Liste sein.by
teilt Datenrahmen in Unterdatenrahmen auf, wird jedoch nichtf
separat für Spalten verwendet. Nur wenn es eine Methode für die 'data.frame'-Klasse gibt, wird diese möglicherweisef
spaltenweise angewendetby
.aggregate
ist generisch, so dass für verschiedene Klassen des ersten Arguments unterschiedliche Methoden existieren.Antworten:
R hat viele * Apply-Funktionen, die in den Hilfedateien (z
?apply
. B. ) ausführlich beschrieben sind . Es gibt jedoch genug davon, so dass es für Anfänger schwierig sein kann, zu entscheiden, welche für ihre Situation geeignet ist, oder sich sogar an sie alle zu erinnern. Sie mögen allgemein den Eindruck haben, dass "ich hier eine * Apply-Funktion verwenden sollte", aber es kann schwierig sein, sie zunächst alle gerade zu halten.Trotz der Tatsache (in anderen Antworten vermerkt), dass ein Großteil der Funktionalität der * apply-Familie durch das äußerst beliebte
plyr
Paket abgedeckt wird , bleiben die Basisfunktionen nützlich und wissenswert.Diese Antwort soll als eine Art Wegweiser für neue Benutzer dienen, um sie auf die richtige * Apply-Funktion für ihr bestimmtes Problem hinzuweisen. Beachten Sie, dass dies nicht dazu gedacht ist, die R-Dokumentation einfach wieder zu erbrechen oder zu ersetzen! Die Hoffnung ist, dass diese Antwort Ihnen hilft, zu entscheiden, welche * Apply-Funktion zu Ihrer Situation passt, und dann liegt es an Ihnen, sie weiter zu erforschen. Mit einer Ausnahme werden Leistungsunterschiede nicht berücksichtigt.
anwenden - Wenn Sie eine Funktion auf die Zeilen oder Spalten einer Matrix (und höherdimensionale Analoga) anwenden möchten; Im Allgemeinen nicht empfehlenswert für Datenrahmen, da diese zuerst zu einer Matrix gezwungen werden.
Wenn Sie Zeilen / Spalten - Mittel oder Summen für eine 2D - Matrix möchten, müssen Sie die hochoptimierte, blitzschnell untersuchen
colMeans
,rowMeans
,colSums
,rowSums
.lapply - Wenn Sie nacheinander eine Funktion auf jedes Element einer Liste anwenden und eine Liste zurückerhalten möchten.
Dies ist das Arbeitstier vieler anderer * Apply-Funktionen. Ziehen Sie ihren Code zurück und Sie werden ihn oft
lapply
darunter finden .sapply - Wenn Sie nacheinander eine Funktion auf jedes Element einer Liste anwenden möchten, aber einen Vektor anstelle einer Liste zurückhaben möchten .
Wenn Sie tippen
unlist(lapply(...))
, hören Sie auf und überlegen Siesapply
.Bei fortgeschritteneren Anwendungen
sapply
wird versucht, das Ergebnis gegebenenfalls in ein mehrdimensionales Array zu zwingen. Wenn unsere Funktion beispielsweise Vektoren gleicher Länge zurückgibt,sapply
werden sie als Spalten einer Matrix verwendet:Wenn unsere Funktion eine zweidimensionale Matrix zurückgibt,
sapply
wird sie im Wesentlichen dasselbe tun und jede zurückgegebene Matrix als einen einzelnen langen Vektor behandeln:Sofern nicht
simplify = "array"
anders angegeben , werden in diesem Fall die einzelnen Matrizen verwendet, um ein mehrdimensionales Array zu erstellen:Jedes dieser Verhaltensweisen hängt natürlich davon ab, dass unsere Funktion Vektoren oder Matrizen gleicher Länge oder Dimension zurückgibt.
vapply - Wenn Sie verwenden möchten, aber möglicherweise etwas mehr Geschwindigkeit aus Ihrem Code herausholen müssen.
sapply
Für
vapply
geben R Sie im Grunde ein Beispiel , welche Art von Sache zurückkehren Ihre Funktion, die einige Zeit Nötigung zurückgegebenen Werte speichern können in einem einzigen Atom-Vektor passen.Mapply - Wenn Sie mehrere Datenstrukturen haben (z. B. Vektoren, Listen) und eine Funktion auf die ersten Elemente von jedem und dann auf die zweiten Elemente von jedem usw. anwenden möchten, um das Ergebnis wie in einem Vektor / Array zu erzwingen
sapply
.Dies ist in dem Sinne multivariat, dass Ihre Funktion mehrere Argumente akzeptieren muss.
Map - Ein Wrapper,
mapply
mit demSIMPLIFY = FALSE
garantiert wird, dass eine Liste zurückgegeben wird.rapply - Wenn Sie eine Funktion rekursiv auf jedes Element einer verschachtelten Listenstruktur anwenden möchten .
Um Ihnen eine Vorstellung davon zu geben, wie ungewöhnlich es
rapply
ist, habe ich es beim ersten Posten dieser Antwort vergessen! Natürlich bin ich sicher, dass viele Leute es benutzen, aber YMMV.rapply
wird am besten mit einer benutzerdefinierten Funktion veranschaulicht, die angewendet werden soll:tapply - Wenn Sie eine Funktion auf Teilmengen eines Vektors anwenden möchten und die Teilmengen durch einen anderen Vektor definiert werden, normalerweise einen Faktor.
Die schwarzen Schafe der * bewerben Familie. Die Verwendung des Ausdrucks "zerlumptes Array" in der Hilfedatei kann etwas verwirrend sein , ist aber eigentlich recht einfach.
Ein Vektor:
Ein Faktor (von gleicher Länge!), Der Gruppen definiert:
Addieren Sie die Werte in
x
jeder Untergruppe, die definiert ist durchy
:Komplexere Beispiele können behandelt werden, wenn die Untergruppen durch die eindeutigen Kombinationen einer Liste mehrerer Faktoren definiert sind.
tapply
ähnlich ist die Split-apply-Mähdrescherfunktionen im Geist , die gemeinsam in R (aggregate
,by
,ave
,ddply
Status, etc.) Daher ihr schwarze Schafe.quelle
by
rein gespalten ist undaggregate
sichtapply
in ihren Kernen befindet. Ich denke, schwarze Schafe sind ein ausgezeichneter Stoff.aggregate
undby
auch? (Ich verstehe sie schließlich nach Ihrer Beschreibung!, Aber sie sind ziemlich häufig, so dass es nützlich sein könnte, einige spezifische Beispiele für diese beiden Funktionen herauszulösen und zu haben.)aggregate
,by
etc. basiert auf * an Funktionen, wie du sie mit anderem Ansatz genug von einem Benutzer Perspektive ist , dass sie sollten in einer separaten Antwort zusammengefasst werden. Ich kann das versuchen, wenn ich Zeit habe, oder vielleicht schlägt mich jemand anderes und verdient meine Gegenstimme.?Map
als Verwandter vonmapply
data.frame
s sind ein absolut zentraler Bestandteil von R und werden alslist
Objekt häufig mitlapply
besonders manipuliert . Sie dienen auch als Container zum Gruppieren von Vektoren / Faktoren vieler Typen in einem herkömmlichen rechteckigen Datensatz. Währenddata.table
undplyr
möglicherweise eine bestimmte Art von Syntax hinzugefügt wird, die einige möglicherweise als komfortabler empfinden, erweitern und wirken sie aufdata.frame
s.Nebenbei bemerkt, hier ist, wie die verschiedenen
plyr
Funktionen den Basisfunktionen entsprechen*apply
(vom Intro bis zum Plyr-Dokument von der Plyr-Webseite http://had.co.nz/plyr/ ).Eines der Ziele von
plyr
ist es, konsistente Namenskonventionen für jede der Funktionen bereitzustellen und die Eingabe- und Ausgabedatentypen im Funktionsnamen zu codieren. Es bietet auch Konsistenz in der Ausgabe, da die Ausgabe vondlply()
leicht passierbar istldply()
, um nützliche Ausgabe usw. zu erzeugen.Konzeptionell ist das Lernen
plyr
nicht schwieriger als das Verstehen der*apply
Basisfunktionen.plyr
undreshape
Funktionen haben fast alle diese Funktionen in meinem täglichen Gebrauch ersetzt. Aber auch aus dem Intro to Plyr-Dokument:quelle
*apply()
Funktionsfamilie. Für michddply()
war das sehr intuitiv, da ich mit SQL-Aggregationsfunktionen vertraut war.ddply()
wurde mein Hammer für die Lösung vieler Probleme, von denen einige mit anderen Befehlen besser hätten gelöst werden können.plyr
Funktionen Funktionen ähnelt.*apply
Wenn Sie also eine ausführen können, können Sie die andere ausführen, aberplyr
Funktionen sind leichter zu merken. Aber ich stimme demddply()
Hammer voll und ganz zu !join()
Funktion, die ähnliche Aufgaben wie das Zusammenführen ausführt. Vielleicht ist es mehr auf den Punkt, es im Zusammenhang mit Plyr zu erwähnen.eapply
vapply
und die Nachteile von heruntersapply
. Ein Hauptvorteil vonvapply
ist, dass es den Ausgabetyp und die Ausgabelänge erzwingt, sodass Sie entweder die genaue erwartete Ausgabe oder einen informativen Fehler erhalten. Auf der anderen Seitesapply
wird versucht, die Ausgabe nach Regeln zu vereinfachen, die nicht immer offensichtlich sind, und ansonsten auf eine Liste zurückzugreifen. Versuchen Sie beispielsweise, die Art der Ausgabe vorherzusagen, die dadurch erzeugt wird :sapply(list(1:5, 6:10, matrix(1:4, 2)), function(x) head(x, 1))
. Was ist mitsapply(list(matrix(1:4, 2), matrix(1:4, 2)), ...)
?Aus Folie 21 von http://www.slideshare.net/hadley/plyr-one-data-analytic-strategy :
(Hoffentlich ist klar, dass dies
apply
@ Hadleysaaply
undaggregate
@ Hadleysddply
usw. entspricht. Folie 20 derselben Diashow verdeutlicht, wenn Sie es nicht von diesem Bild erhalten.)(links wird eingegeben, oben wird ausgegeben)
quelle
Beginnen Sie zuerst mit Jorans hervorragender Antwort - zweifelhaft, dass irgendetwas das verbessern kann.
Dann können die folgenden Mnemoniken helfen, sich an die Unterschiede zwischen den einzelnen zu erinnern. Während einige offensichtlich sind, mögen andere weniger sein - für diese finden Sie Rechtfertigung in Jorans Diskussionen.
Mnemonik
lapply
ist eine Liste , die auf eine Liste oder einen Vektor einwirkt und eine Liste zurückgibt.sapply
ist eine einfachelapply
(Funktion gibt standardmäßig einen Vektor oder eine Matrix zurück, wenn möglich)vapply
ist eine verifizierte Anwendung (ermöglicht die Vorgabe des Rückgabeobjekttyps)rapply
ist eine rekursive Anwendung für verschachtelte Listen, dh Listen innerhalb von Listentapply
ist eine getaggte Anwendung, bei der die Tags die Teilmengen identifizierenapply
ist generisch : Wendet eine Funktion auf die Zeilen oder Spalten einer Matrix an (oder allgemeiner auf die Dimensionen eines Arrays).Den richtigen Hintergrund schaffen
Wenn sich die Nutzung der
apply
Familie für Sie immer noch etwas fremd anfühlt, fehlt Ihnen möglicherweise eine wichtige Sichtweise.Diese beiden Artikel können helfen. Sie liefern den notwendigen Hintergrund, um die funktionalen Programmiertechniken zu motivieren , die von der
apply
Funktionsfamilie bereitgestellt werden .Benutzer von Lisp werden das Paradigma sofort erkennen. Wenn Sie mit Lisp nicht vertraut sind, haben Sie, sobald Sie sich mit FP vertraut gemacht haben, eine leistungsstarke Sichtweise für die Verwendung in R gewonnen - und dies
apply
wird viel sinnvoller sein.quelle
Da habe ich festgestellt, dass (die sehr ausgezeichneten) Antworten dieses Beitrags fehlen
by
undaggregate
Erklärungen. Hier ist mein Beitrag.DURCH
Die
by
in der Dokumentation angegebene Funktion kann jedoch als "Wrapper" fürtapply
. Die Kraft vonby
entsteht, wenn wir eine Aufgabe berechnen wollen,tapply
die nicht erledigt werden kann. Ein Beispiel ist dieser Code:Wenn wir diese beiden Objekte drucken
ct
undcb
"im Wesentlichen" die gleichen Ergebnisse erzielen und die einzigen Unterschiede darin bestehen, wie sie angezeigt werden und in welchen unterschiedlichenclass
Attributenby
fürcb
undarray
fürct
.Wie ich schon sagte,
by
entsteht die Kraft von , wenn wir nicht nutzen könnentapply
; Der folgende Code ist ein Beispiel:R sagt, dass Argumente die gleiche Länge haben müssen, sagen wir "wir wollen die
summary
aller Variableniris
entlang des Faktors berechnenSpecies
": aber R kann das einfach nicht, weil es nicht weiß, wie es zu handhaben ist.Mit der
by
Funktion R wird eine bestimmte Methode für diedata frame
Klasse ausgelöst und diesummary
Funktion dann auch dann funktionieren gelassen , wenn die Länge des ersten Arguments (und auch der Typ) unterschiedlich sind.es funktioniert in der Tat und das Ergebnis ist sehr überraschend. Es ist ein Objekt der Klasse
by
, das zusammenSpecies
(etwa für jedes von ihnen) dassummary
von jeder Variablen berechnet .Beachten Sie, dass
data frame
die ausgelöste Funktion eine Methode für diese Objektklasse haben muss , wenn das erste Argument a ist . Zum Beispiel verwenden wir diesen Code mit dermean
Funktion, dass wir diesen Code haben, der überhaupt keinen Sinn hat:AGGREGAT
aggregate
kann als eine andere Art der Verwendung angesehen werden,tapply
wenn wir es so verwenden.Die beiden unmittelbaren Unterschiede sind , dass das zweite Argument der
aggregate
muss eine Liste sein , währendtapply
kann (nicht zwingend) eine Liste sein und dass der Ausgangaggregate
ist ein Datenrahmen , während der eine vontapply
einem istarray
.Die Stärke von
aggregate
ist, dass es leicht Teilmengen der Daten mitsubset
Argumenten verarbeiten kann und dass es Methoden fürts
Objekte undformula
auch hat.Diese Elemente
aggregate
erleichterntapply
in einigen Situationen die Arbeit damit . Hier einige Beispiele (in der Dokumentation verfügbar):Wir können dasselbe erreichen,
tapply
aber die Syntax ist etwas schwieriger und die Ausgabe (unter bestimmten Umständen) weniger lesbar:Es gibt andere Zeiten, in denen wir nicht verwenden können
by
odertapply
müssenaggregate
.Wir können das vorherige Ergebnis nicht mit
tapply
einem Aufruf erhalten, aber wir müssen den MittelwertMonth
für jedes Element berechnen und dann kombinieren (beachten Sie auch, dass wir das aufrufen müssenna.rm = TRUE
, da dieformula
Methoden deraggregate
Funktion standardmäßig das habenna.action = na.omit
):Während
by
wir dies einfach nicht erreichen können, gibt der folgende Funktionsaufruf einen Fehler zurück (aber höchstwahrscheinlich hängt er mit der bereitgestellten Funktion zusammenmean
):In anderen Fällen sind die Ergebnisse gleich und die Unterschiede liegen nur in der Klasse (und dann, wie es angezeigt / gedruckt wird und nicht nur - Beispiel, wie man es untergibt) Objekt:
Der vorherige Code erreicht das gleiche Ziel und die gleichen Ergebnisse. An einigen Stellen ist das zu verwendende Tool nur eine Frage des persönlichen Geschmacks und der persönlichen Bedürfnisse. Die beiden vorherigen Objekte haben sehr unterschiedliche Anforderungen an die Teilmenge.
quelle
data.frame(tapply(unlist(iris[,-5]),list(rep(iris[,5],ncol(iris[-5])),col(iris[-5])),summary))
dies eine Verwendung von tapply. With the right splitting there is nothing you cant do with
tapply. The only thing is it returns a matrix. Please be careful by saying we cant use
tapply`Es gibt viele gute Antworten, die Unterschiede in den Anwendungsfällen für jede Funktion diskutieren. In keiner der Antworten werden die Leistungsunterschiede erörtert. Dies ist sinnvoll, da verschiedene Funktionen unterschiedliche Eingaben erwarten und unterschiedliche Ausgaben erzeugen. Die meisten von ihnen haben jedoch ein allgemeines gemeinsames Ziel, sie nach Serien / Gruppen zu bewerten. Meine Antwort wird sich auf die Leistung konzentrieren. Aufgrund der obigen Angaben ist die Eingabeerstellung aus den Vektoren im Timing enthalten, auch die
apply
Funktion wird nicht gemessen.Ich habe zwei verschiedene Funktionen getestet
sum
undlength
auf einmal. Das getestete Volumen beträgt 50 M am Eingang und 50 K am Ausgang. Ich habe auch zwei derzeit beliebte Pakete aufgenommen, die zu dem Zeitpunkt, als die Frage gestellt wurde, nicht weit verbreitet waren,data.table
unddplyr
. Beides ist auf jeden Fall einen Blick wert, wenn Sie eine gute Leistung anstreben.quelle
Trotz all der tollen Antworten hier gibt es zwei weitere Basisfunktionen, die es zu erwähnen gilt, die nützliche
outer
Funktion und die obskureeapply
Funktionäußere
outer
ist eine sehr nützliche Funktion, die als weltlichere verborgen ist. Wenn Sie die Hilfe fürouter
die Beschreibung lesen, heißt es:was es so erscheinen lässt, ist nur für Dinge vom Typ lineare Algebra nützlich. Es kann jedoch ähnlich verwendet werden
mapply
, um eine Funktion auf zwei Vektoren von Eingaben anzuwenden. Der Unterschied besteht darin, dassmapply
die Funktion auf die ersten beiden Elemente und dann auf die zweiten beiden usw. angewendetouter
wird , während die Funktion auf jede Kombination eines Elements aus dem ersten Vektor und eines aus dem zweiten angewendet wird. Zum Beispiel:Ich persönlich habe dies verwendet, wenn ich einen Wertevektor und einen Vektor von Bedingungen habe und sehen möchte, welche Werte welche Bedingungen erfüllen.
eifrig
eapply
ist solapply
, als würde eine Funktion nicht auf jedes Element in einer Liste angewendet, sondern auf jedes Element in einer Umgebung. Wenn Sie beispielsweise eine Liste benutzerdefinierter Funktionen in der globalen Umgebung suchen möchten:Ehrlich gesagt benutze ich das nicht sehr oft, aber wenn Sie viele Pakete erstellen oder viele Umgebungen erstellen, kann es nützlich sein.
quelle
Es ist vielleicht erwähnenswert
ave
.ave
isttapply
der freundliche Cousin. Es gibt Ergebnisse in einem Formular zurück, das Sie direkt wieder in Ihren Datenrahmen einfügen können.Das Basispaket enthält nichts, was
ave
für ganze Datenrahmen funktioniert (by
wietapply
für Datenrahmen). Aber Sie können es fummeln:quelle
Ich habe kürzlich die ziemlich nützliche
sweep
Funktion entdeckt und der Vollständigkeit halber hier hinzugefügt:fegen
Die Grundidee besteht darin , ein Array zeilen- oder spaltenweise zu durchlaufen und ein modifiziertes Array zurückzugeben. Ein Beispiel wird dies verdeutlichen (Quelle: Datencamp ):
Angenommen, Sie haben eine Matrix und möchten diese spaltenweise standardisieren :
NB: Für dieses einfache Beispiel kann das gleiche Ergebnis natürlich leichter erzielt werden durch
apply(dataPoints, 2, scale)
quelle
sweep
ist eine Funktion höherer Ordnung wie alle anderen hier erwähnten, zum Beispielapply
,sapply
,lapply
also die gleiche Frage über die akzeptierte Antwort mit über 1.000 upvotes und die Beispiele darin gegeben gestellt werden könnten. Schauen Sie sich einfach das dort gegebene Beispiel anapply
.sweep(matrix(1:6,nrow=2),2,7:9,list)
. Es ist normalerweise effizienter alsapply
weil woapply
Schleifensweep
vektorisierte Funktionen verwenden können.In dem kürzlich auf CRAN veröffentlichten Collapse- Paket habe ich versucht, die meisten gängigen Apply-Funktionen in nur zwei Funktionen zu komprimieren:
dapply
(Data-Apply) wendet Funktionen auf Zeilen oder (Standard-) Spalten von Matrizen und data.frames an und (Standard) gibt ein Objekt desselben Typs und mit denselben Attributen zurück (es sei denn, das Ergebnis jeder Berechnung ist atomar unddrop = TRUE
). Die Leistung ist vergleichbar mitlapply
von data.frame-Spalten und etwa zweimal schneller alsapply
bei Matrixzeilen oder -spalten . Parallelität ist übermclapply
(nur für MAC) verfügbar .Syntax:
Beispiele:
BY
ist ein S3-Generikum für Split-Apply-Combine-Computing mit Vektor-, Matrix- und Data.frame-Methode. Es ist deutlich schneller alstapply
,by
undaggregate
(ein auch schneller alsplyr
auf große Datendplyr
schneller obwohl).Syntax:
Beispiele:
Es können auch Listen mit Gruppierungsvariablen bereitgestellt werden
g
.Apropos Leistung: Ein Hauptziel des Zusammenbruchs besteht darin, die Hochleistungsprogrammierung in R zu fördern und über das Split-Apply-Combine-Kombinieren hinauszugehen. Zu diesem Zweck hat das Paket eine ganze Reihe von C ++ basierten schnell generische Funktionen:
fmean
,fmedian
,fmode
,fsum
,fprod
,fsd
,fvar
,fmin
,fmax
,ffirst
,flast
,fNobs
,fNdistinct
,fscale
,fbetween
,fwithin
,fHDbetween
,fHDwithin
,flag
,fdiff
undfgrowth
. Sie führen gruppierte Berechnungen in einem einzigen Durchgang durch die Daten durch (dh keine Aufteilung und Rekombination).Syntax:
Beispiele:
In den Paketvignetten gebe ich Benchmarks an. Das Programmieren mit den schnellen Funktionen ist erheblich schneller als das Programmieren mit dplyr oder data.table , insbesondere bei kleineren Daten, aber auch bei großen Datenmengen.
quelle