Rencontres R 2024
Une grande créativité dans les mises en forme !
Population active et taux d’activité au sens du recensement selon le sexe et l’âge en 2020 : comparaisons départementales
Intitulés des colonnes fusionnées
Zone des données décalée
readxl
En spécifiant les colonnes à la main
readxl
tidyxl
xlsx_cells
donne un tibble
de la localisation et du contenu des cellules
tidyxl
+ unpivotr
tidyxl
+ unpivotr
up-left
car une cellule fusionnée ne remplit que le haut à gauche
tidyxl
+ unpivotr
tidyxl
+ unpivotr
tidyxl
+ unpivotr
tidyxl
+ unpivotr
Début des données décalées
Intitulés des colonnes fusionnées
Un onglet par année (mais tous pareil) + un onglet de documentation
Des données à la fin que l’on ne souhaite pas importer
readxl
On prend les colonnes telles quelles
readxl
Idem sur les onglets dans un map
excel_sheets(path_c24) |>
set_names() |>
_[-12] |>
map(read_xlsx,
path = path_c24,
skip = 5,
.name_repair = "unique_quiet") |>
list_rbind(names_to = "annee") |>
rename(code_dep = ...1,
lib_dep = ...2) |>
pivot_longer(-c(annee, code_dep, lib_dep),
names_to = "age_mere",
values_to = "perc_naiss") |>
mutate(annee = as.numeric(annee)) |>
filter(!is.na(code_dep) &
!is.na(perc_naiss) &
!code_dep %in% c("F", "M"))
readxl
tidyxl
tidyxl
+ dplyr
/tidyr
df_cells_c24 |>
filter(sheet != "Documentation") |>
filter(row >= 4 & !is_blank & col != 2) |>
select(sheet, row, col, character, numeric) |>
mutate(header_row = case_when(row == 6 ~ character),
code_dep = case_when(col == 1 ~ coalesce(as.character(numeric), character))) |>
group_by(col) |>
fill(header_row, .direction = "down") |>
group_by(row) |>
fill(code_dep, .direction = "down") |>
ungroup() |>
filter(!is.na(numeric) &
!is.na(code_dep) &
!is.na(header_row) & !code_dep %in% c("F", "M")) |>
mutate(sheet = as.numeric(sheet),
header_row = str_trim(header_row)) |>
select(annee = sheet,
code_dep,
age_mere = header_row,
perc_naiss = numeric)
tidyxl
+ unpivotr
penser à grouper par onglet
df_cells_c24 |>
filter(row >= 5) |>
group_by(sheet) |>
behead("up-left", "typ_var") |>
behead("up", "mod_var") |>
behead("left", "code_dep") |>
behead("left", "lib_dep") |>
ungroup() |>
mutate(mod_var = str_trim(mod_var)) |>
select(sheet, typ_var, mod_var, code_dep, lib_dep, numeric) |>
filter(!is.na(code_dep) &
!code_dep %in% c("F", "M") &
!is.na(numeric))
tidyxl
+ unpivotr
filter
), car les espacements ne sont pas toujours les mêmes d’une année sur l’autredplyr
et tidyr
comme fill
ou coalesce
en complémentstr_detect
, comme la date de mise à jourEt des espacements différents, à détecter
Ligne de début - “Départements”
Ligne de fin - ligne blanche vide
df_cells_faj |>
inner_join(df_cells_faj_min, by = join_by(sheet)) |>
inner_join(df_cells_faj_max, by = join_by(sheet)) |>
filter(between(row, row_min, row_max)) |>
group_by(sheet) |>
behead("up-left", "typ_var") |>
behead("up", "mod_var") |>
behead("left", "code_dep") |>
behead("left", "lib_dep") |>
ungroup() |>
select(sheet, typ_var, mod_var, code_dep, lib_dep, character, numeric)
Deux tableaux dans le même onglet
Détection des débuts de tableaux
Puis map
(ou traitement séparé)
De l’information stockée sous une autre forme que le test :
Chargement du contenu et du format de chaque cellule
On utilise unpivotr::behead_if
df_cells_panorama |>
behead("up", "code_geo") |>
behead_if(format_panorama$local$font$bold[local_format_id],
direction = "left-up",
name = "type_etab") |>
behead_if(
format_panorama$local$alignment$indent[local_format_id] == 2,
direction = "left-up",
name = "type_var"
) |>
behead_if(
format_panorama$local$alignment$indent[local_format_id] == 4,
direction = "left",
name = "type_places"
) |>
select(code_geo, type_etab, type_var, type_places, numeric, character) |>
filter(!is.na(numeric))
L’import, avec tidyxl
se résume souvent à de la manipulation de données
Chaque fichier Excel est unique !
Il faut rester pragmatique !