From f3a9368c4af4ce9f040b00e6ea8cbdf78a3b1f07 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Tue, 16 Jun 2026 15:34:40 +0000 Subject: [PATCH 01/14] fix bug rv sync --- rproject.toml | 3 +-- rv.lock | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/rproject.toml b/rproject.toml index 9461a440..25895fc3 100644 --- a/rproject.toml +++ b/rproject.toml @@ -7,8 +7,7 @@ r_version = "4.6" # Example: { alias = "PPM", url = "https://packagemanager.posit.co/cran/latest" }, repositories = [ {alias = "PPM", url = "https://packagemanager.posit.co/cran/latest"}, - { alias = "CRAN", url = "https://cran.r-project.org" }, - { alias = "bioconductor", url = "https://bioconductor.org/packages/3.18/bioc", force_source = true } + { alias = "CRAN", url = "https://cran.r-project.org" } ] # A list of packages to install and any additional configuration diff --git a/rv.lock b/rv.lock index e07c8d0d..a57bc4c0 100644 --- a/rv.lock +++ b/rv.lock @@ -1,7 +1,7 @@ # This file is automatically @generated by rv. # It is not intended for manual editing. version = 2 -r_version = "4.5" +r_version = "4.6" [[packages]] name = "DBI" @@ -34,7 +34,7 @@ dependencies = [] [[packages]] name = "FactoMineR" -version = "2.14" +version = "2.15" source = { repository = "https://packagemanager.posit.co/cran/latest" } force_source = false dependencies = [ @@ -51,6 +51,7 @@ dependencies = [ "scatterplot3d", "ggplot2", "ggrepel", + "irlba", ] [[packages]] @@ -76,7 +77,7 @@ dependencies = [] [[packages]] name = "Matrix" -version = "1.7-4" +version = "1.7-5" source = { builtin = true } force_source = false dependencies = [ @@ -940,6 +941,15 @@ dependencies = [ { name = "cpp11", requirement = "(>= 0.5.0)" }, ] +[[packages]] +name = "irlba" +version = "2.3.7" +source = { repository = "https://packagemanager.posit.co/cran/latest" } +force_source = false +dependencies = [ + "Matrix", +] + [[packages]] name = "isoband" version = "0.3.0" @@ -1197,7 +1207,7 @@ dependencies = [] [[packages]] name = "nlme" -version = "3.1-168" +version = "3.1-169" source = { builtin = true } force_source = false dependencies = [ @@ -1541,7 +1551,7 @@ dependencies = [ [[packages]] name = "rstudioapi" -version = "0.18.0" +version = "0.19.0" source = { repository = "https://packagemanager.posit.co/cran/latest" } force_source = false dependencies = [] @@ -1595,7 +1605,7 @@ dependencies = [] [[packages]] name = "secretbase" -version = "1.2.2" +version = "1.3.0" source = { repository = "https://packagemanager.posit.co/cran/latest" } force_source = false dependencies = [] From f9edcf0af8c1fa7dea0907b9cd0a792a34b5066c Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Tue, 16 Jun 2026 15:35:01 +0000 Subject: [PATCH 02/14] fix path install --- init_utilitr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init_utilitr.sh b/init_utilitr.sh index 9f27562b..f1ac9369 100644 --- a/init_utilitr.sh +++ b/init_utilitr.sh @@ -3,8 +3,8 @@ curl -sSL https://raw.githubusercontent.com/A2-ai/rv/refs/heads/main/scripts/ins export PATH="~/.local/bin:$PATH" source ~/.bashrc -if [ -d "/home/onyxia/work/utilitr" ]; then - cd /home/onyxia/work/utilitr +if [ -d "/home/onyxia/work/utilitR" ]; then + cd /home/onyxia/work/utilitR rv sync else git clone https://github.com/inseefrlab/utilitr From 6eea7b21413b3bd2556ce95a97b97d5c33b62f13 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Tue, 16 Jun 2026 15:36:17 +0000 Subject: [PATCH 03/14] Relecture fiche duckdb --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 218 +++++++++++++------------ 1 file changed, 111 insertions(+), 107 deletions(-) diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index 895cb3ac..74df140b 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -1,34 +1,57 @@ # Manipuler des données avec `duckdb` {#duckdb} -## Tâches concernées et recommandations - L'utilisateur souhaite manipuler des données structurées sous forme de `data.frame` par le biais de l'écosystème `duckdb` (sélectionner des variables, sélectionner des observations, créer des variables, joindre des tables). -::: {.callout-important} -Tâches concernées et recommandations - -- Pour des tables de données de taille petite et moyenne (inférieure à 1 Go ou moins d'un million d'observations), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui sont présentés dans la fiche [Manipuler des données avec le `tidyverse`](#tidyverse); - -- Pour des tables de données de grande taille (plus de 1 Go en CSV, plus de 200 Mo en Parquet, ou plus d'un million d'observations), il est recommandé d'utiliser soit les *packages* `arrow` (voir la fiche [Manipuler des données avec `arrow`](#arrow)) et `duckdb` qui fait l'objet de la présente fiche, soit le *package* `data.table` qui fait l'objet de la fiche [Manipuler des données avec `data.table`](#datatable). +## Pourquoi travailler avec le *package* `duckdb` pour un statisticien utilisant `R`? -- Il est essentiel de travailler avec la dernière version d'`arrow`, de `duckdb` et de `R` car les *packages* `arrow` et `duckdb` sont en cours de développement. Par ailleurs, les recommandations d'`utilitR` peuvent évoluer en fonction du développement de ces _packages_. +Le *package* `duckdb` permet de faire trois choses: -- Si les données sont très volumineuses (plus de 5 Go en CSV, plus de 1 Go en Parquet ou plus de 5 millions d'observations), il est recommandé de manipuler les données avec `duckdb` (et avec `arrow`) plutôt qu'avec le `tidyverse`. Il peut arriver que le volume de données soit tellement important qu'il ne soit pas possible de les traiter avec `duckdb` et `arrow`; il faut s'orienter vers des infrastructures *big data* permettant le calcul distribué et utiliser des logiciels adaptés (`Spark` par exemple). -::: +- Lire des sources de données dans une multitude de formats (csv, parquet, json, geojson, shape, postgresql...), y compris directement en ligne, y compris plusieurs fichiers d'un seul coup (en local comme avec S3, GCS ou HuggingFace); +- Manipuler des données avec la syntaxe `dplyr`, ou avec le langage SQL; +- Écrire des données dans une multitude de formats (csv, parquet, json, formats SIG...) +## Débuter avec `duckdb` -::: {.callout-note} Apprendre à utiliser `duckdb` n'est pas difficile, car la syntaxe utilisée est quasiment identique à celle du `tidyverse`. Toutefois, une bonne compréhension du fonctionnement de `R` et de `duckdb` est nécessaire pour bien utiliser `duckdb` sur des données volumineuses. Voici quelques conseils pour bien démarrer: - Il est indispensable de lire la fiche [Manipuler des données avec le `tidyverse`](#tidyverse) avant de lire la présente fiche. -- Il est recommandé de lire les fiches [Se connecter à une base de données](#bdd) et [Manipuler des données avec `arrow`](#arrow) avant de lire la présente fiche. -- Il est complètement normal de rencontrer des erreurs difficiles à comprendre lorsqu'on commence à utiliser `duckdb`, il ne faut donc pas se décourager. +- Il est recommandé de lire la fiche [Se connecter à une base de données](#bdd) avant de lire la présente fiche. - Il ne faut pas hésiter à demander de l'aide à des collègues, ou à poser des questions sur les salons Tchap adaptés (le salon Langage `R` par exemple). + +::: {.callout-important collapse="true"} +## Pourquoi utiliser `duckdb` plûtot que `arrow` ? + +Bien que les *packages* `duckdb` et `arrow` aient des cas d'usage très similaires (voir la fiche [Manipuler des données avec `arrow`](#arrow)), l'utilisation de `duckdb` **est à privilégier** . On peut également les utiliser ensemble pour profiter de chacun de leurs avantages. Le tableau ci-dessous compare quelques cas d'usage de ces deux *packages* : + +| Je souhaite... | arrow | duckdb | +| ------------------------------------------------------------------------- | ----- | ------ | +| Optimiser mes traitements pour des données volumineuses | ✔️ | ✔️ | +| Travailler sur un fichier .parquet ou .csv sans le charger entièrement en mémoire | ✔️ | ✔️ | +| Utiliser la syntaxe `dplyr` pour traiter mes données | ✔️ | ✔️ | +| Utiliser du langage SQL pour traiter mes données | ❌ | ✔️ | +| Joindre des tables très volumineuses (plus de 4 Go) | ❌ | ✔️ | +| Utiliser des fonctions fenêtres (voir @sec-arrow) | ❌ | ✔️ | +| Utiliser des fonctions statistiques qui n'existent pas dans arrow (voir @sec-arrow) | ❌ | ✔️ | +| Écrire un fichier .parquet | ✔️ | ✔️ * | + +\* pour écrire un fichier .parquet avec le package `duckdb`, il faut utiliser une instruction SQL (voir @sec-ecrire-parquet) ::: +::: {.callout-important collapse="true"} +## Tâches concernées et recommandations + +- Pour des tables de données de taille petite et moyenne (inférieure à 1 Go ou moins d'un million d'observations), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui sont présentés dans la fiche [Manipuler des données avec le `tidyverse`](#tidyverse); + +- Pour des tables de données de grande taille (plus de 1 Go en CSV, plus de 200 Mo en Parquet, ou plus d'un million d'observations), il est recommandé d'utiliser le *package* `duckdb` qui fait l'objet de la présente fiche. + +- Il est essentiel de travailler avec la dernière version de `duckdb` et de `R` car le *package* `duckdb` est en cours de développement. Par ailleurs, les recommandations d'`utilitR` peuvent évoluer en fonction du développement du _package_. + +- Si les données sont très volumineuses (plus de 5 Go en CSV, plus de 1 Go en Parquet ou plus de 5 millions d'observations), il est recommandé de manipuler les données avec `duckdb` plutôt qu'avec le `tidyverse`. Il peut arriver que le volume de données soit tellement important qu'il ne soit pas possible de les traiter avec `duckdb`; il faut s'orienter vers des infrastructures *big data* permettant le calcul distribué et utiliser des logiciels adaptés (`Spark` par exemple). +::: -## Présentation du _package_ `duckdb` et du projet associé +## Présentation du projet `DuckDB` et du _package_ `R` associé +::: {.callout-note collapse="true"} ### Qu'est-ce que `duckdb`? {#sec-presentation} [`DuckDB`](https://duckdb.org/) est un projet *open-source* (license MIT) qui propose un moteur SQL optimisé pour réaliser des travaux d'analyse statistique sur des bases de données : @@ -45,49 +68,29 @@ Un point important à comprendre est que **`DuckDB` n'est pas un outil spécifiq Toutefois, `DuckDB` est très facile à utiliser avec `R`, ce qui permet de bénéficier des optimisations inhérentes au langage SQL, à la fois en terme d'utilisation de la mémoire et de rapidité de calcul. C'est de plus un bon intermédiaire avant de passer à des infrastructures avancées telles que spark ou oracle. +::: -### À quoi sert le *package* `duckdb`? - -Du point de vue d'un statisticien utilisant `R`, le *package* `duckdb` permet de faire trois choses: - -- Lire des données dans une multitude de formats (fichiers CSV, fichiers Parquet, geoparquet, json, geojson, shape...); -- Manipuler des données avec la syntaxe `dplyr`, ou avec le langage SQL; -- Écrire des données dans une multitude de formats (parquet, csv, json, geojson, geoparquet...) - - -### Quels sont les avantages de `duckdb`? +::: {.callout-tip collapse="true"} +## Quels sont les avantages de `duckdb`? -- **Disponibilité immédiate** dans les cas "simples": on peut pré-visualiser les données ou le résultat d'un calcul sans l'exécuter totalement, sans attendre le chargement des données (cela n'est pas vrai dans tous les cas comme par exemple sur des agrégations ou des tris) +- **Disponibilité immédiate** dans les cas "simples": DuckDB ne lit que les données strictement nécessaires à la requête (lazy scanning) et peut retourner les premières lignes d'un filtre ou d'une projection sans charger l'intégralité du fichier. Cette propriété ne s'applique pas aux opérations nécessitant de parcourir toutes les données : agrégations, tris, jointures; - **Performances élevées**: `duckdb` est très rapide pour la manipulation de données tabulaires (nettement plus performant que `dplyr` par exemple); - **Ne pas nécessairement charger les données en mémoire**: `duckdb` permet également de requêter directement sur des fichiers du disque dur (ou en ligne) sans avoir à charger tout le fichier en mémoire ; -- **Optimisations automatiques**: par exemple dans le cas de fichiers parquet ou d'utilisation du format `duckdb` natif, `duckdb` sélectionne automatiquement les colonnes nécessaires, et ne lit que les lignes (ou plus exactement groupes de lignes) nécessaires. Cela permet d'accélérer les calculs et de réduire considérablement les besoins en mémoire, même lorsque les données sont volumineuses. Ces optimisations ne fonctionnent pas pour tous les formats (par exemple CSV, json...); +- **Optimisations automatiques**: avec des fichiers Parquet ou le format natif DuckDB, deux optimisations s'appliquent automatiquement : d'une part, seules les colonnes utiles à la requête sont lues et d'autre part, DuckDB exploite les statistiques stockées dans le fichier pour ignorer les blocs de lignes qui ne peuvent pas contenir les résultats recherchés, réduisant ainsi la quantité de données lues. Ces optimisations ne s'appliquent pas aux formats CSV ou JSON, pour lesquels DuckDB doit lire l'intégralité du fichier; - **Facilité d'apprentissage** grâce aux approches `dplyr` et SQL: `duckdb` peut être utilisé avec les verbes de `dplyr` (`select`, `mutate`, etc.) et/ou avec le langage SQL. Par conséquent, il n'est pas nécessaire d'apprendre une nouvelle syntaxe pour utiliser `duckdb`, on peut s'appuyer sur la ou les approches que l'on maîtrise déjà. +::: -### Quels sont les points d'attention à l'usage ? +::: {.callout-warning collapse="true"} +## Quels sont les points d'attention à l'usage ? - __Préservation de l'ordre des lignes__ : contrairement à un moteur SQL classique, `duckdb` [préserve l'ordre des lignes pour certaines clauses](https://duckdb.org/docs/sql/dialect/order_preservation.html) mais le comportement diffère du {tidyverse} (par exemple`dplyr::*_join` conserve l'ordre mais pas l'ordre `JOIN` de `duckdb`) -- __Traitement de données volumineuses__: `duckdb` peut traiter de gros volumes de données, qu'elles soient en mémoire vive ou sur le disque dur. Lorsque les données sont en mémoire vive, les _packages_ `duckdb` et `arrow` peuvent être utilisés conjointement de façon très efficace: cela veut dire concrètement que `duckdb` peut manipuler directement des données stockées dans un objet `Arrow Table`, sans avoir à convertir les données dans un autre format. Avec des données stockées sur le disque dur, `duckdb` est capable de faire les traitements sur des données plus volumineuses que la mémoire vive (RAM). C'est un avantage majeur en comparaison aux autres approches possibles en `R` (`data.table` et `dplyr` par exemple). Toutefois, il faut dans ce cas ajouter le temps de lecture des données au temps nécessaire pour le calcul. +- __Traitement de données volumineuses__: `duckdb` peut traiter de gros volumes de données, qu'elles soient en mémoire vive ou sur le disque dur. Avec des données stockées sur le disque dur, `duckdb` est capable de faire les traitements sur des données plus volumineuses que la mémoire vive (RAM). C'est un avantage majeur en comparaison aux autres approches possibles en `R` (`data.table` et `dplyr` par exemple). Toutefois, il faut dans ce cas ajouter le temps de lecture des données au temps nécessaire pour le calcul. - __*Évaluation différée*__: `duckdb` construit des requêtes SQL, qui sont exécutées uniquement lorsque le résultat est explicitement demandée, après optimisation des étapes intermédiaires, et peuvent être exécutées partiellement. La @sec-lazy présente en détail cette notion. -- __*Traduction en SQL*__: `duckdb` traduit automatiquement les instructions `dplyr` en requêtes SQL (de la même façon qu'`arrow` traduit ces instructions en code C++). Il arrive toutefois que certaines fonctions de `dplyr` n'aient pas d'équivalent direct en `duckdb` et ne puissent être traduites automatiquement. Dans ce cas (qui est heureusement moins fréquent qu'avec `arrow`), il faut parfois utiliser une fonction SQL directement ou trouver une solution pour contourner le problème. La @sec-sql donne quelques trucs et astuces dans ce cas. +- __*Traduction en SQL*__: le package `dbplyr` traduit automatiquement les instructions `dplyr` en requêtes SQL compatibles avec `duckdb`, qui se charge ensuite de les exécuter. Il arrive toutefois que certaines fonctions `dplyr` n'aient pas d'équivalent direct dans le dialecte SQL de `duckdb` et ne puissent être traduites automatiquement par `dbplyr`. Dans ce cas, il faut parfois recourir directement à une expression SQL ou trouver une solution de contournement.. La @sec-sql donne quelques trucs et astuces dans ce cas. - __Interopérabilité__: `duckdb` est conçu pour être interopérable entre plusieurs langages de programmation tels que `R`, Python, Java, C++, etc. Cela signifie que les données peuvent être échangées entre ces langages sans avoir besoin de convertir les données, d'où des gains importants de temps et de performance. -### Quand utiliser `duckdb` plutôt que `arrow` ? - -Les *packages* `duckdb` et `arrow` ont des cas d'usage très similaires (voir la fiche [Manipuler des données avec `arrow`](#arrow)), mais on peut préférer l'un à l'autre selon les cas. On peut également les utiliser ensemble pour profiter de chacun de leurs avantages. Le tableau ci-dessous compare quelques cas d'usage de ces deux *packages* : - -| Je souhaite... | arrow | duckdb | -| ------------------------------------------------------------------------- | ----- | ------ | -| Optimiser mes traitements pour des données volumineuses | ✔️ | ✔️ | -| Travailler sur un fichier .parquet ou .csv sans le charger entièrement en mémoire | ✔️ | ✔️ | -| Utiliser la syntaxe `dplyr` pour traiter mes données | ✔️ | ✔️ | -| Utiliser du langage SQL pour traiter mes données | ❌ | ✔️ | -| Joindre des tables très volumineuses (plus de 4 Go) | ❌ | ✔️ | -| Utiliser des fonctions fenêtres (voir @sec-arrow) | ❌ | ✔️ | -| Utiliser des fonctions statistiques qui n'existent pas dans arrow (voir @sec-arrow) | ❌ | ✔️ | -| Écrire un fichier .parquet | ✔️ | ✔️ * | - -\* pour écrire un fichier .parquet avec le package `duckdb`, il faut utiliser une instruction SQL (voir @sec-ecrire-parquet) +::: ## Installation de `duckdb` @@ -113,12 +116,13 @@ library(dplyr) Le moteur `duckdb` fonctionnant "en dehors" de `R`, il détecte le nombre de processeurs et effectue les opérations en parallèle si possible. - ### Connexion à une base de données -**`duckdb` est une base de données distante et s'utilise comme telle: il faut ouvrir une connexion, puis "charger" les données dans la base de données pour les manipuler.** +**Principe : `duckdb` est une base de données distante: il faut ouvrir une connexion, puis "charger" les données dans la base de données pour les manipuler. A la fin du traitement, il faut fermer la connexion.** + +#### Ouvrir une connexion -Comme beaucoup d'autres bases de données (distantes ou locales), on ouvre une connexion au moteur `duckdb` avec une base de données en mémoire vive de la façon suivante : +Pour commencer, on ouvre une connexion au moteur `duckdb` avec une base de données en mémoire vive de la façon suivante : ```{r} conn_ddb <- DBI::dbConnect(drv = duckdb::duckdb()) @@ -126,12 +130,20 @@ conn_ddb <- DBI::dbConnect(drv = duckdb::duckdb()) Concrètement, cette commande crée une nouvelle base de données `duckdb` dans la mémoire vive. Cette base de données ne contient aucune donnée lorsqu'elle est créée. L'objet `conn_ddb` apparaît dans l'onglet `Data` de l'environnement `RStudio`, mais la liste des tables n'y est pas directement accessible. Pour plus d'informations, se reporter à la documentation du _package_ `DBI`. -À la fin du traitement ou du programme, on ferme la connexion avec le code ci-dessous. L'option `shutdown` est importante : elle permet de fermer complètement la session `duckdb` et de libérer la mémoire utilisée. Si on n'utilise pas cette option, il arrive souvent que des connexions à moitié ouvertes continuent à consommer des ressources, et il faut alors relancer la session `R`. +#### Fermer une connexion +Lors de la fin du traitement (ou programme), on ferme la connexion avec le code ci-dessous : ```{r} DBI::dbDisconnect(conn_ddb, shutdown = TRUE) ``` +::: {.callout-important collapse="true"} +## Vérifier que la mémoire utilisée dans la session `duckdb` est bien libérée +L'option `shutdown` est importante : elle permet de fermer complètement la session `duckdb` et de libérer la mémoire utilisée. Si on n'utilise pas cette option, il arrive souvent que des connexions à moitié ouvertes continuent à consommer des ressources, et il faut alors relancer la session `R`. +::: + +#### Paramétrer le nombre de cœurs utilisés dans une connexion + Par défaut, `duckdb` utilisera tous les cœurs disponibles. Si vous travaillez sur un serveur mutualisé, il est conseillé de limiter le nombre de cœurs utilisés par `duckdb` afin de ne pas consommer toutes les ressources. Vous pouvez trouver plus d'information dans la section [Configurer `duckdb`](#sec-configuration). ```{r} @@ -145,14 +157,16 @@ Pour la suite, on supposera que la connexion à une base de données duckdb est ### Chargement des données -Une fois qu'on s'est connecté à une base de données duckDB, il faut charger des données dans cette base de données. Il y a deux façons de le faire: +Maintenant que la connexion à une base de données duckDB est créée, chargeons des données dans cette base de données. Pour cela, deux méthods existent : - En établissant un lien entre la base de données duckDB et les objets de la session `R`; - En indiquant à `duckdb` l'emplacement des données sur le disque dur. #### Chargement de données provenant de la session `R` -__La fonction `duckdb_register()` permet de charger dans `duckdb` des données présentes dans la session `R`.__ Cette méthode a l'avantage de ne pas _recopier_ les données: elle se contente d'établir un lien logique entre la base de données `duckdb` et un objet de la session `R`. Voici un exemple avec la Base permanente des équipements: grâce à la fonction `duckdb::duckdb_register()`, l'objet `bpe_ens_2018` est référencé dans la base de données `duckdb` sous le nom `bpe_ens_2018_duckdb`. +__La fonction `duckdb_register()` permet de charger dans `duckdb` des données présentes dans la session `R`.__ Cette méthode a l'avantage de ne pas _recopier_ les données: elle se contente d'établir un lien logique entre la base de données `duckdb` et un objet de la session `R`. + +Voici un exemple avec la Base permanente des équipements: grâce à la fonction `duckdb::duckdb_register()`, l'objet `bpe_ens_2018` est référencé dans la base de données `duckdb` sous le nom `bpe_ens_2018_duckdb`. ```{r} # Charger la Base permanente des équipements 2018 dans la session R @@ -164,62 +178,58 @@ conn_ddb %>% duckdb::duckdb_register( df = bpe_ens_2018) ``` +::: {.callout-tip collapse="true"} +## Vérifier que le chargement des données a bien fonctionné Le code ci-dessous permet de vérifier que le chargement des données a bien fonctionné. La fonction `tbl` permet d'accéder à un objet de la base de données par le nom (de la table), ou par du code SQL (utilisation un peu plus avancée). Par défaut, `duckdb` affiche les 10 premières lignes du résultat, sans effectuer tout le calcul. C'est très pratique et très rapide ! ```{r} conn_ddb %>% tbl("bpe_ens_2018_duckdb") ``` +::: #### Chargement de données stockées sur le disque dur +::: {.callout-note colapse="true"} +## Préambule : sauvegarder la table de travail sur le disque dur Pour l'exemple suivant, on sauvegarde les données `bpe_ens_2018` au format Parquet. ```{r} -bpe_ens_2018 |> arrow::write_dataset("bpe_ens_2018_dataset") +dir.create("bpe_ens_2018_dataset", showWarnings = FALSE) +duckdb::duckdb_register(conn_ddb, "bpe_ens_2018", bpe_ens_2018) +DBI::dbExecute(conn_ddb, "COPY bpe_ens_2018 TO 'bpe_ens_2018_dataset/bpe_ens_2018.parquet' (FORMAT PARQUET)") ``` +::: -**Il existe deux méthodes pour manipuler des données stockées en Parquet avec `duckdb` sans avoir à les charger en mémoire**: soit utiliser la fonction `dplyr::tbl()` qui lit directement les fichiers Parquet avec `duckdb`, soit utiliser la fonction `arrow::open_dataset()` et créer un lien logique avec la fonction `arrow::to_duckdb()`. Si la deuxième méthode est plus simple, surtout quand vous connaissez déjà `arrow`, la première est systématiquement plus efficace et peut générer des gains de consommation mémoire et de temps de traitement conséquents. Il est donc conseillé de ne pas lire vos fichiers avec `arrow::open_dataset` si vos traitements sont lourds (il ne faut pas hésiter à faire des tests). - -**La première approche repose uniquement sur `duckdb`.** Vous devez utilisez la fonction `dplyr::tbl`: +**Pour manipuler des données stockées en Parquet avec `duckdb` sans avoir à les charger en mémoire, il faut utiliser la fonction `dplyr::tbl()` qui lit directement les fichiers Parquet avec `duckdb`:** ```{r messages=FALSE} -conn_ddb %>% tbl("read_parquet('bpe_ens_2018_dataset/**/*.parquet')") +bpe_ens_2018_dataset <- conn_ddb %>% tbl("read_parquet('bpe_ens_2018_dataset/**/*.parquet')") ``` Quelques explications de cette commande: -* La fonction [`read_parquet`](https://duckdb.org/docs/data/parquet/overview.html#read_parquet-function) est une fonction interne à `duckdb`, elle ne doit surtout pas être confondue avec la fonction `read_parquet()` du _package_ `arrow`. Remarque: `duckdb` propose aussi [des fonctions pour lire d'autres formats](https://duckdb.org/docs/data/csv/overview.html) comme csv, json... -* `**/*.parquet` est un motif qui indique que vous souhaitez lire, dans tous les sous-dossiers quelque soit le niveau (`**`), l'ensemble des fichiers parquets (`*.parquet`) qui s'y trouvent. C'est notamment utile pour lire des fichiers Parquet partitionnés. Quand vous n'avez pas besoin de passer d'arguments à `read_parquet`, vous pouvez l'omettre : +* La fonction [`read_parquet`](https://duckdb.org/docs/data/parquet/overview.html#read_parquet-function) est une fonction interne à `duckdb`. `duckdb` propose aussi [des fonctions pour lire d'autres formats](https://duckdb.org/docs/data/csv/overview.html) comme csv, json... +* `**/*.parquet` est un motif qui indique que vous souhaitez lire, dans tous les sous-dossiers quelque soit le niveau (`**`), l'ensemble des fichiers parquets (`*.parquet`) qui s'y trouvent. C'est notamment utile pour lire des fichiers Parquet partitionnés. + +::: {.callout-tip collapse="true"} +## Astuce : import de fichiers parquet +Quand vous n'avez pas besoin de passer d'arguments à `read_parquet`, vous pouvez l'omettre : ```{r messages=FALSE} conn_ddb %>% tbl('bpe_ens_2018_dataset/**/*.parquet') ``` +::: + __Cette approche établit une connexion aux données contenues dans le dataset Parquet, mais elle ne charge pas les données en mémoire__ (ni dans la mémoire de `R`, ni dans celle de `DuckDB`). -**La seconde approche consiste à passer par `arrow`, puis à transmettre les données à `duckdb`.** Cette méthode utilise un objet intermédiaire de type Arrow Dataset (voir la fiche [Manipuler des données avec `arrow`](#arrow)): -```{r} -# Créer une connexion au dataset Parquet -bpe_ens_2018_dataset <- arrow::open_dataset("bpe_ens_2018_dataset") - -# Etablir le lien entre la base de données duckdb et le dataset Parquet -bpe_ens_2018_dataset %>% arrow::to_duckdb(conn_ddb) -``` - -Ces deux approches ont un point commun important: __elles établissent une connexion aux données contenues dans le dataset Parquet, mais elles ne chargent pas les données en mémoire__ (ni dans la mémoire de `R`, ni dans celle de `DuckDB`). - -Pour plus de commodité, on sauvegarde l'instruction précédente dans la variable `bpe_ens_2018_dataset`. -```{r} -bpe_ens_2018_dataset <- conn_ddb %>% - tbl('bpe_ens_2018_dataset/*.parquet') -``` ### Manipulation des données avec la syntaxe `dplyr` Le _package_ `R` `duckdb` a été écrit de façon à pouvoir manipuler les données avec la syntaxe de `dplyr` (`select`, `filter`, `mutate`, `left_join`, etc.). `duckdb` traduit le code `R`, y compris certaines fonctions de `stringr` et `lubridate` en requête SQL. Cela s'avère très commode en pratique, car lorsqu'on sait utiliser `dplyr` et le `tidyverse`, on peut commencer à utiliser `duckdb` sans avoir à apprendre une nouvelle syntaxe de manipulation de données. -Dans l'exemple suivant, on calcule le nombre d'équipements par région, à partir d'un `tibble` et à partir d'une table `duckdb`. La seule différence apparente entre les deux traitement est la présence de la fonction `collect()` à la fin des instructions; cette fonction indique que l'on souhaite obtenir le résultat du traitement sous la forme d'un `tibble`. La raison d'être de ce `collect()` est expliquée plus loin, dans le paragraphe sur l'évaluation différée. Les résultats sont identiques, à l'exception de l'ordre des lignes. En effet, un moteur SQL ne respecte pas l'ordre par défaut, il faut le demander explicitement avec `arrange`. +Dans l'exemple suivant, on calcule le nombre d'équipements par région, à partir d'un `tibble` et à partir d'une table `duckdb`: :::: {.columns} @@ -258,6 +268,13 @@ bpe_ens_2018_dataset |> :::: +La seule différence apparente entre les deux traitement est la présence de la fonction `collect()` à la fin des instructions. + +:::{.callout-note collaspe="true"} +## La fonction `collect()` +Cette fonction indique que l'on souhaite obtenir le résultat du traitement sous la forme d'un `tibble`. Les résultats sont identiques, à l'exception de l'ordre des lignes. En effet, un moteur SQL ne respecte pas l'ordre par défaut, il faut le demander explicitement avec `arrange`. + +::: On peut examiner la requête SQL construite par `duckdb` avec la fonction `show_query()`. @@ -273,7 +290,7 @@ bpe_ens_2018_dataset |> Cette requête est envoyée au serveur SQL et exécutée de façon différente en fonction de la dernière instruction du traitement: - si le traitement se termine par `collect()`: le calcul est exécuté en entier et le résultat est retourné sous la forme d'un `tibble`, -- si le traitement se termine par `print(n=nb_lignes)`: seules les `nb_lignes` demandées sont affichées. Dans le cas où vous n'avez pas d'opérations bloquantes (agrégations, tris...), cela permet de minimiser les ressources et la mémoire utilisées. +- si le traitement se termine par print(n=nb_lignes) : dbplyr ajoute automatiquement un LIMIT à la requête SQL. Dans le cas où il n'y a pas d'opérations bloquantes (agrégations, tris...), DuckDB peut exploiter ce LIMIT pour ne lire qu'une partie des données et retourner rapidement les premières lignes. En présence d'opérations bloquantes, toutes les données sont néanmoins traitées. __Ce point est important: en utilisant `print()` en l'abscence d'opérations bloquantes on peut prévisualiser le résultat d'une requête `duckdb` de façon très rapide, sans exécuter tout le traitement.__ Il ne faut pas hésiter à s'en servir pour explorer les données et pour construire le traitement étape par étape, en ajustant en fonction des résultats. @@ -282,43 +299,26 @@ __Ce point est important: en utilisant `print()` en l'abscence d'opérations blo ### Écriture au format Parquet -**Pour écrire une table (ou le résultat de n'importe quelle requête) sur le disque au format Parquet, il est recommandé d'utiliser la librairie `arrow`.** +Pour écrire une table (ou le résultat de n'importe quelle requête) sur le disque au format Parquet, il faut utiliser l'instruction suivante (ici, nous exportons un data.frame présent dans l'environnement R dans un fichier parquet): ```{r} -bpe_ens_2018_dataset %>% - arrow::to_arrow() %>% arrow::write_dataset("temp_dataset") -list.files("temp_dataset") # liste des fichiers du répertoire temp_dataset/ +dir.create("temp_dataset", showWarnings = FALSE) +duckdb::duckdb_register(conn_ddb, "bpe_ens_2018_temp", bpe_ens_2018) # ajouter l'objet R dans la base duckDB +DBI::dbExecute(conn_ddb, "COPY bpe_ens_2018_temp TO 'temp_dataset/bpe_ens_2018.parquet' (FORMAT PARQUET)") +list.files("temp_dataset") ``` -Pour un usage basique en syntaxe `dplyr`, passer par `arrow` (au lieu de SQL) est plus facile à manipuler, notamment quand on souhaite ajouter des options telle que le partitionnement. - +::: {.callout-warning collapse="true"} +## Utilisation du package `arrow` pour l'export de fichier parquet +Même si le package `arrow` peut sembler plus simple à utiliser que SQL pour certaines manipulations `dplyr`, il est préférable de rester avec `duckdb` pour limiter les dépendances et garder une approche cohérente. +::: ### Erreurs courantes -Cette section présente quelques erreurs classiques. - -#### On a éliminé des colonnes nécessaires - -```{r error=TRUE} -bpe_ens_2018_dataset |> select(DEP) |> - mutate(NB_EQUIP_TOTAL_DEP = sum(NB_EQUIP)) -``` - -#### Convertir les types - -Dans cet exemple, on veut multiplier un nombre par une indicatrice. -```{r error=TRUE} -bpe_ens_2018_dataset %>% - summarise(nb_boulangeries = sum(NB_EQUIP * (TYPEQU == "B203")), .by = DEP) -``` - -Avec `duckdb`, il faut transformer explicitement un booléen en nombre (entier ou flottant). - -```{r} -bpe_ens_2018_dataset %>% - summarise(nb_boulangeries = sum(NB_EQUIP * as.integer(TYPEQU == "B203")), .by = DEP) -``` - +| Erreur | Description | Solution | +|--------|-------------|----------| +| Colonne absente | Une colonne utilisée dans un calcul a été supprimée en amont par `select()` | Conserver toutes les colonnes nécessaires aux étapes suivantes dans le `select()` | +| Type booléen non converti | Multiplication d'un booléen (ex. `TYPEQU == "B203"`) par un nombre : DuckDB n'effectue pas cette conversion implicitement | Convertir explicitement en entier : `as.integer(TYPEQU == "B203")` | ## Notions avancées / bien utiliser `duckdb` @@ -327,6 +327,7 @@ bpe_ens_2018_dataset %>% `duckdb` propose de nombreux paramètres mais nous n'allons voir que les principaux. Vous pouvez vous reporter à la [documentation officielle](https://duckdb.org/docs/configuration/overview) pour en apprendre davantage sur la configuration de `duckdb`. +::: {.callout-note collapse="true"} #### Configuration lors de l'initialisation Pour configurer `duckdb` lors de l'initialisation de la base de données (c'est-à-dire au moment où on utilise `DBI::dbConnect(drv = duckdb::duckdb())`), on utilise les arguments du _driver_ `duckdb`. @@ -367,7 +368,9 @@ Il n'existe pas de règle générale pour définir le nombre de _threads_, mais - **`temp_directory` : définir le dossier sur disque dans lequel `duckdb` peut écrire des fichiers temporaires**. Un avantage de `duckdb` est qu'il sait ["déborder" sur disque](https://duckdb.org/docs/guides/performance/how_to_tune_workloads.html#larger-than-memory-workloads-out-of-core-processing) pour une grande partie de ces opérations. Cela signifie que `duckdb` va écrire dans des fichiers temporaires sur le disque les données qu'il ne peut conserver en mémoire car il a atteint la limite de mémoire fixée. Le paramètre `temp_directory` permet de choisir dans quel dossier ces fichiers temporaires seront écrits. Toutefois, il est généralement beaucoup plus efficace de diminuer le nombre de _threads_ que de déborder sur disque mais dans le cas où vous avez besoin de "juste un peu plus" de mémoire cela peut se révéler utile. A noter que ce paramètre est automatiquement fixé si vous avez décidé d'utiliser une base persistante. - **`preserve_insertion_order` : préserver l'ordre de lecture/écriture ou non**. `duckdb` peut consommer beaucoup de mémoire pour conserver l'ordre de lecture et d'écriture. Ce dernier paramètre permet d'autoriser `duckdb` à ne pas préserver l'ordre des données à la lecture et à l'écriture des fichiers dans le cas où il n'y a pas de clause `ORDER BY` / `arrange`. +::: +::: {.callout-note collapse="true"} #### Fixer les paramètres après l'initialisation Vous pouvez également changer les paramètres d'une base après son initialisation en utilisant la commande `dbExecute`. Par exemple, pour fixer le nombre de _threads_ à 4 : @@ -376,6 +379,7 @@ Vous pouvez également changer les paramètres d'une base après son initialisat #| eval: false dbExecute(conn_ddb, "SET threads = '4';") ``` +::: ### L'évaluation différée avec `duckdb` (_lazy evaluation_) {#sec-lazy} From 3ba746d964dec35fac2d381d38e93cc9691b14b9 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Wed, 17 Jun 2026 12:48:39 +0000 Subject: [PATCH 04/14] Refactor + prise en compte #531 sur la fiche duckdb --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 635 ++++++++++++------------- 1 file changed, 313 insertions(+), 322 deletions(-) diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index 74df140b..f3a0abd8 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -16,12 +16,14 @@ Apprendre à utiliser `duckdb` n'est pas difficile, car la syntaxe utilisée est - Il est indispensable de lire la fiche [Manipuler des données avec le `tidyverse`](#tidyverse) avant de lire la présente fiche. - Il est recommandé de lire la fiche [Se connecter à une base de données](#bdd) avant de lire la présente fiche. +- Il est essentiel de travailler avec la dernière version de `duckdb` et de `R` car le *package* `duckdb` est en cours de développement. Par ailleurs, les recommandations d'`utilitR` peuvent évoluer en fonction du développement du _package_. - Il ne faut pas hésiter à demander de l'aide à des collègues, ou à poser des questions sur les salons Tchap adaptés (le salon Langage `R` par exemple). ::: {.callout-important collapse="true"} ## Pourquoi utiliser `duckdb` plûtot que `arrow` ? -Bien que les *packages* `duckdb` et `arrow` aient des cas d'usage très similaires (voir la fiche [Manipuler des données avec `arrow`](#arrow)), l'utilisation de `duckdb` **est à privilégier** . On peut également les utiliser ensemble pour profiter de chacun de leurs avantages. Le tableau ci-dessous compare quelques cas d'usage de ces deux *packages* : +Bien que les *packages* `duckdb` et `arrow` aient des cas d'usage très similaires (voir la fiche [Manipuler des données avec `arrow`](#arrow)), l'utilisation de `duckdb` **est à privilégier** . En effet, `duckdb` est d'un usage plus général, plus fiable et plus rapide qu' `arrow`. +Le tableau ci-dessous compare quelques cas d'usage de ces deux *packages* : | Je souhaite... | arrow | duckdb | | ------------------------------------------------------------------------- | ----- | ------ | @@ -30,25 +32,13 @@ Bien que les *packages* `duckdb` et `arrow` aient des cas d'usage très similair | Utiliser la syntaxe `dplyr` pour traiter mes données | ✔️ | ✔️ | | Utiliser du langage SQL pour traiter mes données | ❌ | ✔️ | | Joindre des tables très volumineuses (plus de 4 Go) | ❌ | ✔️ | -| Utiliser des fonctions fenêtres (voir @sec-arrow) | ❌ | ✔️ | -| Utiliser des fonctions statistiques qui n'existent pas dans arrow (voir @sec-arrow) | ❌ | ✔️ | +| Utiliser des fonctions fenêtres (voir @sec-sql) | ❌ | ✔️ | +| Utiliser des fonctions statistiques qui n'existent pas dans arrow (voir @sec-sql) | ❌ | ✔️ | | Écrire un fichier .parquet | ✔️ | ✔️ * | \* pour écrire un fichier .parquet avec le package `duckdb`, il faut utiliser une instruction SQL (voir @sec-ecrire-parquet) ::: -::: {.callout-important collapse="true"} -## Tâches concernées et recommandations - -- Pour des tables de données de taille petite et moyenne (inférieure à 1 Go ou moins d'un million d'observations), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui sont présentés dans la fiche [Manipuler des données avec le `tidyverse`](#tidyverse); - -- Pour des tables de données de grande taille (plus de 1 Go en CSV, plus de 200 Mo en Parquet, ou plus d'un million d'observations), il est recommandé d'utiliser le *package* `duckdb` qui fait l'objet de la présente fiche. - -- Il est essentiel de travailler avec la dernière version de `duckdb` et de `R` car le *package* `duckdb` est en cours de développement. Par ailleurs, les recommandations d'`utilitR` peuvent évoluer en fonction du développement du _package_. - -- Si les données sont très volumineuses (plus de 5 Go en CSV, plus de 1 Go en Parquet ou plus de 5 millions d'observations), il est recommandé de manipuler les données avec `duckdb` plutôt qu'avec le `tidyverse`. Il peut arriver que le volume de données soit tellement important qu'il ne soit pas possible de les traiter avec `duckdb`; il faut s'orienter vers des infrastructures *big data* permettant le calcul distribué et utiliser des logiciels adaptés (`Spark` par exemple). -::: - ## Présentation du projet `DuckDB` et du _package_ `R` associé ::: {.callout-note collapse="true"} @@ -116,9 +106,22 @@ library(dplyr) Le moteur `duckdb` fonctionnant "en dehors" de `R`, il détecte le nombre de processeurs et effectue les opérations en parallèle si possible. +::: {.callout-important collapse="true"} +## Utilisation des packages `dplyr` / `dbplyr` / `duckplyr` + +Trois packages coexistent pour manipuler des données avec la syntaxe `dplyr` : + +- `dplyr` est le package de référence pour manipuler des `data.frame` et `tibble` en mémoire. +- `dbplyr` est une extension qui permet d'utiliser la syntaxe `dplyr` avec n'importe quelle base de données SQL (dont DuckDB) : il traduit automatiquement le code `dplyr` en requêtes SQL, mais nécessite une connexion explicite et un `collect()` pour récupérer les résultats dans `R`. +- [`duckplyr`](https://duckplyr.tidyverse.org/), présent dans le tidyverse, est une alternative plus récente : il se présente comme un remplacement direct de `dplyr` (même syntaxe, même comportement), en utilisant DuckDB comme moteur de calcul en arrière-plan. Contrairement à `dbplyr`, il n'y a pas de notion de connexion ni de `collect()`. `duckplyr` travaille directement sur des `tibble` et bascule automatiquement sur DuckDB quand c'est possible, avec un repli sur `dplyr` sinon. + +Pour l'instant, il est recommandé de rester avec l'utilisation des packages `dplyr` et `dbplyr`. + +::: + ### Connexion à une base de données -**Principe : `duckdb` est une base de données distante: il faut ouvrir une connexion, puis "charger" les données dans la base de données pour les manipuler. A la fin du traitement, il faut fermer la connexion.** +`duckdb` est une base de données distante: il faut ouvrir une connexion, puis "charger" les données dans la base de données pour les manipuler. A la fin du traitement, il faut fermer la connexion. #### Ouvrir une connexion @@ -166,7 +169,7 @@ Maintenant que la connexion à une base de données duckDB est créée, chargeon __La fonction `duckdb_register()` permet de charger dans `duckdb` des données présentes dans la session `R`.__ Cette méthode a l'avantage de ne pas _recopier_ les données: elle se contente d'établir un lien logique entre la base de données `duckdb` et un objet de la session `R`. -Voici un exemple avec la Base permanente des équipements: grâce à la fonction `duckdb::duckdb_register()`, l'objet `bpe_ens_2018` est référencé dans la base de données `duckdb` sous le nom `bpe_ens_2018_duckdb`. +*Voici un exemple avec la Base permanente des équipements: grâce à la fonction `duckdb::duckdb_register()`, l'objet `bpe_ens_2018` est référencé dans la base de données `duckdb` sous le nom `bpe_ens_2018_duckdb`.* ```{r} # Charger la Base permanente des équipements 2018 dans la session R @@ -180,7 +183,9 @@ conn_ddb %>% duckdb::duckdb_register( ::: {.callout-tip collapse="true"} ## Vérifier que le chargement des données a bien fonctionné -Le code ci-dessous permet de vérifier que le chargement des données a bien fonctionné. La fonction `tbl` permet d'accéder à un objet de la base de données par le nom (de la table), ou par du code SQL (utilisation un peu plus avancée). Par défaut, `duckdb` affiche les 10 premières lignes du résultat, sans effectuer tout le calcul. C'est très pratique et très rapide ! +Le code ci-dessous permet de vérifier que le chargement des données a bien fonctionné. La fonction `tbl` permet d'accéder à un objet de la base de données par le nom (de la table), ou par du code SQL (utilisation un peu plus avancée). + +Par défaut, `duckdb` affiche les 10 premières lignes du résultat, sans effectuer tout le calcul. C'est très pratique et très rapide ! ```{r} conn_ddb %>% tbl("bpe_ens_2018_duckdb") @@ -190,7 +195,7 @@ conn_ddb %>% tbl("bpe_ens_2018_duckdb") #### Chargement de données stockées sur le disque dur -::: {.callout-note colapse="true"} +::: {.callout-note collapse="true"} ## Préambule : sauvegarder la table de travail sur le disque dur Pour l'exemple suivant, on sauvegarde les données `bpe_ens_2018` au format Parquet. @@ -229,7 +234,7 @@ conn_ddb %>% tbl('bpe_ens_2018_dataset/**/*.parquet') Le _package_ `R` `duckdb` a été écrit de façon à pouvoir manipuler les données avec la syntaxe de `dplyr` (`select`, `filter`, `mutate`, `left_join`, etc.). `duckdb` traduit le code `R`, y compris certaines fonctions de `stringr` et `lubridate` en requête SQL. Cela s'avère très commode en pratique, car lorsqu'on sait utiliser `dplyr` et le `tidyverse`, on peut commencer à utiliser `duckdb` sans avoir à apprendre une nouvelle syntaxe de manipulation de données. -Dans l'exemple suivant, on calcule le nombre d'équipements par région, à partir d'un `tibble` et à partir d'une table `duckdb`: +*Dans l'exemple suivant, on calcule le nombre d'équipements par région, à partir d'un `tibble` et à partir d'une table `duckdb`:* :::: {.columns} @@ -270,12 +275,14 @@ bpe_ens_2018_dataset |> La seule différence apparente entre les deux traitement est la présence de la fonction `collect()` à la fin des instructions. -:::{.callout-note collaspe="true"} +::: {.callout-note collapse="true"} ## La fonction `collect()` -Cette fonction indique que l'on souhaite obtenir le résultat du traitement sous la forme d'un `tibble`. Les résultats sont identiques, à l'exception de l'ordre des lignes. En effet, un moteur SQL ne respecte pas l'ordre par défaut, il faut le demander explicitement avec `arrange`. +Cette fonction indique que l'on souhaite obtenir le résultat du traitement sous la forme d'un `tibble` : *ie.* qu'on passe d'une table `duckdb` à un objet disponible dans l'environnement `R`. Les résultats sont identiques, à l'exception de l'ordre des lignes. En effet, un moteur SQL ne respecte pas l'ordre par défaut, il faut le demander explicitement avec `arrange`. ::: +::: {.callout-note collapse="true"} +## Comment `duckdb` exécute une requête `dplyr` On peut examiner la requête SQL construite par `duckdb` avec la fonction `show_query()`. ```{r} @@ -290,368 +297,363 @@ bpe_ens_2018_dataset |> Cette requête est envoyée au serveur SQL et exécutée de façon différente en fonction de la dernière instruction du traitement: - si le traitement se termine par `collect()`: le calcul est exécuté en entier et le résultat est retourné sous la forme d'un `tibble`, -- si le traitement se termine par print(n=nb_lignes) : dbplyr ajoute automatiquement un LIMIT à la requête SQL. Dans le cas où il n'y a pas d'opérations bloquantes (agrégations, tris...), DuckDB peut exploiter ce LIMIT pour ne lire qu'une partie des données et retourner rapidement les premières lignes. En présence d'opérations bloquantes, toutes les données sont néanmoins traitées. +- si le traitement se termine par `print(n=nb_lignes)` : `dplyr` ajoute automatiquement un LIMIT à la requête SQL. **Dans le cas où il n'y a pas d'opérations bloquantes (agrégations, tris...), `duckdb` peut exploiter ce LIMIT pour ne lire qu'une partie des données et retourner rapidement les premières lignes. En présence d'opérations bloquantes, toutes les données sont néanmoins traitées.** *Il ne faut pas hésiter à s'en servir pour explorer les données et pour construire le traitement étape par étape, en ajustant en fonction des résultats.* -__Ce point est important: en utilisant `print()` en l'abscence d'opérations bloquantes on peut prévisualiser le résultat d'une requête `duckdb` de façon très rapide, sans exécuter tout le traitement.__ Il ne faut pas hésiter à s'en servir pour explorer les données et pour construire le traitement étape par étape, en ajustant en fonction des résultats. +::: +### Manipulation des données avec SQL +`DuckDB` étant un moteur SQL à part entière, on peut interagir avec `DuckDB` directement avec des requêtes SQL. +Avec DuckDB, on peut matérialiser un résultat à l'aide de requêtes SQL de deux façons : -### Écriture au format Parquet +- **Une table** : les données sont calculées et stockées physiquement (en mémoire ou sur disque). C'est utile si le calcul est long et que vous souhaitez réutiliser le résultat plusieurs fois sans le recalculer. +- **Une vue (view)** : aucune donnée n'est stockée. Une vue n'est qu'un raccourci vers une requête SQL qui sera ré-exécutée à chaque utilisation. Elle ne consomme pas de mémoire. -Pour écrire une table (ou le résultat de n'importe quelle requête) sur le disque au format Parquet, il faut utiliser l'instruction suivante (ici, nous exportons un data.frame présent dans l'environnement R dans un fichier parquet): +En pratique, préférez toujours une vue si vous n'avez pas besoin de conserver le résultat durablement. +Pour créer une table ou une vue, on utilise `DBI::dbExecute()` qui envoie une instruction SQL à DuckDB : + ```{r} -dir.create("temp_dataset", showWarnings = FALSE) -duckdb::duckdb_register(conn_ddb, "bpe_ens_2018_temp", bpe_ens_2018) # ajouter l'objet R dans la base duckDB -DBI::dbExecute(conn_ddb, "COPY bpe_ens_2018_temp TO 'temp_dataset/bpe_ens_2018.parquet' (FORMAT PARQUET)") -list.files("temp_dataset") -``` - -::: {.callout-warning collapse="true"} -## Utilisation du package `arrow` pour l'export de fichier parquet -Même si le package `arrow` peut sembler plus simple à utiliser que SQL pour certaines manipulations `dplyr`, il est préférable de rester avec `duckdb` pour limiter les dépendances et garder une approche cohérente. -::: - -### Erreurs courantes - -| Erreur | Description | Solution | -|--------|-------------|----------| -| Colonne absente | Une colonne utilisée dans un calcul a été supprimée en amont par `select()` | Conserver toutes les colonnes nécessaires aux étapes suivantes dans le `select()` | -| Type booléen non converti | Multiplication d'un booléen (ex. `TYPEQU == "B203"`) par un nombre : DuckDB n'effectue pas cette conversion implicitement | Convertir explicitement en entier : `as.integer(TYPEQU == "B203")` | - +# Créer une table dans la base de données DuckDB +DBI::dbExecute(conn_ddb, " + CREATE TABLE bpe_ens_2018_table AS + SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT + FROM bpe_ens_2018_duckdb + GROUP BY REG") # Utilise de la mémoire -## Notions avancées / bien utiliser `duckdb` +# Créer une vue dans la base de données DuckDB (Recommandé) +DBI::dbExecute(conn_ddb, " + CREATE VIEW bpe_ens_2018_view AS + SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT + FROM bpe_ens_2018_duckdb + GROUP BY REG") # n'utilise pas de mémoire -### Configurer `duckdb` {#sec-configuration} +# Lire le résultat dans R sous forme de tibble +nb_equip_bpe <- DBI::dbGetQuery(conn_ddb, "SELECT * FROM bpe_ens_2018_view") +``` -`duckdb` propose de nombreux paramètres mais nous n'allons voir que les principaux. Vous pouvez vous reporter à la [documentation officielle](https://duckdb.org/docs/configuration/overview) pour en apprendre davantage sur la configuration de `duckdb`. +::: {.callout-note} +`DBI::dbExecute()` est utilisé pour les instructions qui modifient la base (créer une table, une vue, insérer des lignes...) : il retourne le nombre de lignes affectées. -::: {.callout-note collapse="true"} -#### Configuration lors de l'initialisation +`DBI::dbGetQuery()` est utilisé pour les instructions qui retournent des données (SELECT) : il retourne un tibble. +::: -Pour configurer `duckdb` lors de l'initialisation de la base de données (c'est-à-dire au moment où on utilise `DBI::dbConnect(drv = duckdb::duckdb())`), on utilise les arguments du _driver_ `duckdb`. +Vous pouvez ensuite requêter les objets créés dans la base SQL via `dplyr`: ```{r} -#| eval: false -# Configurer le driver duckdb -drv <- duckdb::duckdb( - dbdir = "fichier.db", - config = list( - threads = "4", - memory_limit = "40GB", - temp_directory = "tmp_path/", - preserve_insertion_order = "true") -) - -# Initaliser la base de données duckdb avec la configuration -conn_ddb <- DBI::dbConnect(drv = drv) +conn_ddb %>% tbl("bpe_ens_2018_view") ``` -Voici une description des principaux paramètres de configuration: +Vous pouvez bien sûr lire des fichiers `Parquet`, `CSV` ou autres en utilisant les [fonctions de duckdb](https://duckdb.org/docs/data/overview) : +```{r} +DBI::dbGetQuery(conn_ddb, "SELECT * FROM read_parquet('bpe_ens_2018_dataset/**/*.parquet') LIMIT 5") +``` -- **`dbdir` : utiliser une base de données persistante**. Par défaut, `duckdb` crée une base de données dans la mémoire vive, qui est automatiquement détruite lorsque vous fermez la session `R` ou la connexion `duckdb`. Si vous mettez un chemin dans le paramètre `dbdir`, `duckdb` créera une base de données sur disque que vous pourrez réouvrir à votre prochaine session. +::: {.callout-tip} +Le SQL de `duckdb` est très proche de celui de PostgreSQL avec [quelques évolutions très pertinentes](https://duckdb.org/docs/guides/sql_features/friendly_sql). +::: -Si vous utilisez principalement `dplyr`, les bases de données en mémoire sont certainement suffisantes. En revanche, ce paramètre peut éventuellement vous être utile si vous utilisez du SQL, si vous créez des vues ou si vous utilisez `dplyr::compute`. -- **`threads` : limiter le nombre de _threads_ utilisés par `duckdb`**. Pour simplifier, un _thread_ est un processeur ou un morceau de processeur (l'unité électronique qui réalise les calculs). Par défaut, `duckdb` utilise tous les processeurs disponibles, ce qui n'est pas forcément souhaitable pour plusieurs raisons : +#### Séparer vos traitements SQL en blocs -- sur un serveur partagé, vos collègues seront gênés ; -- il est [conseillé de disposer de 5 à 10Go](https://duckdb.org/docs/guides/performance/environment.html) de mémoire par _thread_ (5 pour des aggrégations, 10 pour des jointures) donc beaucoup de threads implique beaucoup de mémoire ; -- avoir trop de _threads_ peut être contre-productif. +Si vos requêtes deviennent trop complexes et/ou longues, vous pouvez facilement les découper en créant des vues intermédiaires que vous réutiliserez plus tard : -Il n'existe pas de règle générale pour définir le nombre de _threads_, mais utiliser 4 à 8 _threads_ (en respectant le ratio _threads_/mémoire ci-dessus) constitue un point de départ raisonnable. Au delà, les performances augmentent généralement peu pour une consommation mémoire plus importante. +```{r eval=FALSE} +# Créer une vue qui correspond à la première étape du traitement +dbExecute(conn_ddb, "CREATE OR REPLACE VIEW data1_nettoye AS SELECT ... FROM read_parquet('data1.parquet')") -- **`memory_limit` : limiter la mémoire vive utilisée par `duckdb`**. Par défaut, `duckdb` limite la mémoire à 80% de la mémoire disponible sur le serveur. Si vous avez une quantité limitée de mémoire, essayez plutôt de limiter le nombre de _threads_ en respectant la règle de 5 à 10 Go par thread. +# Créer une vue qui correspond à la deuxième étape du traitement +dbExecute(conn_ddb, "CREATE OR REPLACE VIEW data2_nettoye AS SELECT ... FROM read_parquet('data2.parquet')") -- **`temp_directory` : définir le dossier sur disque dans lequel `duckdb` peut écrire des fichiers temporaires**. Un avantage de `duckdb` est qu'il sait ["déborder" sur disque](https://duckdb.org/docs/guides/performance/how_to_tune_workloads.html#larger-than-memory-workloads-out-of-core-processing) pour une grande partie de ces opérations. Cela signifie que `duckdb` va écrire dans des fichiers temporaires sur le disque les données qu'il ne peut conserver en mémoire car il a atteint la limite de mémoire fixée. Le paramètre `temp_directory` permet de choisir dans quel dossier ces fichiers temporaires seront écrits. Toutefois, il est généralement beaucoup plus efficace de diminuer le nombre de _threads_ que de déborder sur disque mais dans le cas où vous avez besoin de "juste un peu plus" de mémoire cela peut se révéler utile. A noter que ce paramètre est automatiquement fixé si vous avez décidé d'utiliser une base persistante. +# Faire la dernière étape du traitement et récupérer les résultats dans un tibble +resultats <- dbGetQuery(conn_ddb, "SELECT * FROM data1_nettoye LEFT JOIN data2_nettoye ON data1.id = data2.id") +``` -- **`preserve_insertion_order` : préserver l'ordre de lecture/écriture ou non**. `duckdb` peut consommer beaucoup de mémoire pour conserver l'ordre de lecture et d'écriture. Ce dernier paramètre permet d'autoriser `duckdb` à ne pas préserver l'ordre des données à la lecture et à l'écriture des fichiers dans le cas où il n'y a pas de clause `ORDER BY` / `arrange`. -::: +Et vous pouvez bien sûr créer des tables intermédiaires (temporaires ou non) à la place des vues (en utilisant `CREATE TABLE` pluôt que `CREATE VIEW`) pour éviter de les recalculer à chaque fois. ::: {.callout-note collapse="true"} -#### Fixer les paramètres après l'initialisation +## Regrouper plusiuers requêtes SQL dans une seule -Vous pouvez également changer les paramètres d'une base après son initialisation en utilisant la commande `dbExecute`. Par exemple, pour fixer le nombre de _threads_ à 4 : +Vous pouvez grouper les requêtes SQL dans un même `dbExecute` : -```{r} -#| eval: false -dbExecute(conn_ddb, "SET threads = '4';") +```{r eval=FALSE} +# Créer une vue qui correspond à la première étape du traitement +dbExecute(conn_ddb, + "CREATE OR REPLACE VIEW data1_nettoye AS SELECT ... FROM read_parquet('data1.parquet'); + CREATE OR REPLACE VIEW data2_nettoye AS SELECT ... FROM read_parquet('data2.parquet'); + SELECT * FROM data1_nettoye LEFT JOIN data2_nettoye ON data1.id = data2.id")" +) ``` -::: - -### L'évaluation différée avec `duckdb` (_lazy evaluation_) {#sec-lazy} - -::: {.callout-tip} -Il est vivement conseillé de lire la fiche [Manipuler des données avec `arrow`](#arrow) avant de lire cette section, en particulier la partie sur l'évaluation différée. -::: - -Quand on manipule des objets `duckdb`, on construit des requêtes SQL. Le _package_ `duckdb` se contente de traduire le code `dplyr` en `SQL` sans l'exécuter (de la même façon que le _package_ `arrow` traduit du code `dplyr` en instructions C++). On rappelle qu'il faut utiliser `show_query()` pour visualiser la requête. La fonction `print()` permet de pré-visualiser le résultat. -```{r} -# Étape 1: compter les équipements -req_dep <- - bpe_ens_2018_dataset |> - group_by(DEP) |> - summarise( - NB_EQUIP_TOT = sum(NB_EQUIP) - ) -req_dep |> - show_query() +Ou utiliser la clause SQL `WITH` : -# Étape 2: filtrer sur le département -req_dep_filter <- req_dep |> - filter(DEP == "59") -req_dep_filter |> - show_query() +```{r eval=FALSE} +# Créer une vue qui correspond à la première étape du traitement +dbExecute(conn_ddb, + "WITH data1_nettoye AS (SELECT ... FROM read_parquet('data1.parquet')), + data2_nettoye AS (SELECT ... FROM read_parquet('data2.parquet')) + SELECT * FROM data1_nettoye LEFT JOIN data2_nettoye ON data1.id = data2.id")" +) ``` -La fonction `collect()` génère le SQL, l'envoie à `duckdb` pour exécuter le calcul, et transmet les résultats à `R`. Un point essentiel est que tous les ordres passés avant l'instruction `collect()` seront exécutés par le moteur SQL de `duckdb`, tandis que ceux passés après l'instruction `collect()` seront réalisés par le moteur de `R` sur un objet `R` (`tibble`) standard. Par conséquent, il faut passer le plus d'ordres possibles avant `collect()` pour bénéficier de la rapidité du moteur SQL ! +::: -```{r} -req_dep_filter |> collect() -``` -On pourrait penser que, lorsqu'on exécute l'ensemble de ce traitement, `duckdb` se contente d'exécuter les instructions les unes après les autres: compter les équipements par département, puis conserver uniquement le département 59. Mais en réalité `duckdb` fait beaucoup mieux que cela: __`duckdb` analyse la requête avant de l'exécuter, et optimise le traitement pour minimiser le travail__. Dans le cas présent, `duckdb` repère que la requête ne porte en fait que sur le département 59, et commence donc par filtrer les données sur le département avant de compter les équipements, de façon à ne conserver que le minimum de données nécessaires et à ne réaliser que le minimum de calculs. Ce type d'optimisation s'avère très utile quand les données à traiter sont très volumineuses. +### Écriture au format Parquet {#sec-ecrire-parquet} +Pour écrire une table (ou le résultat de n'importe quelle requête) sur le disque au format Parquet avec `duckdb`, il faut utiliser l'instruction SQL `COPY ... TO ... (FORMAT PARQUET)` -:::: {.columns} +*Par exemple, nous exportons un data.frame présent dans l'environnement `R` dans un fichier parquet*: -::: {.column width="49%"} +```{r} +dir.create("temp_dataset", showWarnings = FALSE) # Création d'un répertoire pour l'export du fichier parquet -__Situation à éviter__ +duckdb::duckdb_register(conn_ddb, "bpe_ens_2018_temp", bpe_ens_2018) # ajouter l'objet R dans la base duckDB +DBI::dbExecute(conn_ddb, "COPY bpe_ens_2018_temp TO 'temp_dataset/bpe_ens_2018.parquet' (FORMAT PARQUET)") -La première étape de traitement est déclenchée par `collect()`, la table intermédiaire `res_etape1` est donc un `tibble`. C'est le moteur d'exécution de `dplyr` qui est utilisé pour manipuler `res_etape1` lors de la seconde étape, ce qui dégrade fortement les performances sur données volumineuses. +list.files("temp_dataset") # Lecture des fichiers présents dans le répertoire "temp_dataset" +``` -```{r} -# Etape 1 -res_etape1 <- - bpe_ens_2018_dataset |> - group_by(DEP) |> - summarise( - NB_EQUIP_TOT = sum(NB_EQUIP) - ) |> - collect() +Attention, l'instruction SQL `COPY ... TO ... (FORMAT PARQUET)` permet d'exporter des tables `duckdb` uniquement. Pour exporter une table depuis l'environnement `R`, il faut établir un lien entre la base `duckdb` et la table présente dans la session `R` grâce à la foncton `duckdb_register()`. -# Etape 2 -res_final <- res_etape1 |> - filter(DEP == "59") |> - collect() +Vous pouvez aussi utiliser les fonctions d'export du _package_ `duckplyr` : -# Sauvegarder les résultats -arrow::write_parquet(res_final, "resultats.parquet") +```{r, eval=FALSE} +req <- duckplyr::as_duckdb_tibble(source_data) |> + # opérations dplyr ... + duckplyr::compute_parquet("mon_dataset.parquet") ``` +::: {.callout-warning} +`compute_parquet()` écrit un fichier Parquet unique et ne supporte pas le partitionnement. Si vous avez besoin d'un dataset partitionné, utilisez la commande SQL `COPY ... TO ... (FORMAT PARQUET, PARTITION_BY (...))`. ::: -::: {.column width="2%"} - +::: {.callout-caution collapse="true"} +## Utilisation du package `arrow` pour l'export de fichier parquet +Même si le package `arrow` peut sembler plus simple à utiliser que SQL pour certaines manipulations `dplyr`, il est préférable de rester avec `duckdb` pour limiter les dépendances et garder une approche cohérente. ::: -::: {.column width="49%"} +## Bien utiliser `duckdb` avec l'évaluation différée {#sec-lazy} -__Usage recommandé__ - -La première étape construit une requête SQL, sans effectuer de calcul. La deuxième étape complète la requête sans effectuer de calcul. Ici, pas de fonction `print()`, donc pas de calcul partiel. Le calcul n'est exécuté qu'au moment de la sauvegarde des résultats par `DuckDB`, ce qui assure de bonnes performances notamment sur données volumineuses. Les données ne sont chargées dans la mémoire de `R` à aucun moment. +### Principe : construire la requête avant de l'exécuter +Quand on écrit du code `dplyr` avec `duckdb`, les instructions ne sont **pas exécutées immédiatement** : `dbplyr` les traduit en SQL et attend. On dit que les objets créés sont des **requêtes différées** : ils décrivent ce qu'il faut faire, sans le faire encore. ```{r} -# Etape 1 -res_etape1 <- bpe_ens_2018_dataset |> +# Ces deux étapes ne déclenchent aucun calcul +req_etape1 <- bpe_ens_2018_dataset |> group_by(DEP) |> - summarise( - NB_EQUIP_TOT = sum(NB_EQUIP) - ) + summarise(NB_EQUIP_TOT = sum(NB_EQUIP)) -# Etape 2 -res_final <- res_etape1 |> - filter(DEP == "59") - -# Sauvegarder les résultats -res_final |> arrow::to_arrow() |> - arrow::write_parquet("resultats.parquet") +req_etape2 <- req_etape1 |> + filter(DEP == "59") ``` +::: {.callout-tip} +Si vous ne savez plus si un objet est une requête différée ou un `tibble` contenant des données, exécutez `class(votre_objet)` : une requête différée a la classe `tbl_dbi`, un tibble a la classe `tbl_df`. ::: -:::: +### Visualiser la requête SQL avec `show_query()` -::: {.callout-tip} -Si vous ne savez plus si une table de données est une requête SQL ou un `tibble`, il suffit d'exécuter `print(votre_table)` ou `class(votre_table)`. -::: +À tout moment, on peut inspecter la requête SQL construite par `dbplyr` avec `show_query()` : +```{r} +req_etape1 |> show_query() +req_etape2 |> show_query() +``` -### Fonctions non traduites et/ou comment passer des paramètres ? {#sec-sql} +On constate que la deuxième requête **contient** la première : `duckdb` a assemblé toutes les instructions en une seule requête SQL. On remarque également que `duckdb` a **réordonné** les opérations : le filtre sur le département 59 est appliqué _avant_ l'agrégation, afin de réduire la quantité de données à traiter. C'est l'optimiseur de `duckdb` qui fait ce travail automatiquement. -Il peut arriver que le _package_ `duckdb` ne parvienne pas à traduire votre code `dplyr` en SQL, par exemple lorsque vous voulez utiliser une fonction `R` dont `duckdb` ne connaît pas la traduction SQL, ou lorsque vous voulez passer un paramètre à une fonction. Pour surmonter ce problème (heureusement peu fréquent), il faut mettre les mains dans le mécanisme de traduction vers SQL. Il y a deux points importants: +### Déclencher l'exécution avec `collect()` -- Lorsque `duckdb` ne connaît pas la traduction SQL d'une fonction `R` est que **la fonction inconnue est reprise directement dans le code SQL** sans aucune modification. Voici un exemple, dans lequel on peut voir que la fonction `fonction_inexistante()` apparaît telle quelle dans le code SQL. +L'exécution n'a lieu qu'au moment où on appelle `collect()`, qui envoie la requête SQL à `duckdb` et retourne le résultat sous forme de `tibble` dans R : ```{r} -req <- bpe_ens_2018_dataset |> - mutate(test = fonction_inexistante(DEP)) |> - show_query() +req_etape2 |> collect() ``` -- `DuckDB` contient un grand nombre de fonctions optimisées ([documentation ici](https://duckdb.org/docs/sql/functions/overview)), et il est possible de les utiliser directement dans du code `R`. +Tant que l'instruction `collect()` n'est pas exécutée, aucun calcul n'a lieu : les instructions `dplyr` s'accumulent silencieusement pour former une requête. Au moment de l'exécution de `collect()`, `dbplyr` traduit l'ensemble de ces instructions en une seule requête SQL, puis la transmet à `duckdb` qui l'exécute. `duckdb` renvoie le résultat à R sous forme de `tibble`. Tout ce qu'on écrit **après** `collect()` est ensuite exécuté par R sur ce `tibble`. +Il faut donc passer **le maximum d'opérations avant** `collect()`, pour que `duckdb` les exécute de façon optimisée plutôt que R. -Ces deux points ensemble permettent de **surmonter dans la plupart des cas le problème des fonctions `R` inconnues de `duckdb`: il suffit d'appeler la fonction de `DuckDB` qui fait la même chose**. Voici un exemple qui explique cela en détail dans le cas de la fonction `R` `as.Date()`. On commence par créer une petite table `duckdb` contenant des dates sous forme de chaînes de caractères avec le format "DD/MM/YYYY". +::: {.callout-tip collapse="true"} +## Astuce : sauvegarder sans `collect()` -```{r} -# Créer des dates sous forme de chaînes de caractères -dates <- tibble( - date_naissance = c("02/07/1980", "29/02/2004"), - date_deces = c("05/06/2001", "12/07/2023") -) +Il est possible de sauvegarder le résultat directement sur disque sans jamais charger les données dans R, en utilisant `COPY` à la place de `collect()`. `dbplyr::remote_query()` récupère la requête SQL sans déclencher son exécution : -# Créer une connexion entre ces données et la base de données duckdb -conn_ddb %>% duckdb::duckdb_register(name = "dates_duckdb", df = dates, overwrite = TRUE) +```{r} +DBI::dbExecute(conn_ddb, paste0( + "COPY (", dbplyr::remote_query(req_etape2), ") TO 'resultats.parquet' (FORMAT PARQUET)" +)) ``` +::: -Le _package_ `duckdb` dispose d'une traduction SQL de la fonction `as.Date()`, mais cette traduction a deux limites: elle n'accepte que les données en format "YYYY-MM-DD", et ne supporte pas l'argument `format` qui permet de préciser que les données sont en format "DD/MM/YYYY". Par conséquent, on rencontre une erreur si on essaie d'utiliser la fonction `as.Date()` avec l'argument `format` (car `duckdb` ne sait pas gérer cet argument), et on rencontre une erreur si on essaie d'utiliser la fonction `as.Date()` sans cet argument (car les données n'ont pas le bon format). +### Limites de l'évaluation différée -```{r error=TRUE} -conn_ddb %>% tbl("dates_duckdb") %>% - mutate(date_naissance = as.Date(date_naissance, format = "%d/%m/%Y")) # erreur -``` +L'évaluation différée est très efficace, mais elle a ses limites. Pour des traitements complexes (nombreuses jointures, agrégations multiples), la requête SQL générée peut devenir très volumineuse et nécessiter beaucoup de mémoire pour être exécutée en une seule fois. +Lorsque `duckdb` manque de mémoire, il retourne une erreur explicite — voir @sec-configuration pour les options de configuration mémoire. -```{r error=TRUE} -conn_ddb %>% tbl("dates_duckdb") %>% - mutate(date_naissance = as.Date(date_naissance)) # erreur -``` +Une autre limite concerne la **lisibilité et le débogage** : une requête correspondant à 200 lignes de code `dplyr` est difficile à inspecter et à corriger en cas d'erreur. -On pourrait penser que ce problème est sérieux. En fait, la solution est très simple: il suffit d'utiliser la fonction [`strptime`](https://duckdb.org/docs/sql/functions/dateformat.html) du moteur SQL `DuckDB` en indiquant le paramètre adéquat. Comme vous pouvez voir dans l'exemple suivant, on appelle cette fonction directement dans le code `R`. Par ailleurs, cette façon d'utiliser les fonctions de `DuckDB` dans du code `R` permet de passer facilement un paramètre à une fonction (le format "%d/%m/%Y" dans le cas présent). +### Décomposer le traitement avec `compute()` -```{r} -conn_ddb %>% tbl("dates_duckdb") %>% - mutate(date_naissance = strptime(date_naissance, "%d/%m/%Y")) -``` +La solution consiste à découper le traitement en étapes, en matérialisant les résultats intermédiaires avec `compute()`. Contrairement à `collect()`, `compute()` crée une **table temporaire dans `duckdb`** : les données restent dans `duckdb`, elles ne sont pas chargées dans R. -::: {.callout-note} +```{r eval=FALSE} +# Étape 1 : retraitement de la première table — résultat stocké dans duckdb +table_intermediaire1 <- bpe_ens_2018_dataset |> + select(...) |> + filter(...) |> + mutate(...) |> + compute() -La logique présentée ici fonctionne également dans un cas plus avancé: l'utilisation d'une fonction sur plusieurs variables avec `mutate_at`. L'exemple ci-dessous reprend l'exemple ci-dessus avec deux variables. +# Étape 2 : retraitement de la deuxième table +table_intermediaire2 <- autre_dataset |> + select(...) |> + filter(...) |> + compute() -```{r} -liste_variables <- c("date_naissance","date_deces") -conn_ddb %>% tbl("dates_duckdb") %>% - mutate_at(liste_variables, ~ strptime(.,"%d/%m/%Y")) +# Étape 3 : jointure et résultat final dans R +resultat <- table_intermediaire1 |> + left_join(table_intermediaire2, by = "identifiant") |> + collect() ``` -::: +::: {.callout-tip} +## Quelques conseils pour bien séquencer les étapes +1 - **Cohérence logique** : les étapes doivent avoir un sens. Si le traitement consiste à retraiter deux tables puis à les joindre, trois étapes s'imposent naturellement. +2 - **Longueur raisonnable** : une étape de 30 à 40 lignes est un bon point de départ ; au-delà, la requête risque d'être trop complexe. +3 - **Jointures volumineuses** : éviter d'enchaîner plus de deux ou trois jointures sur de grandes tables sans `compute()` intermédiaire. +4 - **Construire progressivement** : vérifier le résultat de chaque étape avec `print()` avant d'ajouter la suivante. +::: -### Manipulation des données avec SQL +## Notions avancées -`DuckDB` étant un moteur SQL à part entière, on peut interagir avec `DuckDB` directement avec des requêtes SQL. Par exemple, en reprenant une table enregistrée plus haut avec la fonction `duckdb::duckdb_register` : +### Configurer `duckdb` {#sec-configuration} -```{r} -DBI::dbGetQuery(conn_ddb, "SELECT * FROM bpe_ens_2018_duckdb") |> head() -``` +`duckdb` propose de nombreux paramètres mais nous n'allons voir que les principaux. Vous pouvez vous reporter à la [documentation officielle](https://duckdb.org/docs/configuration/overview) pour en apprendre davantage sur la configuration de `duckdb`. -Vous pouvez créer des vues ou des tables explicitement. La fonction `dbExecute()` retourne le nombre de lignes modifiées, tandis que la fonction `dbGetQuery` retourne le résultat sous la forme d'un `tibble`. Si vous n'avez pas l'intention de conserver durablement une table intermédiaire, il est préférable de créer une vue (qui ne consomme pas de mémoire) plutôt qu'une table (qui consomme de la mémoire). On peut d'ailleurs noter que les fonctions `read_parquet()` en SQL et `duckdb_register` du _package_ utilisent `CREATE VIEW` implicitement. +::: {.callout-note collapse="true"} +#### Configuration lors de l'initialisation de la base de données -```{r} -# Créer une table dans la base de données DuckDB -DBI::dbExecute(conn_ddb, " - CREATE TABLE bpe_ens_2018_table AS - SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT - FROM bpe_ens_2018_duckdb - GROUP BY REG") # Utilise de la mémoire +Pour configurer `duckdb` au moment de la connexion, on passe les options dans le _driver_ avant d'appeler `DBI::dbConnect()` : -# Créer une vue dans la base de données DuckDB -DBI::dbExecute(conn_ddb, " - CREATE VIEW bpe_ens_2018_view AS - SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT - FROM bpe_ens_2018_duckdb - GROUP BY REG") # n'utilise pas de mémoire +```{r} +#| eval: false +drv <- duckdb::duckdb( + dbdir = "fichier.db", + config = list( + threads = "4", + memory_limit = "40GB", + temp_directory = "tmp_path/", + preserve_insertion_order = "true" + ) +) +conn_ddb <- DBI::dbConnect(drv = drv) ``` + +| Paramètre | Rôle | Conseil | +|-----------|------|---------| +| `dbdir` | Par défaut, `duckdb` stocke tout en mémoire vive et efface tout à la fermeture de la session. En spécifiant un chemin, la base +est sauvegardée sur disque et réutilisable. | Utile surtout si vous créez des tables ou des vues avec SQL ou `dplyr::compute()`. Pour un +usage `dplyr` classique, la mémoire suffit. | +| `threads` | Nombre de processeurs utilisés. Par défaut, `duckdb` utilise tous les processeurs disponibles. | Sur un serveur partagé, +limitez à 4 ou 8 _threads_. Prévoir 5 à 10 Go de mémoire par _thread_ (5 pour des agrégations, 10 pour des jointures). Au-delà de 8 +_threads_, le gain de performance est souvent marginal. | +| `memory_limit` | Quantité maximale de mémoire vive que `duckdb` peut utiliser (80 % de la mémoire disponible par défaut). | Si la mémoire +est limitée, préférez réduire le nombre de _threads_ plutôt que de baisser cette limite. | +| `temp_directory` | Dossier dans lequel `duckdb` écrit des fichiers temporaires quand la mémoire est pleine (_spill to disk_). | Utile en +dernier recours si vous manquez légèrement de mémoire. Réduire les _threads_ reste plus efficace. Ce paramètre est fixé automatiquement si +vous utilisez une base persistante. | +| `preserve_insertion_order` | Indique si `duckdb` doit conserver l'ordre de lecture/écriture des données. Conserver cet ordre consomme de la +mémoire. | Mettre à `"false"` si l'ordre n'a pas d'importance (pas de `arrange()` / `ORDER BY`), pour réduire la consommation mémoire. | + +::: -Vous pouvez ensuite requêter les objets créés dans la base SQL via `dplyr`: +::: {.callout-note collapse="true"} +#### Fixer les paramètres après l'initialisation + +Vous pouvez également changer les paramètres d'une base après son initialisation en utilisant la commande `dbExecute`. Par exemple, pour fixer le nombre de _threads_ à 4 : ```{r} -conn_ddb %>% tbl("bpe_ens_2018_view") +#| eval: false +dbExecute(conn_ddb, "SET threads = '4';") ``` +::: -Vous pouvez bien sûr lire des fichiers `Parquet`, `CSV` ou autres en utilisant les [fonctions de duckdb](https://duckdb.org/docs/data/overview) : +### Fonctions non traduites et/ou comment passer des paramètres ? {#sec-sql} + +Il arrive que `dbplyr` ne sache pas traduire une fonction `R` en SQL DuckDB. Dans ce cas, **la fonction inconnue est reprise telle quelle dans le code SQL**, ce qui provoque une erreur à l'exécution : ```{r} -DBI::dbGetQuery(conn_ddb, "SELECT * FROM read_parquet('bpe_ens_2018_dataset/**/*.parquet') LIMIT 5") +bpe_ens_2018_dataset |> + mutate(test = fonction_inexistante(DEP)) |> + show_query() ``` -::: {.callout-tip} -Le SQL de `duckdb` est très proche de celui de PostgreSQL avec [quelques évolutions très pertinentes](https://duckdb.org/docs/guides/sql_features/friendly_sql). -::: - - -#### Séparer vos traitements SQL en blocs +La solution est simple : **utiliser directement la fonction DuckDB équivalente** dans le code `R`. DuckDB dispose d'un grand nombre de fonctions optimisées ([documentation](https://duckdb.org/docs/sql/functions/overview)) qui peuvent être appelées directement depuis `R`. -Si vos requêtes deviennent trop complexes et/ou longues, vous pouvez facilement les découper en créant des vues intermédiaires que vous réutiliserez plus tard : -```{r eval=FALSE} -# Créer une vue qui correspond à la première étape du traitement -dbExecute(conn_ddb, "CREATE OR REPLACE VIEW data1_nettoye AS SELECT ... FROM read_parquet('data1.parquet')") +**Exemple** -# Créer une vue qui correspond à la deuxième étape du traitement -dbExecute(conn_ddb, "CREATE OR REPLACE VIEW data2_nettoye AS SELECT ... FROM read_parquet('data2.parquet')") +Supposons des dates au format "JJ/MM/AAAA" : -# Faire la dernière étape du traitement et récupérer les résultats dans un tibble -resultats <- dbGetQuery(conn_ddb, "SELECT * FROM data1_nettoye LEFT JOIN data2_nettoye ON data1.id = data2.id") +```{r} +dates <- tibble( + date_naissance = c("02/07/1980", "29/02/2004"), + date_deces = c("05/06/2001", "12/07/2023") +) +conn_ddb |> duckdb::duckdb_register(name = "dates_duckdb", df = dates, overwrite = TRUE) ``` -Et vous pouvez bien sûr créer des tables intermédiaires (temporaires ou non) à la place des vues (en utilisant `CREATE TABLE` pluôt que `CREATE VIEW`) pour éviter de les recalculer à chaque fois. +La fonction `R` `as.Date()` ne fonctionne pas ici : `dplyr` ne sait pas traduire l'argument `format`, et DuckDB n'accepte que le format "AAAA-MM-JJ" par défaut. -A noter, vous pouvez grouper les requêtes SQL dans un même `dbExecute` : -```{r eval=FALSE} -# Créer une vue qui correspond à la première étape du traitement -dbExecute(conn_ddb, - "CREATE OR REPLACE VIEW data1_nettoye AS SELECT ... FROM read_parquet('data1.parquet'); - CREATE OR REPLACE VIEW data2_nettoye AS SELECT ... FROM read_parquet('data2.parquet'); - SELECT * FROM data1_nettoye LEFT JOIN data2_nettoye ON data1.id = data2.id")" -) +```{r error=TRUE} +conn_ddb |> tbl("dates_duckdb") |> + mutate(date_naissance = as.Date(date_naissance, format = "%d/%m/%Y")) ``` -Ou utiliser la clause SQL `WITH` : +Il suffit d'utiliser la fonction DuckDB `strptime()` directement dans le code `R` : -```{r eval=FALSE} -# Créer une vue qui correspond à la première étape du traitement -dbExecute(conn_ddb, - "WITH data1_nettoye AS (SELECT ... FROM read_parquet('data1.parquet')), - data2_nettoye AS (SELECT ... FROM read_parquet('data2.parquet')) - SELECT * FROM data1_nettoye LEFT JOIN data2_nettoye ON data1.id = data2.id")" -) +```{r} +conn_ddb |> tbl("dates_duckdb") |> + mutate(date_naissance = strptime(date_naissance, "%d/%m/%Y")) ``` -#### Écrire des fichiers {#sec-ecrire-parquet} +::: {.callout-tip collapse="true"} +## Appliquer une même fonction sur plusieurs colonnes -Vous pouvez exporter des données vers des fichiers en utilisant [`COPY ... TO ...`](https://duckdb.org/docs/sql/statements/copy.html#copy--to) : +Cette approche fonctionne aussi avec `mutate(across())` pour appliquer la fonction à plusieurs colonnes à la fois : -```{r, message=F} -dbExecute(conn_ddb, "COPY (SELECT * FROM read_parquet('bpe_ens_2018_dataset/**/*.parquet')) - TO 'mon_dataset_parquet' (FORMAT PARQUET, PARTITION_BY (REG), OVERWRITE_OR_IGNORE 1)") +```{r} +liste_variables <- c("date_naissance", "date_deces") +conn_ddb |> tbl("dates_duckdb") |> + mutate(across(all_of(liste_variables), ~ strptime(., "%d/%m/%Y"))) ``` +::: -Si vous préférez utiliser les fonctions de `arrow`, vous pouvez créez une vue et utiliser `dbplr::tbl` avec `arrow::write_dataset` : +::: {.callout-warning collapse="true"} +## Comportement de `duckplyr` et `dbplyr` en cas de fonction inconnue -```{r, eval=FALSE} -dbExecute(conn_ddb, "CREATE OR REPLACE VIEW output AS SELECT ...") +`duckplyr` et `dbplyr` ne se comportent pas de la même façon lorsqu'une fonction n'est pas disponible dans DuckDB : -tbl(conn_ddb, "output") |> - arrow::to_arrow() |> - write_dataset("mon_dataset") -``` +- avec **`duckplyr`** : le traitement bascule silencieusement sur `dplyr` standard, ce qui implique de **charger les données en mémoire**. Sur des données volumineuses, cela peut saturer la RAM sans avertissement explicite. Activez `options(duckplyr.fallback_info = TRUE)` pour être notifié des bascules. +- avec **`dbplyr`** : la fonction inconnue est **transmise telle quelle à DuckDB** sous forme de SQL. Cela permet d'utiliser directement des fonctions natives DuckDB (comme `strptime()`), mais génère une erreur SQL si la fonction n'existe pas non plus côté DuckDB. +::: ### Optimisations Les opérations difficiles en SQL, longues, nécessitant beaucoup de mémoire, sont les fonctions dites "fenêtre": jointures, `GROUP BY` avec beaucoup de petits groupes, dédoublonnage, etc. On propose ici quelques techniques pour faire passer ces calculs difficiles. - +::: {.callout-note collapse="true"} #### Utilisation de la mémoire vive -Comme expliqué plus haut, les objets manipulés dans cette fiche sont des requêtes SQL, et ne nécessitent pas de mémoire vive. Les données déclarées par `read_parquet` sont stockées sur le disque dur, lues à la demande, et "oubliées" à la fin du calcul. On retourne le _résultat_ du calcul. +Par défaut, les objets manipulés avec `duckdb` sont de simples requêtes SQL : les données restent sur le disque et ne sont chargées en mémoire que le temps du calcul, avant d'être libérées. La mémoire utilisée correspond donc au résultat du calcul, pas aux données en entrée. -Pour les opérations compliquées, il peut être nécessaire de charger les données en mémoire pour effectuer le calcul, au risque de saturer la mémoire. Lorsque ce problème se pose, `duckdb` renvoie un message du type: +Toutefois, certaines opérations complexes (jointures volumineuses, agrégations sur de très grands fichiers) nécessitent de conserver temporairement beaucoup de données en mémoire. Lorsque la mémoire est saturée, `duckdb` renvoie une erreur de ce type : ``` Error: rapi_execute: Failed to run query @@ -663,9 +665,9 @@ Launch the database with a persistent storage back-end Or set PRAGMA temp_directory='/path/to/tmp.tmp' ``` -Pour contourner le manque de mémoire vive, on propose les quatre techniques suivantes : +**Solutions, de la plus simple à la plus avancée :** -- diminuer le nombre de _threads_ utilisés par `duckdb`, donc moins de besoins de mémoire (mais aussi moins de parallélisme): +**1. Réduire le nombre de _threads_** (recommandé en premier). Moins de _threads_ = moins de calculs en parallèle = moins de mémoire consommée. La règle est de prévoir 5 à 10 Go de mémoire par _thread_ : ```{r eval=FALSE} conn_ddb <- dbConnect(duckdb(), @@ -677,16 +679,26 @@ ou dbExecute(conn_ddb, "SET threads = '1';") ``` -- exécuter et sauvegarder les résultats au fur et à mesure. La commande `arrow::write_dataset` et la commande SQL `COPY request TO filename.parquet` savent le faire automatiquement, sans faire déborder la mémoire, pour certains calculs. -- découper le calcul et sauvegarder une base intermédiaire (cf ci-dessous). -- adosser un fichier sur le disque dur à la base de données en mémoire au moment de la création de la connexion. Cela ralentit considérablement les calculs, et ne permet pas toujours d'obtenir un résultat. + **2. Écrire les résultats au fur et à mesure.** La commande SQL `COPY ... TO` sait écrire en Parquet de façon incrémentale pour certains calculs, sans tout charger en mémoire : + ```{r eval=FALSE} -conn_ddb <- dbConnect(duckdb(), dbdir = "my-db.duckdb") +DBI::dbExecute(conn_ddb, "COPY (SELECT ...) TO 'resultats.parquet' (FORMAT PARQUET)") ``` -L'interaction entre les différentes options de `duckdb` est complexe et rendent difficile l'élaboration de recommandations claires. Nous mettrons à jour cette fiche quand des benchmarks plus poussés seront disponibles. +**3. Découper le calcul** en étapes intermédiaires sauvegardées sur disque, pour ne traiter qu'une partie des données à la fois. + +**4. Utiliser une base persistante sur disque.** En adossant `duckdb` à un fichier sur disque, il peut y écrire des fichiers temporaires quand la mémoire est pleine (_spill to disk_). Cette option ralentit les calculs et ne résout pas tous les cas : +```{r eval=FALSE} +conn_ddb <- DBI::dbConnect(duckdb::duckdb(), dbdir = "my-db.duckdb") +``` + +::: {.callout-tip} +L'interaction entre ces différentes options est complexe et les effets varient selon les données et les calculs. En pratique, **commencer par réduire le nombre de _threads_** est le levier le plus simple et le plus efficace. +::: +::: +::: {.callout-note collapse="true"} #### Sauvegarder des résultats intermédiaires Dans plusieurs cas, vous pouvez vouloir passer par des résultats intermédiaires : @@ -694,21 +706,7 @@ Dans plusieurs cas, vous pouvez vouloir passer par des résultats intermédiaire - Votre traitement est long et vous ne souhaitez pas le recalculer entièrement à chaque fois ; - Certaines requêtes sont trop compliquées pour le moteur SQL et/ou pour la traduction automatique, vous devez le découper. -Vous avez plusieurs méthodes possibles : - -- `arrow::write_dataset()` sait faire les calculs par morceaux automatiquement, et libère la mémoire au fur et à mesure. - -```{r eval=FALSE} -conn_ddb %>% calcul1() %>% - arrow::to_arrow() %>% - arrow::write_dataset("base_intermediaire") - -arrow::open_dataset("base_intermediaire") %>% - arrow::to_duckdb(conn_ddb) %>% - calcul2() -``` - -- Vous pouvez utiliser `dbplyr::compute()` pour créer une table `duckdb` stockée sur le disque (si vous avez préalablement créé une base sur disque) que vous pourrez directement utiliser par la suite dans une autre session : +Vous pouvez utiliser `dbplyr::compute()` pour créer une table `duckdb` stockée sur le disque (si vous avez préalablement créé une base sur disque) que vous pourrez directement utiliser par la suite dans une autre session : ```{r eval=FALSE} conn_ddb %>% @@ -719,8 +717,6 @@ tbl(conn_dbb, "matable") %>% calcul2() ``` -La première méthode avec `arrow` est généralement la plus rapide et la seconde avec `dbplyr::compute` sur une table nommée est la plus efficace (de loin) en terme d'occupation mémoire. - A noter que vous pouvez également utiliser `dbplyr::compute` pour créer une table temporaire `duckdb` stockée en mémoire qui disparaitra à la fin de votre session : ```{r eval=FALSE} @@ -731,26 +727,44 @@ table_temporaire <- conn_ddb %>% table_temporaire %>% calcul2() ``` +::: + +::: {.callout-note collapse="true"} +#### Partitionner les données lors de l'export de fichier + +**Qu'est-ce que le partitionnement ?** +Partitionner consiste à découper un fichier de données en plusieurs sous-fichiers selon les valeurs d'une colonne. Par exemple, partitionner par région crée un fichier par région. DuckDB peut alors lire uniquement le fichier de la région qui l'intéresse, sans parcourir toutes les données. -#### Partitionner les données +**Pourquoi le partitionnement accélère les calculs : la notion d'index** -- Pour exécuter une fonction fenêtre, il faut pouvoir localiser les données en mémoire avec un _index_. -- Les fichiers `parquet` ont un index `min-max` : les fichiers sont structurés en blocs, et on indique le minimum et maximum des valeurs du bloc dans les métadonnées. Ceci permet de sauter la lecture d'un bloc si l'on s'intéresse à des valeurs en dehors de la plage `min-max`, parce que l'on filtre les données par exemple. -- En SQL, on peut créer un index, mais il faut que les données soient en mémoire, ce qui peut s'avérer être incompatible avec de très grosses volumétries. -- Par contre, on peut partitionner les données, et le moteur SQL sait utiliser le partitionnement comme un index. +Pour exécuter efficacement certaines opérations (filtres, fonctions fenêtre comme `rank()` ou `lag()`), DuckDB a besoin d'un _index_ : un mécanisme qui lui indique rapidement où se trouvent les données qui l'intéressent, sans tout lire. + +Les fichiers Parquet disposent d'un index _min-max_ : chaque bloc de données indique dans ses métadonnées les valeurs minimale et maximale qu'il contient. DuckDB peut ainsi sauter les blocs qui ne correspondent pas à un filtre. + +Le partitionnement va plus loin : en organisant physiquement les données par valeur d'une colonne, il permet à DuckDB de lire uniquement le(s) sous-fichier(s) pertinents, sans même parcourir les autres. + +Créer un index SQL classique est une alternative, mais elle nécessite de charger les données en mémoire, ce qui est incompatible avec de très gros volumes. + +**Comment partitionner avec DuckDB ?** ```{r} -bpe_ens_2018_dataset %>% - arrow::to_arrow() %>% - arrow::write_dataset("bpe_ens_2018_dataset_parts", partitioning = "REG" ) -list.files("bpe_ens_2018_dataset_parts") # on obtient un sous-répertoire par région +dir.create("bpe_ens_2018_dataset_parts", showWarnings = FALSE) + +unlink("bpe_ens_2018_dataset_parts", recursive = TRUE) # supprime les anciens fichier avant l'écriture +DBI::dbExecute(conn_ddb, "COPY bpe_ens_2018 TO 'bpe_ens_2018_dataset_parts' (FORMAT PARQUET, PARTITION_BY (REG))") + +list.files("bpe_ens_2018_dataset_parts") # un sous-répertoire par région ``` +DuckDB crée automatiquement un sous-répertoire par valeur de `REG`, chacun contenant un fichier Parquet avec les données de cette région. -#### Exécuter les traitements par groupe _explicitement_ +::: -S'il faut absolument charger des données en mémoire, on peut découper le calcul pour ne charger qu'une partie des données. Par exemple, faire une jointure région par région au lieu de faire la jointure sur toute la base d'un coup. On peut utiliser le partitionnement pour sauvegarder les résultats partiels, et les ré-assembler ensuite. +::: {.callout-note collapse="true"} +#### Exécuter _explicitement_ les traitements par groupe + +Dans le cas où les données doivent absolument être chargées en mémoire, le calcul peut être découpé pour ne charger qu'une partie des données. Par exemple, faire une jointure région par région au lieu de faire la jointure sur toute la base d'un coup. On peut utiliser le partitionnement pour sauvegarder les résultats partiels, et les ré-assembler ensuite. ```{r eval=FALSE} groups <- bpe_ens_2018_dataset %>% @@ -762,49 +776,26 @@ groups <- bpe_ens_2018_dataset %>% f <- function(x) { bpe_ens_2018_dataset %>% filter(REG == x) %>% - calcul_long() %>% - arrow::to_arrow() %>% - arrow::write_dataset("resultat", partitioning = "REG") + calcul_long() + + DBI::dbExecute(conn_ddb, paste0( + "COPY (", dbplyr::remote_query(req), + ") TO 'resultat' (FORMAT PARQUET, PARTITION_BY (REG))" + )) } # Appliquer la fonction à chaque groupe purrr::walk(f, groups) ``` -## Comparaison avec `arrow` {#sec-arrow} - -`arrow` et `duckdb` partagent de nombreux concepts. Voici quelques différences : - -- `duckdb` comprend parfaitement SQL. Si vous savez utiliser `PROC SQL` avec SAS, vous ne serez pas dépaysés. -- Le projet `duckdb` évolue encore rapidement (même si le rythme s'est stabilisé depuis la sortie de la version 1.0.0). Il y a régulièrement des évolutions qui sont souvent des extensions ou des optimisations, et parfois la résolution de bugs. `arrow` est un projet un peu plus ancien et mature. -- Certaines fonctions standards de `R` ne sont pas traduites, mais la situation est meilleure du côté de `duckdb` que d'`arrow`. Hormis `write_dataset()` (si vous utilisez la syntaxe `dplyr`), la plupart des traitements peuvent être effectués en utilisant uniquement `duckdb`, sans passer par `arrow`. -- Les __conversions de type__: `duckdb` est plus permissif que `arrow` et fera plus facilement des [conversions automatiques](https://duckdb.org/docs/sql/data_types/typecasting.html) sans danger. -- Les __jointures de tables volumineuses__: `arrow` ne parvient pas à joindre des tables de données très volumineuses; il est préférable d'utiliser `duckdb` pour ce type d'opération. -- Les __réorganisations de données__ : les fonctions `pivot_wider` et `pivot_longer` existent nativement dans `duckdb` mais pas dans `arrow`. -- Les __fonctions fenêtre__ (_window functions_): `arrow` ne permet pas d'ajouter directement à une table des informations issues d'une agrégation par groupe de la même table. Par exemple, `arrow` ne peut pas ajouter directement à la base permanente des équipements une colonne égale au nombre total d'équipements du département. Le code fonctionne en `duckdb`. - -```{r} -# arrow ne peut pas exécuter ceci -bpe_ens_2018_dataset |> - group_by(DEP) |> - mutate(NB_EQUIP_TOTAL_DEP = sum(NB_EQUIP)) |> - select(DEP, NB_EQUIP, NB_EQUIP_TOTAL_DEP) -``` - -- les __empilements de tables__: il est facile d'empiler plusieurs `tibbles` avec `dplyr` grâce à la fonction `bind_rows()`: `bind_rows(table1, table2, table3, table4)`. En revanche, il n'existe pas à ce jour de fonction équivalente dans `arrow` ou dans `duckdb`: il faut empiler les tables deux à deux avec les fonctions `union_all()` et `union()`. La différence entre `arrow` et `duckdb` est que `duckdb` est plus souple et acceptera d'empiler des tables qui ne sont pas exactement compatibles (exemple: pas le même nombre de colonnes), tandis qu'`arrow` exige que les deux tables soient parfaitement compatibles (il faut le même nombre de colonnes avec le même nom et le même type, ce qui n'est pas toujours le cas en pratique). Dans l'exemple suivant, on empile deux tables qui n'ont pas exactement le même nombre de colonnes: - -```{r} -# Comment empiler de multiples tables -table_empilees <- bpe_ens_2018_dataset %>% - union_all(bpe_ens_2018_dataset |> select(-DEPCOM)) -``` - +::: ## Pour en savoir plus {#Ressourcesduckdb} - la documentation officielle du _moteur_ [`DuckDB`](https://duckdb.org/docs/) (en anglais) ; - la documentation du _package_ R [DuckDB](https://r.duckdb.org/) ; - la documentation du _package_ [`DBI`](https://dbi.r-dbi.org/) décrit les mécanismes de traduction `dplyr` vers SQL utilisés dans toutes les bases de données interfacées avec `R`. +- la documentation officielle du _package_ [duckplyr](https://duckplyr.tidyverse.org/) ```{r} #| echo: false From 9d0b8263d91fc941149ecac6e77f868aa4b950e0 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Wed, 17 Jun 2026 13:17:22 +0000 Subject: [PATCH 05/14] add minimal example #560 + S3 connexion part with duckdb) --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 117 +++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index f3a0abd8..b2ea6d51 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -228,6 +228,43 @@ conn_ddb %>% tbl('bpe_ens_2018_dataset/**/*.parquet') __Cette approche établit une connexion aux données contenues dans le dataset Parquet, mais elle ne charge pas les données en mémoire__ (ni dans la mémoire de `R`, ni dans celle de `DuckDB`). +#### Chargement de données provenant du stockage S3 (LS3 / SSPCloud) + +De plus en plus de statisticiens utilisent la plateforme de datascience Onyxia, dont le SSPCloud et LS3 en sont des instances. +Le chargement des données sur la base `duckdb` peut être plus complexe à réaliser, notamment car un lien doit être fait entre la base de données et le service s3. + +Pour cela, une table `secret` doit être créée dans la base de données avec tous les credentials nécessaires à la connexion au service S3, afin que `duckdb` puisse établir cette connexion : + +```{r, eval = FALSE} + +DBI::dbExecute(con, sprintf(" + CREATE SECRET my_s3_secret ( + TYPE S3, + KEY_ID '%s', + SECRET '%s', + ENDPOINT '%s', + SESSION_TOKEN '%s', + REGION 'us-east-1', + URL_STYLE 'path' + )", + Sys.getenv("AWS_ACCESS_KEY_ID"), + Sys.getenv("AWS_SECRET_ACCESS_KEY"), + Sys.getenv("AWS_S3_ENDPOINT"), + Sys.getenv("AWS_SESSION_TOKEN") +)) + +``` +Toutes ces variables sont déjà définies dans le service Rstudio / VScode ouvert, il n'y a donc pas besoin de les redéfinir. + +Une fois cette table de secret créée, il suffit de lancer la requête SQL avec `dbExecute()`, en ajoutant le chemin vers les données stockées dans le S3 : + +```{r, eval=FALSE} +bpe_ens_2018_s3 <- DBI::dbGetQuery(con, glue::glue( + " SELECT * + FROM read_parquet('s3://{BUCKET}/XXX.parquet') + ") + ) +``` ### Manipulation des données avec la syntaxe `dplyr` @@ -435,6 +472,86 @@ req <- duckplyr::as_duckdb_tibble(source_data) |> Même si le package `arrow` peut sembler plus simple à utiliser que SQL pour certaines manipulations `dplyr`, il est préférable de rester avec `duckdb` pour limiter les dépendances et garder une approche cohérente. ::: +### Exemple minimal d'utilisation de duckdb dans un projet + +```{r, eval=FALSE} +library(duckdb) +library(dplyr) + +con <- DBI::dbConnect(drv = duckdb::duckdb()) + +# Chargement des données + +## 1 - Directement dans la session R, puis dans la base duckdb +bpe_ens_2018 <- doremifasolData::bpe_ens_2018 |> as_tibble() +con %>% duckdb::duckdb_register( + name = "bpe_ens_2018_duckdb", + df = bpe_ens_2018) + +## 2 - Depuis un fichier stocké sur le disque dur (ou dans un service) +bpe_ens_2018_dataset <- conn_ddb %>% tbl("read_parquet('XXX.parquet')") + +## 3 - Depuis un fichier stocké sur le S3 +# création de la table des secrets +DBI::dbExecute(con, sprintf(" + CREATE SECRET my_s3_secret ( + TYPE S3, + KEY_ID '%s', + SECRET '%s', + ENDPOINT '%s', + SESSION_TOKEN '%s', + REGION 'us-east-1', + URL_STYLE 'path' + )", + Sys.getenv("AWS_ACCESS_KEY_ID"), + Sys.getenv("AWS_SECRET_ACCESS_KEY"), + Sys.getenv("AWS_S3_ENDPOINT"), + Sys.getenv("AWS_SESSION_TOKEN") +)) + +bpe_ens_2018_s3 <- DBI::dbGetQuery(con, glue::glue( + " SELECT * + FROM read_parquet('s3://{BUCKET}/XXX.parquet') + ") + ) + +# Manipulation de données (table duckdb) + +## 1 - avec SQL + +### a - Créer une View +DBI::dbExecute(conn_ddb, " + CREATE VIEW bpe_ens_2018_view AS + SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT + FROM bpe_ens_2018_duckdb + GROUP BY REG") + +### b - Créer une table duckdb +DBI::dbExecute(conn_ddb, " + CREATE TABLE bpe_ens_2018_table AS + SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT + FROM bpe_ens_2018_duckdb + GROUP BY REG") # Utilise de la mémoire + +## 2 - avec dplyr +bpe_ens_2018_dataset |> + group_by(REG) |> + summarise( + NB_EQUIP_TOT = sum(NB_EQUIP) + ) |> + collect() # permet de passer une table duckdb en tibble sur la session R + +# Export dans un fichier parquet +dir.create("temp_dataset", showWarnings = FALSE) # Création d'un répertoire pour l'export du fichier parquet + +duckdb::duckdb_register(con, "bpe_ens_2018_temp", bpe_ens_2018) # ajouter l'objet R dans la base duckDB +DBI::dbExecute(con, "COPY bpe_ens_2018_temp TO 'temp_dataset/bpe_ens_2018.parquet' (FORMAT PARQUET)") + + +DBI::dbDisconnect(con, shutdown = TRUE) + +``` + ## Bien utiliser `duckdb` avec l'évaluation différée {#sec-lazy} ### Principe : construire la requête avant de l'exécuter From 73b8a111091c3b1968c7318efc3f044b3b58c846 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Thu, 18 Jun 2026 08:55:11 +0100 Subject: [PATCH 06/14] Update 03_Fiches_thematiques/Fiche_duckdb.qmd Add more details on SSPCloud and LS3 Co-authored-by: Lino Galiana --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index d692670a..3dc49e02 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -234,7 +234,7 @@ conn_ddb %>% tbl('bpe_ens_2018_dataset/**/*.parquet') #### Chargement de données provenant du stockage S3 (LS3 / SSPCloud) -De plus en plus de statisticiens utilisent la plateforme de datascience Onyxia, dont le SSPCloud et LS3 en sont des instances. +De plus en plus de statisticiens utilisent la plateforme de datascience Onyxia, dont le [SSPCloud](https://datalab.sspcloud.fr/home) (instance ouverte aux agents publiques sur [datalab.sspcloud.fr/](https://datalab.sspcloud.fr/home)) et LS3 (plateforme interne à l'Insee) en sont des instances. Le chargement des données sur la base `duckdb` peut être plus complexe à réaliser, notamment car un lien doit être fait entre la base de données et le service s3. Pour cela, une table `secret` doit être créée dans la base de données avec tous les credentials nécessaires à la connexion au service S3, afin que `duckdb` puisse établir cette connexion : From fb69a0b55315e66670da3441e8aee7d94a0042a5 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Thu, 18 Jun 2026 18:54:51 +0000 Subject: [PATCH 07/14] =?UTF-8?q?Ajout=20pr=C3=A9cisions=20sur=20utilisati?= =?UTF-8?q?on=20VIEW=20/=20TABLES=20avec=20duckdb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 6 ++++-- resources/img/arbre_decision_duckdb.png | Bin 0 -> 132320 bytes 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 resources/img/arbre_decision_duckdb.png diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index 3dc49e02..1b28487a 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -355,7 +355,9 @@ Avec DuckDB, on peut matérialiser un résultat à l'aide de requêtes SQL de de - **Une table** : les données sont calculées et stockées physiquement (en mémoire ou sur disque). C'est utile si le calcul est long et que vous souhaitez réutiliser le résultat plusieurs fois sans le recalculer. - **Une vue (view)** : aucune donnée n'est stockée. Une vue n'est qu'un raccourci vers une requête SQL qui sera ré-exécutée à chaque utilisation. Elle ne consomme pas de mémoire. -En pratique, préférez toujours une vue si vous n'avez pas besoin de conserver le résultat durablement. +En pratique, préférez toujours une vue si vous n'avez pas besoin de conserver le résultat durablement. Ce schéma résume l'utilisation de `TABLE` ou `VIEW` selon le contexte du traitement : + +![](../resources/img/arbre_decision_duckdb.png) Pour créer une table ou une vue, on utilise `DBI::dbExecute()` qui envoie une instruction SQL à DuckDB : @@ -367,7 +369,7 @@ DBI::dbExecute(conn_ddb, " FROM bpe_ens_2018_duckdb GROUP BY REG") # Utilise de la mémoire -# Créer une vue dans la base de données DuckDB (Recommandé) +# Créer une vue dans la base de données DuckDB DBI::dbExecute(conn_ddb, " CREATE VIEW bpe_ens_2018_view AS SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT diff --git a/resources/img/arbre_decision_duckdb.png b/resources/img/arbre_decision_duckdb.png new file mode 100644 index 0000000000000000000000000000000000000000..337e61a82227290dd06ab3b96a9198efc7207805 GIT binary patch literal 132320 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 z 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%0A|3Wyv~vb6 zNmN&-pam_g5T>09y&Us%EMF!I_1|rT+&u@~v?J=_t6SNCj0=uI7Job|(%$G|X?bKA z6}b)cO*X%e)ODbCeu0y_!wcD=*5!>s(Te$)iN(__^j%bA>`KUP*FzY>GR7xPMEl{=d zETh4G>8r+(yflWq{iCBT8sS)(wMPFog^<{^;~CX=U%sC4P72wsGG|68f9E#srqB1m zRS!x_;7Z&979d?aomy!I-rfi{h@#TcwtZt{ilBUk8SW# z`o8il4P_E*K9vrNP;p_K0NKtD6QW^skozQ)Y`}nu03_wd+V*le{HAtfjOWv2Qd0(mXg6C=oVkH8}WN* z52cYCp~;=_oqf6en&G7)kWW%s(73R?w)Q2Xd(MpjWrW5Vq_$q*K}_V~7j&DbhuWG$ zq{q9I`)0Fj*A}yIz9s3+F5pyZwqw~;De{z zC4;fICk)u8l73>tX7;IIihx}K$LSFf(2cf<0sfL9;O#39yKZiV-OAYmNEyif z8g4sL8eI1;Q6v2scEq?9r_?{*l9=xA$UfKua8Cor=x>-v8mjCdLxC^VR-uud(%3x6A`;&DzQz%Cx z8<6OPc8C_sfGhiLu^6ql zy7O0=P!MQBf!a+ioWgL#{AIt%JJ?ph?tAPlGPwvMMH{gPzGy`YJGD?>2qW)(%KgRnuZwK5SGb;F@Av*%_g7Y!nGJ*WcTI znWaf{zRD~RGFl(PN9sJRAHk6`zeBCE7W?h?m%x(s(m!3WW7h2v_2aZWoOp(T=R~&p zP!mD2+PBu5bGq(CMd-}S+$?Og_ZhXq5;s)D?u z!4?%4HYurb7MdPuV;~%|b!E@zMrrcN#*n|8aPt0zq*sE!{K!V^tvb36HOC$0%VUL! z8OQD|hB&j&`Q445Acl<6r0^SHUpA4xKF)tH)*TbA=G+)nsL*Kp*VYFah->X5;{?$4 z_Eaz{e;@4CbkC4|ajRd{vldkcvF-Zv$RQCLIw(vl9<@!jeA@V!EP( z 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

