<- "([A-Za-z]{2,5}-)?[A-Za-z]{2,5}-\\d{2}-\\d{2}" regex_report_id
Recensement des projets
Établir une liste des projets
Chaque rapport de laboratoire contient sur sa page de garde l’ensemble des métadonnées en lien avec le projet de recherche pour lequel cette analyse a été demandé. On désire donc extraire la page de garde de chacun des rapports de laboratoires afin d’obtenir la liste des projets.
Un rapport de laboratoire peut être detectable dans une liste de fichier par la structure de son identifiant unique. Voici un exemple d’identifiant unique: CHEM-PCDD-00-07
ou encore MB-05-10
. Ces identifiants ont une structure unique que l’on peut detecter grace à l’expression régulière suivante:
La variable regex_report_id
sera utilisée plusieurs fois dans ce document.
On liste les rapports de laboratoire présents dans le dossier 03-Labo/Results Reports
.
<- list.files(
reports_path "C:/Users/VissaultS/Documents/03-Labo/Results Reports",
pattern = "*.pdf|*.docx|*.doc", recursive = TRUE, full.names = TRUE
)
# On extrait les identifiants des rapports du nom du fichier
<- stringr::str_extract(reports_path, regex_report_id)
report_id
# On obtient la signature du fichier, ca va être pratique pour detecter les fichiers dupliqués même si le nom du fichier est différent.
<- tools::md5sum(reports_path)
file_hash
# On extrait l'extension du fichier
<- reports_path |>
file_ext strsplit("[.]") |>
::map_chr(\(e) return(e[2]))
purrr
# On compose un tableau avec l'ensemble de ces informations
<- data.frame(
reports path = reports_path,
id = report_id,
hash = file_hash,
ext = file_ext
|> tibble::as_tibble() )
Note: tools::md5sum
permet de générer une signature unique propre au fichier. Ainsi deux fichiers identiques dans le contenu mais avec des noms différents pourront être identifié comme des duplicats.
Voici la liste des fichiers identiques dans le dossier 03-Labo/Results Reports
.
<- reports |>
reports_dup ::as_tibble() |>
tibble::get_dupes(-c(path)) |>
janitor::select(-hash)
dplyr
|> knitr::kable() reports_dup
id | ext | dupe_count | path |
---|---|---|---|
BMK-PFC-23-10 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/BMK-PFC-23-10_HERG-COEI_eggs2023.pdf | |
BMK-PFC-23-10 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/EideràDuvet Rapports 1972-2023/BMK-PFC-23-10_HERG-COEI_eggs2023.pdf | |
BMK-PFC-23-10 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GoelandArgente 2017, 2022-23/BMK-PFC-23-10_HERG-COEI_eggs2023.pdf | |
CHEM-OC-22-10 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/CHEM-OC-22-10_GBHE-HERG2022.pdf | |
CHEM-OC-22-10 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GoelandArgente 2017, 2022-23/CHEM-OC-22-10_GBHE-HERG2022.pdf | |
CHEM-OC-22-10 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GrandHeron Rapports xxxx-2022/Rapports/CHEM-OC-22-10_GBHE-HERG2022.pdf | |
MET-THg-22-05 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GoelandArgente 2017, 2022-23/MET-THg-22-05 - RALA01-2022_HERG-GBHEegg2022.pdf | |
MET-THg-22-05 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GrandHeron Rapports xxxx-2022/Rapports/MET-THg-22-05 - RALA01-2022_HERG-GBHEegg2022.pdf | |
MET-THg-22-05 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/MET-THg-22-05 - RALA01-2022_HERG-GBHEegg2022.pdf | |
MET-THg-23-13 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/EideràDuvet Rapports 1972-2023/MET-THg-23-13 - RALA01-2023.pdf | |
MET-THg-23-13 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GoelandArgente 2017, 2022-23/MET-THg-23-13 - RALA01-2023.pdf | |
MET-THg-23-13 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/MET-THg-23-13 - RALA01-2023_OeufsCOEI-HERG2023.pdf | |
TP-SI-22-09 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GoelandArgente 2017, 2022-23/TP-SI-22-09C_RALA01-2022_HERG-GBHEeggs2022.pdf | |
TP-SI-22-09 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GrandHeron Rapports xxxx-2022/Rapports/TP-SI-22-09C_RALA01-2022_HERG-GBHEeggs2022.pdf | |
TP-SI-22-09 | 3 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/TP-SI-22-09C_RALA01-2022_HERG-GBHEeggs2022.pdf | |
CHEM-OC-21-08 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/CHEM-OC-21-08R.pdf | |
CHEM-OC-21-08 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/FouBassan Rapports 1984-2019/CHEM-OC-21-08R.pdf | |
CHEM-OC-22-05 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/CHEM-OC-22-05_HERGDeslauriers.pdf | |
CHEM-OC-22-05 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/GoelandArgente 2017, 2022-23/CHEM-OC-22-05_HERGDeslauriers.pdf | |
CHEM-OC-23-08 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/CHEM-OC-23-08_EggHERG_COEI_2023.pdf | |
CHEM-OC-23-08 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/EideràDuvet Rapports 1972-2023/CHEM-OC-23-08_EggHERG_COEI_2023.pdf | |
MET-THg-21-03 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/FouBassan Rapports 1984-2019/MET-THg-21-03.pdf | |
MET-THg-21-03 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/MET-THg-21-03 - RALA01-2021_eggs.pdf | |
TP-SI-21-05 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/FouBassan Rapports 1984-2019/TP-SI-21-05C.pdf | |
TP-SI-21-05 | 2 | C:/Users/VissaultS/Documents/03-Labo/Results Reports/TP-SI-21-05C_RALA01-2021.pdf |
On selectionne le premier rapport en se basant sur le id (ex. BMK-PFC-23-01) pour éliminer les rapports dupliqués pour la suite de l’analyse. On s’assure de selectionner préférablement les pdfs si on dispose d’un docx et d’un document pdf pour le même identifiant de rapport de laboratoire.
<- reports |>
reports # On retire les rapports qui sont dupliqués
::group_by(hash) |>
dplyr::slice(1) |>
dplyr::ungroup() |>
dplyr# Si plusieurs extension de fichiers, on selectionne ceux en PDF préférablement, sinon .docx, sinon .doc en dernier recours.
::group_split(id) |>
dplyr::map(\(g){
purrr|> dplyr::arrange(factor(ext, levels = c('pdf', 'docx', 'doc'))) |>
g ::slice(1)
dplyr|>
}) ::bind_rows() dplyr
Quelques rapports de laboratoire demeurent au format doc et docx.
<- reports |> dplyr::filter(ext %in% c('doc', 'docx'))
docs |> knitr::kable() docs
path | id | hash | ext |
---|
Afin de faciliter l’extraction des métadonnées par programmation, on convertit les fichiers .doc et .docx en pdf.
Convertion des documents Word en pdf
Cette étape a été complété manuellement.
Extraire les métadonnées du rapport
Nous souhaitons générer une liste de tous les projets basée sur les 71 rapports de laboratoire stockés dans le dossier 03-Labo/Comptes rendus
de résultats. La première page de chaque rapport de laboratoire contient toutes les informations pertinentes pour produire cette liste.
Pour chaque rapport, nous vérifions s’il s’agit d’une image ou non. Si le rapport est une image, nous devons utiliser une reconnaissance optique de caractères (OCR) afin d’extraire le texte de la première page et d’obtenir toutes les métadonnées pertinentes. Si c’est un pdf ou un fichier word, nous importons la première page du document.
# On détect si le document est une image
<- reports |> dplyr::mutate(
reports filename = basename(path),
is_image = purrr::map2_lgl(path, ext, \(p, e) {
if(e == "pdf"){
<- pdftools::pdf_text(p)
out !all(nchar(out) > 15)
else {
} FALSE
}
})
)
# On extrait le texte par OCR si c'est une image
<- purrr::map2_vec(reports$path, reports$is_image, \(p, i) {
frontpages ifelse(isTRUE(i),
::pdf_ocr_text(pdf = p, pages = 1),
pdftools::pdf_text(pdf = p)[[1]]
pdftools
)|> tolower() })
Une fois le texte de la première page isolé, on applique une série d’opération d’extractions de texte à partir de la position de mots clés. On isole ainsi le titre du projet, l’ID du projet, la date etc.
<- purrr::map_vec(frontpages, \(f){
project_id ::str_extract(f, "(?<=(project: |project |projects|projet :)).*(?=\n)")
stringr|>
}) toupper() |>
::word(1) |>
stringr::str_replace_all("[.,]", "") |>
stringr::str_trim() |>
stringr::na_if("")
dplyr
<- purrr::map_vec(frontpages, \(f){
project_leader ::str_extract(f, "(?<=(project leader: |project leader |project manager: |manager: |study leader: |nom du requérant :)).*(?=\n)")
stringr|>
}) ::str_replace_all(c("[_|:]" = "", "[:digit:]" = "", "[.]$" = "")) |>
stringr::str_to_title() |>
stringr::str_trim()
stringr
<- frontpages |>
project_dates ::map_vec(\(f){
purrr<- stringr::str_extract(f, "\\d{4}-\\d{2}-\\d{2}")
dates if(is.na(dates)) {
<- stringr::str_extract(f, "(?<=(date: )).*(?=\n)")
dates
}return(dates)
})
<- data.frame(
reportsProject report_id = reports$id,
report_access_path = stringr::str_replace_all(reports$path, "C:/Users/VissaultS/Documents", "Z:"),
project_title = NA
project_id, project_leader, project_dates, )
Le data.frame reportsProject
est à la base du fichier “Z:\07-Données BD_projects_list_extract_25032024.xlsx”.
Valider l’existence de rapports de laboratoire dans le dossier 01-Projet et suivis
On valide si certains de ces rapports ne se retrouvent pas dans le dossier 03-Labo/Comptes rendus
. Ces rapports pourraient potentiellement nous interressés.
<- list.files(
files "C:/Users/VissaultS/Documents/01-Projets et suivis",
pattern = "*.pdf|*.docx|*.doc", recursive = TRUE, full.names = TRUE
)
<- data.frame(file = files[which(stringr::str_detect(files, regex_report_id))])
potential_reports
<- potential_reports |> dplyr::mutate(
potential_reports id = stringr::str_extract(file, regex_report_id) |> toupper(),
in_lab_report_folder = !(id %in% reports$id)
|> dplyr::arrange(in_lab_report_folder) |>
) ::mutate(file = stringr::str_replace(file, "C:/Users/VissaultS/Documents/", "Z:")) dplyr