Pour constituer et interroger des tables de données, SQL a pavé le chemin de langages simples, déclaratifs, agençant des verbes faciles à comprendre : SELECT, ORDER BY, GROUP BY, UPDATE… On retrouve cette simplicité d’écriture dans Python ou R par exemple.
Ce que le fameux Tidyverse est à R, la librairie JavaScript Arquero [1] ambitionne de l’être dans le navigateur : un cadre élégant et puissant pour acquérir des données et les faire parler dans un même open dataflow !
Arquero est capable, avec une étonnante fluidité, de :
- lire un fichier CSV (ou Arrow) pour en faire une table statistique (schéma en colonnes),
- nettoyer cette table : définir les types numériques ou caractères adaptés, remplacer les valeurs manquantes, éliminer les doublons,
- restructurer (en transposant), compléter (par jointure ou concaténation avec d’autres tables),
- filtrer, calculer de nouvelles colonnes, agréger selon un ou plusieurs critères, trier, renommer ou déplacer des colonnes,
- appliquer des traitements statistiques avancés : fenêtrages, rangs, échantillonnages, décalages, discrétisations…
L’intérêt d’une telle librairie en JavaScript est évident, car le web est l’alpha et l’omega de tout processus d’analyse opendata. C’est là qu’on trouve les données-source, et c’est aussi dans ce cadre que l’on souhaite, généralement, communiquer sur les résultats.
Arquero s'inspire de Tidyverse (R)
Si R (ou d’autres puissants outils de data-science) restent indispensables pour des modélisations complexes ou des « pré-nettoyages » poussés, les flux purement web sont gages de productivité, d’interopérabilité et de démocratisation.
C’est dans cet esprit que Jeffrey Heer et ses collègues de l’université de Washington ont conçu Arquero, grammaire de manipulation de données et avant elle Vega(-Lite), grammaire de datavisualisation.
Tidyverse a clairement inspiré Arquero, Jeffrey Heer n’en fait pas mystère en présentant ce travail[2] à l’automne 2020.
Les familiers de R pourront considérer qu’Arquero aborde le champ couvert par dplyr et tidyr, tandis que Vega-Lite fonctionne sur les mêmes principes (grammaire graphique et variables visuelles) que ggplot2.
Il est vraiment facile de passer d’un univers à l’autre, selon ses besoins. Mieux encore, connaître les deux permet de mieux les comprendre chacun, par le jeu des subtiles résonnances et différences qu’ils entretiennent.
Last, but not least, Arquero sait déjà tirer parti d’Apache Arrow, qui s’annonce comme le modèle de « dataframe » du futur, standard commun aux outils phares de la data-science (R, Python/pandas, Julia, Spark…)
Arquero est simple et puissant à utiliser
Voyons au travers de quelques opérations concrètes comment Arquero s’utilise et déploie toute sa puissance de traitement. L’ensemble du code est accessible en fin de ce document.
Disponible au format CSV sur le site de l’Insee, un fichier décrit les naissances domiciliées par commune depuis 10 ans, de 2010 à 2019. En voici un extrait sous forme d’une table Arquero :
Comme on le voit, les colonnes de cette table sont soigneusement typées, les codes commune n’ont pas perdu leur précieux 0 ! Et les naissances sont bien reconnues comme numériques.
Là où JavaScript modélise généralement un « array » de lignes, Arquero considère une table comme, avant tout, une collection de colonnes, de même longueur, chacune de contenu homogène. C’est le même principe qui conduit au concept de dataframe dans R ou Python/Pandas.
Le format des données d’origine n’est pas idéal, avec cette multiplication de colonnes millésimées. Il convient de passer en format « long », par transposition, qui fera apparaitre clairement un axe temporel.
C’est aussi simple avec Arquero que dans R. En lieu et place d’un pivot_longer(), on emploiera un fold() de la façon suivante :
tb.fold( aq.startswith('NAISD'), {as: ['AN', 'NAISD']} )
Elégant, n’est-il pas ? Cette table transposée présente désormais 350 000 lignes, soit 10 fois plus que la précédente, mais avec une structure stabilisée à 3 colonnes logiques.
Comme on peut le voir la colonne que j’ai choisi de dénommer AN mixe encore millésimes et nom de variable.
Je m’emploie donc à dégager un vrai code année, en ajustant le contenu de cette colonne. Par la même occasion, je vais faire apparaître une nouvelle colonne avec un code département nommé DEP.
Pour ce faire, j’utilise le verbe Arquero derive : (équivalent d’un mutate dans R/dplyr). Il me permet de créer de nouvelles colonnes ou de modifier une colonne existante par l’emploi de formules de calcul, opérant sur des nombres, ou sur des chaines de caractère.
Ici la fonction substring() répond simplement à mes 2 besoins.
Je voudrais maintenant regrouper mes données par région, mais je n’ai pas cette information encore. Je vais en passer par une table de correspondance entre départements et régions, disponible au format CSV sur le web.
Ainsi, par appariement avec une table de nomenclature, je peux injecter un code région REG dans ma table des naissances.
J’utilise ici le verbe lookup, équivalent de left_join dans R/dplyr. lookup est un raccourci pour join_left, qui facilite l’ajout d’une seule colonne, ce qui est bien le cas ici. Mission accomplie avec l’apparition de REG !
Je vais enfin agréger cette table par région, tout en conservant le détail annuel.
tb_naiss.groupby('REG','AN') .rollup({NAISD: op.sum('NAISD')})
Arquero se marie fort bien avec Vega-Lite
Il ne me reste plus qu’à injecter le nom des régions et construire ce graphique avec quelques lignes de Vega-Lite. J’ai filtré la table ci-dessus en ne retenant que quelques régions (avec le verbe filter()) :
Pour accéder au détail du code et une présentation pas-à-pas de ces transformations, rendez-vous sur cet open dataflow Observable. Tous les tableaux et le graphique ci-dessus en sont issus, et sont donc produits dynamiquement dans la présente page, avec Arquero et Vega-Lite, de façon transparente !
Qu’est-ce qu’une « grammaire »
de manipulation de données ?
Arquero ressemble, on l’a dit, à Tidyverse (R) ou Pandas (Python), lesquels s’inspirent de SQL, en voulant le simplifier. Une grammaire de manipulation de données agence des verbes, évocateurs (déclaratifs) et atomiques (une seule action à chaque fois).
Là où SQL devient difficile à lire quand les sous-requêtes s’imbriquent en une phrase interminable, les grammaires de données modernes séparent chaque instruction (par un . ou le fameux « pipe » %>% dans R, et un retour à la ligne recommandé).
Parce qu’elles reposent sur des règles cohérentes et peu nombreuses, ces grammaires sont plus faciles à assimiler.
Jeffrey Heer aime visiblement la grammaire, il en a déjà conçu plusieurs, avec ses étudiants, pour les données, les graphiques, les interactions, les animations…
Professeur à l’université de Washington, il a encadré le jeune Mike Bostock (créateur de D3) et cosigné avec lui quelques articles. J’apprécie cette belle rigueur intellectuelle, qui inspire et met en confiance. Les outils brillants que Bostock et Heer mettent à disposition de tous sont aussi pétris des principes de sémiologie posés par Jacques Bertin et prolongés par Leland Wilkinson (The grammar of graphics).
Pour aller plus loin
Voici quelques ressources, la deuxième introduit notamment une série d’excellents documents pédagogiques au format Observable. La dernière enfin présente en vidéo un passionnant exposé sur l’histoire de la datavisualisation.
[2] Introducing Arquero, Jeffrey Heer, 2020
Jeffrey Heer, University of Washington
Open data-flows sur le web : c’est fou ce qu’un navigateur moderne sait faire !