&yH$b`g`v8j^S5{>~w<$i@TS93FEL5 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 literal 0 HcmV?d00001 From 45dd113a8cf80e290dde780ce17d893ea788887e Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Thu, 18 Jun 2026 19:18:52 +0000 Subject: [PATCH 08/14] =?UTF-8?q?R=C3=A9=C3=A9criture=20pr=C3=A9sentation?= =?UTF-8?q?=20vue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index 1b28487a..bac703e3 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -353,7 +353,7 @@ Cette requête est envoyée au serveur SQL et exécutée de façon différente e Avec DuckDB, on peut matérialiser un résultat à l'aide de requêtes SQL de deux façons : - **Une table** : les données sont calculées et stockées physiquement (en mémoire ou sur disque). C'est utile si le calcul est long et que vous souhaitez réutiliser le résultat plusieurs fois sans le recalculer. -- **Une vue (view)** : aucune donnée n'est stockée. Une vue n'est qu'un raccourci vers une requête SQL qui sera ré-exécutée à chaque utilisation. Elle ne consomme pas de mémoire. +- **Une vue (view)** : Une vue sauvegarde une requête SQL sous un nom, sans en stocker le résultat, contrairement à une table. La requête est réexécutée à chaque appel, ce qui permet de nommer et réutiliser une requête complexe sans consommer de mémoire supplémentaire. En revanche, elle peut limiter les optimisations que DuckDB applique automatiquement, ce qui, sur de grandes bases de données ou en cas d'appels fréquents, peut dégrader les performances. Il convient donc de trouver un équilibre entre lisibilité et performance. En pratique, préférez toujours une vue si vous n'avez pas besoin de conserver le résultat durablement. Ce schéma résume l'utilisation de `TABLE` ou `VIEW` selon le contexte du traitement : From 7cd513efea28d555e5c11e80a1d7ce2e19fc5e85 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Thu, 18 Jun 2026 20:24:43 +0000 Subject: [PATCH 09/14] Ajout fiche intro sur le choix du paradigme #583 --- .../Fiche_choisir_son_paradigme.qmd | 29 ++++++++++++++++++ resources/img/choix_paradigme.png | Bin 0 -> 133642 bytes 2 files changed, 29 insertions(+) create mode 100644 03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd create mode 100644 resources/img/choix_paradigme.png diff --git a/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd b/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd new file mode 100644 index 00000000..d75c4130 --- /dev/null +++ b/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd @@ -0,0 +1,29 @@ +# Quel paradigme choisir pour la manipulation de données + +L'utilisateur souhaite choisir un éco-système pour la manipulation de données dans `R`. + +## Pourquoi choisir un paradigme pour manipuler des données ? + +`R base`, `tidyverse`, `data.table`, `duckdb`, `arrow`... Il existe presque autant d'outils pour la manipulation de données que de statisticiens, ce qui peut être déroutant pour un utilisateur novice. + +L'utilisation de `R base` (toutes les fonctions natives de `R`) bien que stable par définition, est vite limité dans la manipulation de tables : peu de cas d'utilisations possibles, code difficilement lisible sur des traitements complexes, fonctions non optimisées pour des données volumineuses... + +Au final, choisir son paradigme suit des règles très simples, axées notamment sur la volumétrie des données et le niveau des utilisateurs. + +Le schéma suivant présente le paradigme à utiliser selon la taille des tables à manipuler : + +![](../resources/img/choix_paradigme.png) + +Ce qu'il faut retenir : + +* Pour des tables de données de **taille petite et moyenne** (**inférieure à 1 Go ou moins d'un million d'observations**), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui font l'objet d'une fiche [Manipuler des données avec le `tidyverse`](#tidyverse) ; + +* Pour des tables de données de **grande taille** (**plus de 1 Go en CSV, plus de 200 Mo en Parquet, ou plus d'un million d'observations**), il est recommandé d'utiliser le *package* `duckdb` (voir la fiche [Manipuler des données avec `duckdb`](#duckdb)). L'utilisation des *packages* `data.table`, qui fait l'objet de la fiche [Manipuler des données avec `data.table`](#datatable), et `arrow`, qui fait l'objet de la fiche [Manipuler des données avec `arrow`](#arrow), n'est plus recommandée. + +* Si les données sont **très volumineuses** (**plus de 5 Go en CSV, plus de 1 Go en Parquet ou plus de 5 millions d’observations**), il est recommandé de manipuler les données avec `duckdb` plutôt qu’avec le `tidyverse`. Il peut arriver que le volume de données soit tellement important qu’il ne soit pas possible de les traiter avec `duckdb`; il faut s’orienter vers des infrastructures big data permettant le calcul distribué et utiliser des logiciels adaptés (Spark par exemple). + +::: {.callout-important} + +Il est essentiel de travailler avec la dernière version d'`arrow`, de `duckdb` et de `R` car les packages `arrow` et `duckdb` sont en cours de développement. Par ailleurs, les recommandations d’utilitR peuvent évoluer en fonction du développement de ces packages. + +::: \ No newline at end of file diff --git a/resources/img/choix_paradigme.png b/resources/img/choix_paradigme.png new file mode 100644 index 0000000000000000000000000000000000000000..7f953ea8dcab4901abe907865f803760a5decff6 GIT binary patch literal 133642 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 literal 0 HcmV?d00001 From d129c89f7fc1b8f894bd7fddd0f752fdea302145 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Thu, 18 Jun 2026 20:26:15 +0000 Subject: [PATCH 10/14] MAJ _quarto pour changer dispo chapters choix paradigme --- _quarto.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_quarto.yml b/_quarto.yml index 211b317f..ee9a1163 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -82,10 +82,11 @@ book: - 03_Fiches_thematiques/Fiche_connexion_bdd.qmd - part: "Choisir son paradigme d'analyse des données avec R" chapters: + - 03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd - 03_Fiches_thematiques/Fiche_tidyverse.qmd + - 03_Fiches_thematiques/Fiche_duckdb.qmd - 03_Fiches_thematiques/Fiche_datatable.qmd - 03_Fiches_thematiques/Fiche_arrow.qmd - - 03_Fiches_thematiques/Fiche_duckdb.qmd - part: "Manipuler des données avec R" chapters: - 03_Fiches_thematiques/Fiche_joindre_donnees.qmd From 3c6862da958cd58e82c843f98e14b2b485266d3b Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Thu, 18 Jun 2026 20:30:28 +0000 Subject: [PATCH 11/14] Fix _quarto --- _quarto.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_quarto.yml b/_quarto.yml index 40199b75..c5b2b861 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -74,14 +74,16 @@ website: href: 03_Fiches_thematiques/Fiche_connexion_bdd.qmd - text: "Manipuler des données" menu: + - text: "Choisir son paradigme pour la manipulation de données" + href: 03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd - text: "Manipuler avec le tidyverse" href: 03_Fiches_thematiques/Fiche_tidyverse.qmd + - text: "Manipuler avec duckdb" + href: 03_Fiches_thematiques/Fiche_duckdb.qmd - text: "Manipuler avec data.table" href: 03_Fiches_thematiques/Fiche_datatable.qmd - text: "Manipuler avec arrow" href: 03_Fiches_thematiques/Fiche_arrow.qmd - - text: "Manipuler avec duckdb" - href: 03_Fiches_thematiques/Fiche_duckdb.qmd - text: "Joindre des tables de données" href: 03_Fiches_thematiques/Fiche_joindre_donnees.qmd - text: "Manipuler des données textuelles" From f4e3d637aa8e7b94cfae47faeae8166abd439824 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Fri, 19 Jun 2026 07:42:20 +0000 Subject: [PATCH 12/14] typo --- 03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd b/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd index d75c4130..4b739aed 100644 --- a/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd +++ b/03_Fiches_thematiques/Fiche_choisir_son_paradigme.qmd @@ -4,7 +4,7 @@ L'utilisateur souhaite choisir un éco-système pour la manipulation de données ## Pourquoi choisir un paradigme pour manipuler des données ? -`R base`, `tidyverse`, `data.table`, `duckdb`, `arrow`... Il existe presque autant d'outils pour la manipulation de données que de statisticiens, ce qui peut être déroutant pour un utilisateur novice. +`R base`, `tidyverse`, `data.table`, `duckdb`, `arrow`... La multiplication des outils de manipulation de données en R peut être déroutante, en particulier pour les utilisateurs débutants. L'utilisation de `R base` (toutes les fonctions natives de `R`) bien que stable par définition, est vite limité dans la manipulation de tables : peu de cas d'utilisations possibles, code difficilement lisible sur des traitements complexes, fonctions non optimisées pour des données volumineuses... From 23dde5398d59b3d8584673ea0fc6f24cebe3e718 Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Fri, 19 Jun 2026 08:00:29 +0000 Subject: [PATCH 13/14] Fix URL s3 import --- 03_Fiches_thematiques/Fiche_duckdb.qmd | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/03_Fiches_thematiques/Fiche_duckdb.qmd b/03_Fiches_thematiques/Fiche_duckdb.qmd index bac703e3..0bb94070 100644 --- a/03_Fiches_thematiques/Fiche_duckdb.qmd +++ b/03_Fiches_thematiques/Fiche_duckdb.qmd @@ -265,7 +265,7 @@ Une fois cette table de secret créée, il suffit de lancer la requête SQL avec ```{r, eval=FALSE} bpe_ens_2018_s3 <- DBI::dbGetQuery(con, glue::glue( " SELECT * - FROM read_parquet('s3://{BUCKET}/XXX.parquet') + FROM read_parquet('https://minio.lab.sspcloud.fr/projet-formation/diffusion/utilitR/doremifasoldata/bpe_ens_2018.parquet') ") ) ``` @@ -445,9 +445,6 @@ dbExecute(conn_ddb, ) ``` -::: - - ### Écriture au format Parquet {#sec-ecrire-parquet} Pour écrire une table (ou le résultat de n'importe quelle requête) sur le disque au format Parquet avec `duckdb`, il faut utiliser l'instruction SQL `COPY ... TO ... (FORMAT PARQUET)` @@ -493,13 +490,21 @@ con <- DBI::dbConnect(drv = duckdb::duckdb()) # Chargement des données ## 1 - Directement dans la session R, puis dans la base duckdb -bpe_ens_2018 <- doremifasolData::bpe_ens_2018 |> as_tibble() +bpe_ens_2018 <- duckdb::sql_query(" + INSTALL httpfs; + LOAD httpfs; + SELECT * FROM 'https://minio.lab.sspcloud.fr/projet-formation/diffusion/utilitR/doremifasoldata/bpe_ens_2018.parquet' +") |> as_tibble() + con %>% duckdb::duckdb_register( name = "bpe_ens_2018_duckdb", df = bpe_ens_2018) +# Cette ligne permet l'export de la table afin de tester la deuxième méthode d'import +DBI::dbExecute(con, "COPY bpe_ens_2018_duckdb TO 'bpe_ens_2018.parquet' (FORMAT PARQUET)") + ## 2 - Depuis un fichier stocké sur le disque dur (ou dans un service) -bpe_ens_2018_dataset <- conn_ddb %>% tbl("read_parquet('XXX.parquet')") +bpe_ens_2018_dataset <- con %>% tbl("read_parquet('bpe_ens_2018.parquet')") ## 3 - Depuis un fichier stocké sur le S3 # création de la table des secrets @@ -520,8 +525,10 @@ DBI::dbExecute(con, sprintf(" )) bpe_ens_2018_s3 <- DBI::dbGetQuery(con, glue::glue( - " SELECT * - FROM read_parquet('s3://{BUCKET}/XXX.parquet') + " INSTALL httpfs; + LOAD httpfs; + SELECT * + FROM read_parquet('https://minio.lab.sspcloud.fr/projet-formation/diffusion/utilitR/doremifasoldata/bpe_ens_2018.parquet') ") ) @@ -530,14 +537,14 @@ bpe_ens_2018_s3 <- DBI::dbGetQuery(con, glue::glue( ## 1 - avec SQL ### a - Créer une View -DBI::dbExecute(conn_ddb, " +DBI::dbExecute(con, " CREATE VIEW bpe_ens_2018_view AS SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT FROM bpe_ens_2018_duckdb GROUP BY REG") ### b - Créer une table duckdb -DBI::dbExecute(conn_ddb, " +DBI::dbExecute(con, " CREATE TABLE bpe_ens_2018_table AS SELECT REG, SUM(NB_EQUIP) AS NB_EQUIP_TOT FROM bpe_ens_2018_duckdb From e5b2271ac19a93acf4763af3222ba272aa89388a Mon Sep 17 00:00:00 2001 From: Lauragaimard Date: Fri, 19 Jun 2026 08:11:28 +0000 Subject: [PATCH 14/14] =?UTF-8?q?adaptation=20fiches=20manipulation=20donn?= =?UTF-8?q?=C3=A9es=20avec=20le=20pr=C3=A9ambule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03_Fiches_thematiques/Fiche_arrow.qmd | 16 +++------------- 03_Fiches_thematiques/Fiche_datatable.qmd | 8 -------- 03_Fiches_thematiques/Fiche_tidyverse.qmd | 8 -------- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/03_Fiches_thematiques/Fiche_arrow.qmd b/03_Fiches_thematiques/Fiche_arrow.qmd index 6cc1fb96..550aeb23 100644 --- a/03_Fiches_thematiques/Fiche_arrow.qmd +++ b/03_Fiches_thematiques/Fiche_arrow.qmd @@ -4,19 +4,10 @@ L'utilisateur souhaite manipuler des données structurées sous forme de `data.frame` par le biais de l'écosystème `Arrow` (sélectionner des variables, sélectionner des observations, créer des variables, joindre des tables). -::: {.callout-important} -## Tâches concernées et recommandations - -- Pour des tables de données de taille petite et moyenne (inférieure à 1 Go ou moins d'un million d'observations), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui sont présentés dans la fiche [Manipuler des données avec le `tidyverse`](#tidyverse); - -- Pour des tables de données de grande taille (plus de 1 Go en CSV, plus de 200 Mo en Parquet, ou plus d'un million d'observations), il est recommandé d'utiliser soit les *packages* `arrow` (qui fait l'objet de la présente fiche) et `#duckdb` (voir la fiche [Manipuler des données avec `duckdb`](#duckdb)), soit le *package* `data.table` qui fait l'objet de la fiche [Manipuler des données avec `data.table`](#datatable). - -- Il est essentiel de travailler avec la dernière version d'`arrow`, de `duckdb` et de `R` car les *packages* `arrow` et `duckdb` sont en cours de développement. Par ailleurs, les recommandations d'`utilitR` peuvent évoluer en fonction du développement de ces _packages_. - - -- Si les données traitées sont très volumineuses (plus de 5 Go en CSV, plus de 1 Go en Parquet ou plus de 5 millions d'observations), il est essentiel de manipuler uniquement des objets `Arrow Table`, plutôt que des `tibbles`. Cela implique notamment d'utiliser la fonction `compute()` plutôt que `collect()` dans les traitements intermédiaires. +::: {.callout-tip} +## Astuce : Utiliser un exemple de script pour se familiariser avec arrow -- Pour les personnes qui découvrent `arrow`, il est recommandé de partir de l'exemple de script de la @sec-template-arrow pour se familiariser avec l'usage `d'arrow`. +Pour les personnes qui découvrent `arrow`, il est recommandé de partir de l'exemple de script de la @sec-template-arrow pour se familiariser avec l'usage `d'arrow`. ::: @@ -25,7 +16,6 @@ L'utilisateur souhaite manipuler des données structurées sous forme de `data.f Apprendre à utiliser `arrow` n'est pas difficile, car la syntaxe utilisée est quasiment identique à celle du `tidyverse`. Toutefois, une bonne compréhension du fonctionnement de `R` et de `arrow` est nécessaire pour bien utiliser `arrow` sur des données volumineuses. Voici quelques conseils pour bien démarrer: - Il est indispensable de lire les fiches [Importer des fichiers Parquet](#importparquet) et [Manipuler des données avec le `tidyverse`](#tidyverse) avant de lire la présente fiche. -- Il est complètement normal de rencontrer des erreurs difficiles à comprendre lorsqu'on commence à utiliser `arrow`, il ne faut donc pas se décourager. - Il ne faut pas hésiter à demander de l'aide à des collègues, ou à poser des questions sur les salons Tchap adaptés (le salon Langage `R` par exemple). ::: diff --git a/03_Fiches_thematiques/Fiche_datatable.qmd b/03_Fiches_thematiques/Fiche_datatable.qmd index cc7e65a6..c22bee93 100644 --- a/03_Fiches_thematiques/Fiche_datatable.qmd +++ b/03_Fiches_thematiques/Fiche_datatable.qmd @@ -4,14 +4,6 @@ L'utilisateur souhaite manipuler des données structurées sous forme de `data.frame` (sélectionner des variables, sélectionner des observations, créer des variables, joindre des tables). -::: {.callout-important} -## Tâche concernée et recommandation - -* Pour des tables de données de taille petite et moyenne (inférieure à 1 Go ou moins d'un million d'observations), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui sont présentés dans la fiche [Manipuler des données avec le `tidyverse`](#tidyverse); -* Pour des tables de données de grande taille (plus de 1 Go ou plus d'un million d'observations), il est recommandé d'utiliser soit le _package_ `data.table` qui fait l'objet de la présente fiche, soit les _packages_ `arrow` et `duckdb` présentés dans les fiches [Manipuler des données avec `arrow`](#arrow) et [Manipuler des données avec `duckdb`](#duckdb). -::: - - ## Présentation de `data.table` Ne pas oublier de charger le *package* avec `library(data.table)`. diff --git a/03_Fiches_thematiques/Fiche_tidyverse.qmd b/03_Fiches_thematiques/Fiche_tidyverse.qmd index 4f3f1c7a..03e1381d 100644 --- a/03_Fiches_thematiques/Fiche_tidyverse.qmd +++ b/03_Fiches_thematiques/Fiche_tidyverse.qmd @@ -5,14 +5,6 @@ L'utilisateur souhaite manipuler des données structurées sous forme de `data.frame` (sélectionner des variables, sélectionner des observations, créer des variables, joindre des tables, résumer l'information). -::: {.callout-important} -## Tâche concernée et recommandation - -* Pour des tables de données de taille petite et moyenne (inférieure à 1 Go ou moins d'un million d'observations), il est recommandé d'utiliser les *packages* `tibble`, `dplyr` et `tidyr` qui font l'objet de la présente fiche ; -* Pour des tables de données de grande taille (plus de 1 Go ou plus d'un million d'observations), il est recommandé d'utiliser soit le _package_ `data.table` présenté dans la fiche [Manipuler des données avec `data.table`](#datatable), soit les _packages_ `arrow` et `duckdb` présentés dans les fiches [Manipuler des données avec `arrow`](#arrow) et [Manipuler des données avec `duckdb`](#duckdb). -::: - - ## Présentation des _packages_ `dplyr`, `tidyr` et `tibble` ### Introduction