Dieses data.table-R-Tutorial erklärt die Grundlagen des DT[i, j, by]-Befehls, der das Herzstück des data.table-Pakets ist. Wenn du mehr über das data.table-Paket lernen möchtest, bietet DataCamp einen interaktiven R-Kurs zum data.table-Paket an. Der Kurs enthält mehr als 35 interaktive R-Übungen – alle bequem im Browser – und mehrere Videos mit Matt Dowle, dem Hauptautor des data.table-Pakets, und Arun Srinivasan, einem wichtigen Mitwirkenden. Probiere es kostenlos aus.
Wenn du bereits mit großen Datensätzen im RAM gearbeitet hast (1 bis über 100 GB), weißt du, dass ein data.frame an Grenzen stößt: Bestimmte Operationen dauern einfach zu lange. Data.table löst dieses Problem, indem es die Rechenzeit reduziert. Außerdem kannst du mit weniger Tippen mehr erreichen. Sobald du die data.table-Syntax aus diesem R-Tutorial verinnerlicht hast, wird dich die Leichtigkeit komplexer Operationen überraschen. Du sparst also nicht nur Rechen-, sondern auch Programmierzeit.
Der Befehl DT[i,j,by] hat drei Teile: i, j und by. In SQL-Begriffen entspricht i dem WHERE, j dem SELECT und by dem GROUP BY. Man kann den Befehl so lesen: „Nimm DT, filtere die Zeilen mit ‚i‘ und berechne dann ‚j‘ gruppiert nach ‚by‘.“ Ein einfaches Beispiel mit dem hflights-Datensatz (damit du alles nachbauen kannst) ergibt:
library(hflights)
library(data.table)
DT <- as.data.table(hflights)
DT[Month==10,mean(na.omit(AirTime)), by=UniqueCarrier]Bereitgestellt von
UniqueCarrier V1
AA 68.76471
AS 255.29032
B6 176.93548
CO 141.52861...Bereitgestellt von
Hier haben wir die Tabelle auf den 10. Monat des Jahres eingeschränkt, die durchschnittliche AirTime der tatsächlich geflogenen Flüge berechnet (daher na.omit(); stornierte Flüge haben keinen AirTime-Wert) und die Ergebnisse nach Carrier gruppiert. Man sieht zum Beispiel, dass AA (American Airlines) im Schnitt deutlich kürzere Flugzeiten hat als AS (Alaska Airlines). Ist dir außerdem aufgefallen, dass Basisfunktionen aus R im j-Teil verwendet werden können? Darauf kommen wir gleich zurück.
Der i-Teil
Der ‚i‘-Teil dient zum Zeilen-Subsetting, genau wie bei einem data frame.
#Returns all those rows where the Carrier is American Airlines
Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier FlightNum TailNum ActualElapsedTime
201111614001500 AA 428 N576AA 60201112714011501 AA 428 N557AA 60201113113521502 AA 428 N541AA 70201114214031513 AA 428 N403AA 70201115314051507 AA 428 N492AA 62---20111227210211333 AA 2234 N3ETAA 13220111228310151329 AA 2234 N3FJAA 13420111229410231335 AA 2234 N3GSAA 13220111230510241334 AA 2234 N3BAAA 13020111231610241343 AA 2234 N3HNAA 139
AirTime ArrDelay DepDelay Origin Dest Distance TaxiIn TaxiOut Cancelled CancellationCode Diverted
40-100 IAH DFW 2247130045-91 IAH DFW 224690048-8-8 IAH DFW 224517003933 IAH DFW 2249220044-35 IAH DFW 2249900---112-121 IAH MIA 96481200112-16-5 IAH MIA 96491300110-103 IAH MIA 964121000110-114 IAH MIA 96491100119-24 IAH MIA 96481200Bereitgestellt von
Beachte, dass du kein Komma zum Zeilensubsetting in einer data.table brauchst. In einem data.frame würde DF[2:5] alle Zeilen der 2. bis 5. Spalte zurückgeben. Stattdessen müssen wir (wie allen hier klar ist) DF[2:5,] angeben. Beachte auch, dass DT[,2:5] bei data.tables nichts bedeutet; das wird in der ersten Frage der FAQs des data.table-Pakets erklärt.
Ungewöhnlich und nützlich: Beim Zeilensubsetting kannst du auch das Symbol .N im Befehl DT[…] verwenden; es steht für die Zeilenanzahl bzw. die letzte Zeile. Damit kannst du die letzte Zeile oder einen Versatz davon auswählen.
#Returns the penultimate row of DT
Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier FlightNum TailNum ActualElapsedTime AirTime
20111262656812 WN 621 N727SW 7664
ArrDelay DepDelay Origin Dest Distance TaxiIn TaxiOut Cancelled CancellationCode Diverted
-13-4 HOU TUL 4533900Bereitgestellt von
Der j-Teil
Der ‚j‘-Teil dient dazu, Spalten auszuwählen und etwas damit zu machen. Und etwas kann wirklich alles Mögliche sein. Alle Arten von Funktionen lassen sich verwenden – ein echtes Plus von data.table.
Beachte, dass der ‚i‘-Teil leer ist und das erste Zeichen in der Klammer ein Komma ist. Das wirkt anfangs etwas kontraintuitiv. Es bedeutet schlicht, dass wir keine Zeilen einschränken – also alle Zeilen verwenden. Im ‚j‘-Teil wird dann die durchschnittliche Verspätung bei der Ankunft aller Flüge berechnet. Offenbar hatten die Flüge im hflights-Datensatz im Schnitt mehr als 7 Minuten Verspätung. Plane das bei deinem nächsten Flug ein!
Wenn du mehrere Spalten auswählst und im ‚j‘-Teil etwas damit machst, musst du die ‚.()‘-Notation verwenden. Diese ist lediglich ein Alias für ‚list()‘. Sie liefert eine data.table zurück, während ohne ‚.()‘ – wie oben gezeigt – nur ein Vektor zurückkommt.
DT[, .(mean(na.omit(DepDelay)), mean(na.omit(ArrDelay)))]Bereitgestellt von
Die obigen Punkte zu ‚i‘ und ‚j‘ kombiniert ergeben:
DT[UniqueCarrier=="AA", .(Avg_DepDelay =
mean(na.omit(DepDelay)),
Avg_ArrDelay = mean(na.omit(ArrDelay)),
plot(DepTime,DepDelay,ylim=c(-15,200)),
abline(h=0))]Bereitgestellt von
Avg_DepDelay Avg_ArrDelay V3 V4
6.3901440.8917558NULLNULLBereitgestellt von
Hier haben wir im ‚i‘-Teil alle Zeilen mit Carrier AA ausgewählt, im ‚j‘-Teil die durchschnittliche Abflug- und Ankunftsverspätung berechnet und außerdem Abflugzeit gegen Abflugverspätung geplottet.
Noch einmal zusammengefasst: Der ‚j‘-Teil dient dazu, Berechnungen auf den dort angegebenen Spalten auszuführen. Da die Spalten einer data.table wie Variablen behandelt werden und die Bestandteile von ‚j‘ als Ausdrücke ausgewertet werden, ist im ‚j‘-Teil praktisch alles möglich. Das verkürzt deine Programmierzeit deutlich.
Der by-Teil
Der letzte Abschnitt dieses data.table-R-Tutorials widmet sich dem ‚by‘-Teil. Den ‚by‘-Teil verwendest du, wenn du den ‚j‘-Ausdruck gruppiert nach einer bestimmten Variable (oder einer Transformation davon) berechnen willst. Du wirst sehen, dass der ‚j‘-Ausdruck für jede ‚by‘-Gruppe wiederholt wird. Die Nutzung ist simpel: Gib im ‚by‘-Argument einfach die Spalte an, nach der du gruppieren möchtest.
Hier haben wir die durchschnittliche Abflugverspätung berechnet, allerdings gruppiert nach dem Startflughafen. Offenbar sind Flüge ab HOU im Schnitt stärker verspätet als jene ab IAH.
Wie beim ‚j‘-Teil kannst du auch im ‚by‘-Teil eine Menge machen. Funktionen lassen sich im ‚by‘-Teil einsetzen, sodass die Ergebnisse aus dem ‚j‘-Teil nach etwas gruppiert werden, das wir innerhalb des DT[…]-Befehls festlegen. Funktionen direkt in DT[…] machen diese eine Zeile sehr mächtig. Wenn du mehrere Spalten im ‚by‘-Teil nutzt, brauchst du ebenfalls die ‚.()‘-Notation.
DT[,.(Avg_DepDelay_byWeekdays = mean(na.omit(DepDelay))), by=.(Origin,Weekdays = DayOfWeek<6)]Bereitgestellt von
Hier wurde zunächst die durchschnittliche Abflugverspätung aller Flüge berechnet (kein Subsetting im ‚i‘-Teil, also alle Zeilen), anschließend gruppiert – zuerst nach Startflughafen, dann nach Wochentag. Weekdays ist an Wochenenden False. Es zeigt sich, dass die Abflugverspätung ab HOU größer war als ab IAH, und überraschenderweise an Wochenenden geringer.
Alles zusammen ergibt ein typischer DT[i,j,by]-Befehl:
DT[UniqueCarrier=="DL", .(Avg_DepDelay =
mean(na.omit(DepDelay)),
Avg_ArrDelay = mean(na.omit(ArrDelay)),
Compensation = mean(na.omit(ArrDelay - DepDelay))), by = .(Origin, Weekdays = DayOfWeek&lt;6)]Bereitgestellt von
Hier wurde die Teilmenge der von Delta Air Lines geflogenen Flüge (ausgewählt in ‚i‘) nach Startflughafen und Weekdays gruppiert (in ‚by‘). Außerdem wurde die in der Luft „kompensierte“ Zeit berechnet (in ‚j‘). Es zeigt sich, dass an Wochenenden – unabhängig davon, ob der Flug von IAH oder HOU startete – die in der Luft aufgeholte Zeit größer ist.
Es gibt noch viel mehr im data.table-Paket zu entdecken, aber dieser Beitrag hat den grundlegenden DT[i,j,by]-Befehl veranschaulicht. Der DataCamp-Kurs erklärt das gesamte Paket ausführlich. Du kannst die Übungen in deinem eigenen Tempo im Browser bearbeiten, bekommst Tipps und Feedback und kannst Videos und Folien beliebig oft wiederholen. Dieses interaktive Lernen vermittelt dir fundiertes Wissen und praktische Erfahrung mit data.tables. Probiere es kostenlos aus. Sieh dir auch DataCamps data.table R Package Cheat Sheet an.
Hoffentlich verstehst du dank dieses data.table-R-Tutorials nun die grundlegende Syntax von data.table und bist bereit, selbst zu experimentieren. Wenn du Fragen zum data.table-Paket hast, schau hier vorbei. Matt und Arun sind sehr aktiv. Einer der nächsten Blogposts zum data.table-Paket wird technischer und zeigt die vielen Möglichkeiten von data.tables im Detail. Bleib dran!
Mach dich mit Python-Datenstrukturen vertraut: Lerne mehr über Datentypen und primitive sowie nicht-primitive Datenstrukturen wie Strings, Listen, Stapel usw.
Gewinne Vertrauen in die OLS-Regression, indem du ihre theoretischen Grundlagen beherrschst. Erforsche, wie du einfache Implementierungen in Excel, R und Python durchführst.
Ein umfassendes Einführungs-Tutorial zu Python-Schleifen. Lerne und übe while- und for-Schleifen, verschachtelte Schleifen, die Schlüsselwörter break und continue, die Range-Funktion und vieles mehr!
Dieses data.table-R-Tutorial erklärt die Grundlagen des
DT[i, j, by]-Befehls, der das Herzstück des data.table-Pakets ist. Wenn du mehr über das data.table-Paket lernen möchtest, bietet DataCamp einen interaktiven R-Kurs zum data.table-Paket an. Der Kurs enthält mehr als 35 interaktive R-Übungen – alle bequem im Browser – und mehrere Videos mit Matt Dowle, dem Hauptautor des data.table-Pakets, und Arun Srinivasan, einem wichtigen Mitwirkenden. Probiere es kostenlos aus.Wenn du bereits mit großen Datensätzen im RAM gearbeitet hast (1 bis über 100 GB), weißt du, dass ein
data.framean Grenzen stößt: Bestimmte Operationen dauern einfach zu lange. Data.table löst dieses Problem, indem es die Rechenzeit reduziert. Außerdem kannst du mit weniger Tippen mehr erreichen. Sobald du die data.table-Syntax aus diesem R-Tutorial verinnerlicht hast, wird dich die Leichtigkeit komplexer Operationen überraschen. Du sparst also nicht nur Rechen-, sondern auch Programmierzeit.Der Befehl
DT[i,j,by]hat drei Teile:i,jundby. In SQL-Begriffen entsprichtidem WHERE,jdem SELECT undbydem GROUP BY. Man kann den Befehl so lesen: „Nimm DT, filtere die Zeilen mit ‚i‘ und berechne dann ‚j‘ gruppiert nach ‚by‘.“ Ein einfaches Beispiel mit demhflights-Datensatz (damit du alles nachbauen kannst) ergibt:Hier haben wir die Tabelle auf den 10. Monat des Jahres eingeschränkt, die durchschnittliche AirTime der tatsächlich geflogenen Flüge berechnet (daher
na.omit(); stornierte Flüge haben keinen AirTime-Wert) und die Ergebnisse nach Carrier gruppiert. Man sieht zum Beispiel, dass AA (American Airlines) im Schnitt deutlich kürzere Flugzeiten hat als AS (Alaska Airlines). Ist dir außerdem aufgefallen, dass Basisfunktionen aus R imj-Teil verwendet werden können? Darauf kommen wir gleich zurück.Der i-Teil
Der ‚i‘-Teil dient zum Zeilen-Subsetting, genau wie bei einem data frame.
Du kannst auch Spaltennamen verwenden, da sie im Scope von DT ausgewertet werden.
Beachte, dass du kein Komma zum Zeilensubsetting in einer data.table brauchst. In einem data.frame würde
DF[2:5]alle Zeilen der 2. bis 5. Spalte zurückgeben. Stattdessen müssen wir (wie allen hier klar ist)DF[2:5,]angeben. Beachte auch, dassDT[,2:5]bei data.tables nichts bedeutet; das wird in der ersten Frage der FAQs des data.table-Pakets erklärt.Ungewöhnlich und nützlich: Beim Zeilensubsetting kannst du auch das Symbol
.Nim Befehl DT[…] verwenden; es steht für die Zeilenanzahl bzw. die letzte Zeile. Damit kannst du die letzte Zeile oder einen Versatz davon auswählen.Der j-Teil
Der ‚j‘-Teil dient dazu, Spalten auszuwählen und etwas damit zu machen. Und etwas kann wirklich alles Mögliche sein. Alle Arten von Funktionen lassen sich verwenden – ein echtes Plus von data.table.
Beachte, dass der ‚i‘-Teil leer ist und das erste Zeichen in der Klammer ein Komma ist. Das wirkt anfangs etwas kontraintuitiv. Es bedeutet schlicht, dass wir keine Zeilen einschränken – also alle Zeilen verwenden. Im ‚j‘-Teil wird dann die durchschnittliche Verspätung bei der Ankunft aller Flüge berechnet. Offenbar hatten die Flüge im hflights-Datensatz im Schnitt mehr als 7 Minuten Verspätung. Plane das bei deinem nächsten Flug ein!
Wenn du mehrere Spalten auswählst und im ‚j‘-Teil etwas damit machst, musst du die ‚
.()‘-Notation verwenden. Diese ist lediglich ein Alias für ‚list()‘. Sie liefert eine data.table zurück, während ohne ‚.()‘ – wie oben gezeigt – nur ein Vektor zurückkommt.Eine weitere nützliche Funktion, die die ‚
.()‘-Notation erfordert, erlaubt es dir, Spalten innerhalb des DT[…]-Befehls umzubenennen.Neue Spaltennamen sind natürlich optional.
Die obigen Punkte zu ‚i‘ und ‚j‘ kombiniert ergeben:
Hier haben wir im ‚i‘-Teil alle Zeilen mit Carrier AA ausgewählt, im ‚j‘-Teil die durchschnittliche Abflug- und Ankunftsverspätung berechnet und außerdem Abflugzeit gegen Abflugverspätung geplottet.
Noch einmal zusammengefasst: Der ‚j‘-Teil dient dazu, Berechnungen auf den dort angegebenen Spalten auszuführen. Da die Spalten einer data.table wie Variablen behandelt werden und die Bestandteile von ‚j‘ als Ausdrücke ausgewertet werden, ist im ‚j‘-Teil praktisch alles möglich. Das verkürzt deine Programmierzeit deutlich.
Der by-Teil
Der letzte Abschnitt dieses data.table-R-Tutorials widmet sich dem ‚by‘-Teil. Den ‚by‘-Teil verwendest du, wenn du den ‚j‘-Ausdruck gruppiert nach einer bestimmten Variable (oder einer Transformation davon) berechnen willst. Du wirst sehen, dass der ‚j‘-Ausdruck für jede ‚by‘-Gruppe wiederholt wird. Die Nutzung ist simpel: Gib im ‚by‘-Argument einfach die Spalte an, nach der du gruppieren möchtest.
Hier haben wir die durchschnittliche Abflugverspätung berechnet, allerdings gruppiert nach dem Startflughafen. Offenbar sind Flüge ab HOU im Schnitt stärker verspätet als jene ab IAH.
Wie beim ‚j‘-Teil kannst du auch im ‚by‘-Teil eine Menge machen. Funktionen lassen sich im ‚by‘-Teil einsetzen, sodass die Ergebnisse aus dem ‚j‘-Teil nach etwas gruppiert werden, das wir innerhalb des DT[…]-Befehls festlegen. Funktionen direkt in
DT[…]machen diese eine Zeile sehr mächtig. Wenn du mehrere Spalten im ‚by‘-Teil nutzt, brauchst du ebenfalls die ‚.()‘-Notation.Hier wurde zunächst die durchschnittliche Abflugverspätung aller Flüge berechnet (kein Subsetting im ‚i‘-Teil, also alle Zeilen), anschließend gruppiert – zuerst nach Startflughafen, dann nach Wochentag.
Weekdaysist an WochenendenFalse. Es zeigt sich, dass die Abflugverspätung ab HOU größer war als ab IAH, und überraschenderweise an Wochenenden geringer.Alles zusammen ergibt ein typischer
DT[i,j,by]-Befehl:Hier wurde die Teilmenge der von Delta Air Lines geflogenen Flüge (ausgewählt in ‚i‘) nach Startflughafen und
Weekdaysgruppiert (in ‚by‘). Außerdem wurde die in der Luft „kompensierte“ Zeit berechnet (in ‚j‘). Es zeigt sich, dass an Wochenenden – unabhängig davon, ob der Flug von IAH oder HOU startete – die in der Luft aufgeholte Zeit größer ist.Es gibt noch viel mehr im data.table-Paket zu entdecken, aber dieser Beitrag hat den grundlegenden
DT[i,j,by]-Befehl veranschaulicht. Der DataCamp-Kurs erklärt das gesamte Paket ausführlich. Du kannst die Übungen in deinem eigenen Tempo im Browser bearbeiten, bekommst Tipps und Feedback und kannst Videos und Folien beliebig oft wiederholen. Dieses interaktive Lernen vermittelt dir fundiertes Wissen und praktische Erfahrung mit data.tables. Probiere es kostenlos aus. Sieh dir auch DataCamps data.table R Package Cheat Sheet an.Hoffentlich verstehst du dank dieses data.table-R-Tutorials nun die grundlegende Syntax von data.table und bist bereit, selbst zu experimentieren. Wenn du Fragen zum data.table-Paket hast, schau hier vorbei. Matt und Arun sind sehr aktiv. Einer der nächsten Blogposts zum data.table-Paket wird technischer und zeigt die vielen Möglichkeiten von data.tables im Detail. Bleib dran!