C'est de la data et mon expeRtise afin d'en tirer le maximum

Exportations multiples en fichiers csv ou feuilles Excel

Dans ce court tutoriel, je vais vous montrer comment “découper” votre jeu de données selon les modalités d’une variable catégorielle (une espèce, un pays etc..), pour ensuite exporter ces données en de multiples fichiers csv, ou en multiples feuilles d’un même classeur Excel.

Table des matières

Data

Pour illustrer cet exemple, je vais employer les données world-records.csv, du projet Tidytuesday (https://github.com/rfordatascience/tidytuesday).

Pour celles et ceux qui ne connaissent pas TidyTuesday, c’est un projet initié par Thomas Mock qui consiste, chaque semaine (le mardi), à mettre à disposition un jeu de données, au format tidy, pour permettre à tous ceux qui le souhaitent de réaliser une data visualisation et une analyse de ce jeu de données, et éventuellement de partager son travail.

Les données world-records.csv sont relatives aux records du monde sur le jeu vidéo Mario Kart World, sur Nintendo 64.

Pour les télécharger rapidement, nous pouvons employer la fonction read_csv() du package readr (qui appartient au super package tidyverse) :

install.packages("tidyverse")
library(tidyverse)

records <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-05-25/records.csv') 

Ces données contiennent une variable track qui correspond aux 16 circuits du jeu :

records$track <-as.factor(records$track) 
levels(records$track)
##  [1] "Banshee Boardwalk"     "Bowser's Castle"       "Choco Mountain"       
##  [4] "D.K.'s Jungle Parkway" "Frappe Snowland"       "Kalimari Desert"      
##  [7] "Koopa Troopa Beach"    "Luigi Raceway"         "Mario Raceway"        
## [10] "Moo Moo Farm"          "Rainbow Road"          "Royal Raceway"        
## [13] "Sherbet Land"          "Toad's Turnpike"       "Wario Stadium"        
## [16] "Yoshi Valley" 

C’est selon cette variable que nous allons découper le jeu de données, pour créer, dans un premier temps, 16 fichiers csv (un par circuit), et les exporter automatiquement dans le dossier data du projet R.

Vous trouverez plus d’informations concernant la création de projets R dans mon article “7 étapes pour organiser son travail sous R” .

Dans un second temps, nous exporterons les données de chaque circuit dans un seul et même classeur Excel, contenant une feuille par circuit.

Exportation multiples en fichiers csv

Prérequis

Nous allons réaliser les exportations multiples dans un dossier nommé data que nous allons placer à la racine du projet R. Pour créer ce dossier data, vous pouvez employer l’outil de R Studio :

créer un dossier data

Ou employer directement la commande suivante :

dir.create("data") 

Pour réaliser ces exportations multiples en fichiers csv, nous allons employer plusieurs fonctions du package purrr qui appartient au super package tidyverse. Il est donc nécessaire d’installer et d’ouvrir ce package :

#install.package("tidyverse")
library(tidyverse) 

Principe

Pour réaliser ces exportations multiple en .csv nous allons :

  1. grouper les données par circuit
  2. créer un data frame nesté avec ces données en employant la fonction nest() du package purrr (contenu dans tidyverse).
  3. réaliser les exportations pour chaque ligne de ces données nestées, grâce aux fonctions pwalk(),du package purrr, et write_csv2() du package readr.

 

Voici les lignes de commandes qui permettent de faire cette exportation en multiples fichiers csv :

records %>% 
    group_by(track) %>% 
    nest() %>% 
    pwalk(~write_csv2(x = .y, file = paste0("data/",.x, ".csv") )) 

Si tout s’est bien déroulé, vous devriez voir apparaître vos 16 fichiers csv dans le dossier data :

Création des multiples fichiers csv

Remarque : je me suis largement inspiré de cette page pour créer le code: https://community.rstudio.com/t/map-write-csv/33292/2

Explications

La fonction nest()

La fonction nest() permet de créer un data frame nesté. Il s’agit d’un data frame contenant deux colonnes :

  • track qui contient le nom du circuit,
  • data qui contenant les données de ce circuit, sous la forme d’un data frame.

 

Vous pourrez le visualiser en utilisant les commandes suivantes:

tracks_nest <- records %>% 
    group_by(track) %>% 
    nest()
View(tracks_nest) 

La fonction pwalk()

Les exportations sont des effets “immatériels” (ou side-effect) car aucun objet n’est retourné par la fonction (il n’y a pas de création d’objet dans R). On parle alors de side effect. Ces side effects sont générés par la fonction walk() du package purrr (alors que la génération d’output se fait avec une fonction map()).

La lettre p devant walk veut dire “parallèle”. D’après ce que j’ai compris (n’hésitez pas à me corriger si besoin) cela correspond au fait que la fonction réalise une itération sur chaque élément de .x et de .y parallèlement (le ième élément de x correspondant au ième élément de y…) (voir juste en dessous pour l’explication de ce que sont .x et .y).  Si seulement .x était utilisé, alors on emploierait la fonction walk() tout court.

Les élements .x et .y

Là encore, d’après ce que j’ai compris, dans la commande pwalk(~write_csv(x = .y, path = paste0("data/",.x, ".csv") )) :

  • l’élément .y correspond à la seconde colonne du data frame nesté, c’est-à-dire la colonne data qui contient les données. Cela permet d’indiquer que ce que l’on souhaite exporter se trouve dans cette seconde colonne.
  • l’élément .x correspond à la première colonne de ce data frame nesté. La fonction paste0("data/",.x, ".csv") permet de créer automatiquement le nom du fichier csv, en utilisant ce qui est dans la colonne .x, c’est-à-dire le nom du circuit.

Exportations multiples en feuilles d'un classeur Excel

Principe

La procédure est plus simple. Il s’agit de :

  1. découper le data.frame par circuit et de placer les multiples data frame générés, dans une liste, en employant la fonction split()
  2. d’employer la fonction write_xlsx() du package writexl pour exporter chaque élément de la liste (chaque data frame correspondant à un circuit) dans une feuille Excel d’un même classeur

Voici les lignes de commande :

library(writexl)
records %>% 
    split(.$track) %>% 
    writexl::write_xlsx(path = "data/mario_kart.xlsx") 

Explication

La fonction write_xlsx() prend en entrée la liste des data frame (grâce au pipe %>%) et créé automatiquement des feuilles avec le nom des éléments de la liste.

Dit autrement, la liste contient 16 éléments, qui sont les 16 data frame. Ces 16 éléments ont des noms, qui ont été générés automatiquement lors du découpage avec la fonction split(). Ces noms sont ceux des circuits.

Pour mieux comprendre, ce passage en format list , et le nom des éléments, vous pouvez employer ces commandes :

records_ls <- records %>% 
    split(.$track)
names(records_ls)
##  [1] "Banshee Boardwalk"     "Bowser's Castle"       "Choco Mountain"       
##  [4] "D.K.'s Jungle Parkway" "Frappe Snowland"       "Kalimari Desert"      
##  [7] "Koopa Troopa Beach"    "Luigi Raceway"         "Mario Raceway"        
## [10] "Moo Moo Farm"          "Rainbow Road"          "Royal Raceway"        
## [13] "Sherbet Land"          "Toad's Turnpike"       "Wario Stadium"        
## [16] "Yoshi Valley" 

Au final, vous deviez obtenir le classeur suivant :

Exportation vers de multiples feuilles Excel

Remarque : cette solution a été proposée par Martin Chan

Pour aller plus loin

Vous trouverez une très bonne introduction (en français) au package purrr sur le site de Lise Vaudor.

Vous trouverez encore des liens vers des tutoriels dans mon article  “Liste de ressources pour le package purrr”. 

Conclusion

Le sujet de cet article m’a été soufflé par une lectrice du blog (et aussi stagiaire d’une de mes formations), qui avait ce besoin d’exporter vers de multiples fichiers.

J’espère que ce court tutoriel rendra également service à un grand nombre d’entre vous . Je pense que c’est une bonne chose d’avoir ces deux petits bouts de code dans sa boite à outils !

Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir ce blog en faisant un don sur sa page Tipeee 🙏

Poursuivez votre lecture

4 réponses

  1. Bonjour Claire,

    ce procédé très utile que vous rappelez m’a fait repenser aussi à la fonction group_walk, qui permet d’éviter un nest() et donc de simplifier un peu l’écriture :

    records %>%
    group_by(track) %>%
    group_walk(~write_csv2(.x , file = paste0(“data/”, .y$track, “.csv”) ))

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bonjour !

vous venez souvent ?

Identifiez-vous pour avoir accès à toutes les fontionnalités !

Aide mémoire off'R ;)

Enregistrez vous pour recevoir gratuitement mes fiches “aide mémoire” (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.