Cours
Ce tutoriel R sur data.table présente les bases de la commande DT[i, j, by], au cœur du package data.table. Pour aller plus loin avec data.table, DataCamp propose un cours R interactif sur le package data.table. Le cours comprend plus de 35 exercices R interactifs — le tout directement dans votre navigateur — et plusieurs vidéos avec Matt Dowle, auteur principal de data.table, et Arun Srinivasan, contributeur majeur. Essayez-le gratuitement.
Si vous avez déjà travaillé avec de très grands jeux de données en mémoire (de 1 à plus de 100 Go), vous savez qu’un data.frame peut vite montrer ses limites : certaines opérations prennent beaucoup trop de temps. Data.table résout ce problème en réduisant les temps de calcul. Mieux encore, il permet d’en faire plus avec moins de saisie. Une fois la syntaxe data.table maîtrisée grâce à ce tutoriel R, la facilité avec laquelle vous réaliserez des opérations complexes va vous surprendre. Vous gagnerez ainsi à la fois en temps de calcul et en temps de développement.
La commande DT[i,j,by] comporte trois parties : i, j et by. En termes SQL, i correspond à WHERE, j à SELECT et by à GROUP BY. On énonce la commande ainsi : « Prenez DT, filtrez les lignes avec ‘i’, puis calculez ‘j’ en regroupant par ‘by’ ». Sur un exemple simple avec le jeu de données hflights (pour que vous puissiez tout reproduire), cela donne :
library(hflights)
library(data.table)
DT <- as.data.table(hflights)
DT[Month==10,mean(na.omit(AirTime)), by=UniqueCarrier]
UniqueCarrier V1
AA 68.76471
AS 255.29032
B6 176.93548
CO 141.52861
...
Ici, nous avons restreint la table aux vols du mois d’octobre, calculé le temps de vol moyen des avions qui ont effectivement volé (d’où l’usage de na.omit(), les vols annulés n’ayant pas de valeur d’AirTime), puis regroupé les résultats par compagnie. On observe par exemple que AA (American Airlines) affiche un AirTime moyen bien plus court que AS (Alaska Airlines). Avez-vous aussi remarqué que les fonctions de base R peuvent être utilisées dans la partie j ? Nous y reviendrons.
La partie i
La partie « i » sert à filtrer les lignes, comme dans un data frame.
DT[2:5]
#selects the second to the fifth row of DT
Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier FlightNum TailNum ActualElapsedTime AirTime
2011 1 2 7 1401 1501 AA 428 N557AA 60 45
2011 1 3 1 1352 1502 AA 428 N541AA 70 48
2011 1 4 2 1403 1513 AA 428 N403AA 70 39
2011 1 5 3 1405 1507 AA 428 N492AA 62 44
ArrDelay DepDelay Origin Dest Distance TaxiIn TaxiOut Cancelled CancellationCode Diverted
-9 1 IAH DFW 224 6 9 0 0
-8 -8 IAH DFW 224 5 17 0 0
3 3 IAH DFW 224 9 22 0 0
-3 5 IAH DFW 224 9 9 0 0
Vous pouvez aussi utiliser les noms de colonnes, car ils sont évalués dans l’environnement de DT.
DT[UniqueCarrier=="AA"]
#Returns all those rows where the Carrier is American Airlines
Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier FlightNum TailNum ActualElapsedTime
2011 1 1 6 1400 1500 AA 428 N576AA 60
2011 1 2 7 1401 1501 AA 428 N557AA 60
2011 1 3 1 1352 1502 AA 428 N541AA 70
2011 1 4 2 1403 1513 AA 428 N403AA 70
2011 1 5 3 1405 1507 AA 428 N492AA 62
---
2011 12 27 2 1021 1333 AA 2234 N3ETAA 132
2011 12 28 3 1015 1329 AA 2234 N3FJAA 134
2011 12 29 4 1023 1335 AA 2234 N3GSAA 132
2011 12 30 5 1024 1334 AA 2234 N3BAAA 130
2011 12 31 6 1024 1343 AA 2234 N3HNAA 139
AirTime ArrDelay DepDelay Origin Dest Distance TaxiIn TaxiOut Cancelled CancellationCode Diverted
40 -10 0 IAH DFW 224 7 13 0 0
45 -9 1 IAH DFW 224 6 9 0 0
48 -8 -8 IAH DFW 224 5 17 0 0
39 3 3 IAH DFW 224 9 22 0 0
44 -3 5 IAH DFW 224 9 9 0 0
---
112 -12 1 IAH MIA 964 8 12 0 0
112 -16 -5 IAH MIA 964 9 13 0 0
110 -10 3 IAH MIA 964 12 10 0 0
110 -11 4 IAH MIA 964 9 11 0 0
119 -2 4 IAH MIA 964 8 12 0 0
Notez que vous n’avez pas besoin de virgule pour filtrer les lignes dans une data table. Dans un data.frame, écrire DF[2:5] renverrait toutes les lignes des colonnes 2 à 5. À la place (comme vous le savez), il faut préciser DF[2:5,]. Notez aussi que DT[,2:5] n’a pas de sens pour les data tables, comme expliqué dans la première question de la FAQ du package data.table.
Astuce pratique : lors du filtrage des lignes, vous pouvez utiliser le symbole .N dans la commande DT[...], qui représente le nombre de lignes — et permet donc d’atteindre la dernière ligne. Vous pouvez l’utiliser pour sélectionner la dernière ligne ou un décalage par rapport à celle-ci.
DT[.N-1]
#Returns the penultimate row of DT
Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier FlightNum TailNum ActualElapsedTime AirTime
2011 12 6 2 656 812 WN 621 N727SW 76 64
ArrDelay DepDelay Origin Dest Distance TaxiIn TaxiOut Cancelled CancellationCode Diverted
-13 -4 HOU TUL 453 3 9 0 0
La partie j
La partie « j » sert à sélectionner des colonnes et à faire des choses avec. Et « choses » peut vraiment vouloir dire n’importe quelle opération. Toutes sortes de fonctions peuvent être utilisées, ce qui fait la force de data.table.
DT[, mean(na.omit(ArrDelay))]
[1] 7.094334
Remarquez que la partie « i » est vide et que la virgule arrive en premier dans les crochets. Cela peut sembler contre‑intuitif au départ. Cela signifie simplement que l’on ne filtre aucune ligne : toutes les lignes sont sélectionnées. Dans la partie « j », on calcule le retard moyen à l’arrivée de tous les vols. Il semble que, dans hflights, l’avion moyen ait plus de 7 minutes de retard. Prévoyez large pour votre prochain vol !
Lorsque vous sélectionnez plusieurs colonnes et effectuez des opérations dans « j », vous devez utiliser la notation « .() ». C’est en fait un alias de « list() ». Elle renvoie une data table, tandis que ne pas utiliser « .() » renvoie seulement un vecteur, comme ci‑dessus.
DT[, .(mean(na.omit(DepDelay)), mean(na.omit(ArrDelay)))]
V1 V2
9.444951 7.094334
Autre fonctionnalité utile nécessitant « .() » : vous pouvez renommer les colonnes directement dans la commande DT[...].
DT[, .(Avg_ArrDelay =
mean(na.omit(ArrDelay)))]
Avg_ArrDelay
7.094334
DT[, .(Avg_DepDelay = mean(na.omit(DepDelay)),
avg_ArrDelay = mean(na.omit(ArrDelay)))]
Avg_DepDelay Avg_ArrDelay
9.444951 7.094334
Bien sûr, renommer n’est pas obligatoire.
En combinant ce qui précède sur « i » et « j », on obtient :
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))]
Avg_DepDelay Avg_ArrDelay V3 V4
6.390144 0.8917558 NULL NULL
Ici, nous avons pris DT, sélectionné les lignes où la compagnie est AA dans « i », calculé le retard moyen au départ et à l’arrivée, puis tracé l’heure de départ en fonction du retard au départ dans « j ».
Pour résumer, la partie « j » sert à effectuer des calculs sur les colonnes mentionnées. Les colonnes d’une data table étant vues comme des variables, et les éléments de « j » étant évalués comme des expressions, vous pouvez pratiquement tout faire dans « j ». Votre temps de développement s’en trouve considérablement réduit.
La partie by
La dernière section de ce tutoriel R sur data.table se concentre sur « by ». Cette partie sert à calculer l’expression « j » en la regroupant par une variable donnée (ou une transformation de celle‑ci). Vous verrez que l’expression « j » est répétée pour chaque groupe « by ». Son utilisation est simple : indiquez simplement la colonne de regroupement dans l’argument « by ».
DT[,mean(na.omit(DepDelay)),by=Origin]
Origin V1
IAH 8.436951
HOU 12.837873
Ici, nous avons calculé le retard moyen au départ, regroupé par aéroport d’origine. Il semble que les vols partant de HOU aient un retard moyen plus élevé que ceux au départ de IAH.
Comme pour « j », vous pouvez faire beaucoup de choses dans « by ». On peut y utiliser des fonctions pour que les résultats des opérations réalisées dans « j » soient regroupés par un élément précisé dans la commande DT[...]. L’usage de fonctions au sein de DT[...] rend cette ligne très puissante. De même, la notation « .() » s’impose lorsque plusieurs colonnes sont utilisées dans « by ».
DT[,.(Avg_DepDelay_byWeekdays = mean(na.omit(DepDelay))), by=.(Origin,Weekdays = DayOfWeek<6)]
Origin Weekdays Avg_DepDelay_byWeekdays
IAH FALSE 8.286543
IAH TRUE 8.492484
HOU FALSE 10.965384
HOU TRUE 13.433994
Ici, le retard moyen au départ (pas de filtrage en « i », donc toutes les lignes sont prises) est d’abord calculé, puis regroupé par aéroport d’origine et par jour de la semaine. Weekdays vaut FALSE le week‑end. Il apparaît que les retards au départ sont plus élevés au départ de HOU que de IAH, et — de façon surprenante — plus faibles le week‑end.
En combinant tout, une commande type DT[i,j,by] donne :
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)]
Origin Weekdays Avg_DepDelay Avg_ArrDelay Compensation
IAH FALSE 8.979730 4.116751 -4.825719
HOU FALSE 7.120000 2.656566 -4.555556
IAH TRUE 9.270948 6.281941 -2.836609
HOU TRUE 11.631387 10.406593 -1.278388
Ici, le sous‑ensemble des vols opérés par Delta Air Lines (sélection en « i ») est regroupé par aéroport d’origine et par Weekdays (dans « by »). Le temps « rattrapé » en vol est également calculé (dans « j »). On observe que, le week‑end, quel que soit l’aéroport (IAH ou HOU), le temps compensé en vol (en volant plus vite) est plus important.
Le package data.table recèle bien d’autres fonctionnalités, mais ce billet a illustré la commande de base DT[i,j,by]. Le cours DataCamp couvre le package dans son ensemble. Vous pouvez faire les exercices à votre rythme dans le navigateur, avec indices et retours, et revoir vidéos et supports à volonté. Cet apprentissage interactif vous apporte une compréhension solide et une véritable expérience pratique des data tables. Essayez‑le gratuitement. Découvrez aussi la cheat sheet du package data.table pour R de DataCamp.
Nous espérons que ce tutoriel R sur data.table vous a permis de comprendre la syntaxe fondamentale de data.table et que vous êtes prêt à expérimenter. Si vous avez des questions sur data.table, jetez un œil ici. Matt et Arun sont très actifs. L’un des prochains billets consacrés à data.table sera plus technique et explorera en profondeur ses vastes possibilités. Restez à l’écoute !

