-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitgr_tbl_analytes.qmd
207 lines (153 loc) · 9.76 KB
/
itgr_tbl_analytes.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
---
title: "Consolidation de la nomenclature des analytes"
author: "Steve Vissault"
date: "2024-03-28"
execute:
eval: FALSE
cache: true
---
Nous désirons consolider la nomenclature des analytes. On peut observer plusieurs divergences dans la facon de nommer les analytes, exemple PCB-17 ou PCB 17. Cette section documente la démarche pour tendre vers une réconciliation des termes utilisés.
On charge les données intégrées depuis le package `toxbox`. Les données ne sont pas entreposées dans le package, la function `itgr_measurements()` permet de lire les fichiers Excels entreposées sur le disque réseau `Z:` et les fusionne dans un seul `data.frame`. Il faut pour cela que le VPN soit ouvert, si vous n'êtes pas directement sur le réseau d'environnement canada.
```{r}
source("src/itgr_measurements.R")
```
```{r}
measurements <- itgr_measurements()
```
## Analytes avec un numéro CAS fournis par le laboratoire
La nomenclature des composées chimiques / analytes peut diverger d'un laboratoire à un autre. Chaque pays dispose également de sa propre nomenclature (ex. États-Unis, Allemagne, Royaume-Unis). Afin de reconcilier la nomenclature, nous souhaitons utiliser un identifiant unique international tel que l'[International Chemical Identifier](https://fr.wikipedia.org/wiki/International_Chemical_Identifier) (InChl).
Dans un premier temps, on charge les données sur les analytes (incluant le CAS) fournies par les laboratoires. Le fichier `analytes_consolidation_27032024` est la fusion des onglets _Analyte Information_ des différentes base de données.
On fusionne les données sur les analytes avec les mesures.
```{r}
analytes <- readxl::read_excel("Z:/07-Données BD/intermediate_files/analytes_consolidation_27032024.xlsx") |>
dplyr::select(Analyte, CASNumber) |>
dplyr::filter(!is.na(CASNumber)) |>
dplyr::mutate(
key = janitor::make_clean_names(Analyte, allow_dupes = TRUE, case = "none") |> tolower()
) |>
dplyr::distinct()
measurements <- measurements |>
dplyr::mutate(
key = stringr::str_replace(variable, "PCB-|PCB ", "PCB") |>
janitor::make_clean_names(allow_dupes = TRUE, case = "none") |> tolower()
)
measurements <- measurements |>
dplyr::left_join(analytes, by = "key")
```
On isole le nom des contaminants pour lesquels nous n'avons pas de CAS associés. Voici la liste de ces contaminants:
```{R, results="asis"}
contaminants_orphelins <- measurements |>
dplyr::filter(is.na(CASNumber)) |>
dplyr::select(key, variable, CASNumber) |>
dplyr::distinct()
reactable::reactable(contaminants_orphelins, searchable = TRUE)
```
## Obtention du numéro de CAS par le service CTS
La fonction `webchem::cts_convert()` permet d'interroger plusieurs base de données de référence sur des composées chimiques et d'extraire des identifiants tels que le CAS à partir du nom d'un composé chimique. La fonction `webchem::cts_convert()` s'interface sur le service https://cts.fiehnlab.ucdavis.edu/.
```{r}
cas_from_cts <- webchem::cts_convert(contaminants_orphelins$variable, from = "Chemical Name", to = "CAS", match = "first")
cas <- purrr::map2_df(names(cas_from_cts), cas_from_cts, \(n, c){
return(data.frame(variable = n, CASNumber = c))
})
reactable::reactable(cas, searchable = TRUE)
```
En cherchant le numéro CAS avec le nom du composé, on s'apercoit que plusieurs PCB (ex. PCB 60 et 64) tombent sous le même CAS, ce qui est incorrect. On change donc d'approche puisque le service CTS ne semblent pas être un bon service de résolution par le nom.
## Obtention du numéro de CAS par le service ChemSpider (csid)
Ce service est fournis par la Société Royale de Chimie. C'est un des services qui semble être robuste pour obtenir un identifiant unique à partir du nom du composé. Une fois, l'identifiant ChemSpider obtenue il est possible d'obtenir le numéro CAS en utilisant le service https://cts.fiehnlab.ucdavis.edu/. On utilise ce service pour effectuer la conversion d'identifiants entre nomenclature (ex. csid vers CAS). Attention, ce service requière l'enregistrement d'un compte et le nombre de requête est limités à 1000 appels par mois.
```{R, eval = FALSE}
csid <- webchem::get_csid(contaminants_orphelins$variable, from = "name")
csid <- csid |> dplyr::rename(variable = query) |>
dplyr::left_join(
dplyr::select(contaminants_orphelins, key, variable)
) |>
dplyr::filter(!is.na(csid)) |>
dplyr::mutate(csid = as.character(csid))
saveRDS(csid, "data/csid.rds")
```
```{r}
if(!exists("csid")) csid <- readRDS("data/csid.rds")
cas_from_csid <- webchem::cts_convert(csid$csid, from = "ChemSpider", to = "CAS", match = "first")
cas2 <- purrr::map2_df(names(cas_from_csid), cas_from_csid, \(n, c){
return(data.frame(csid = n, CASNumber = c))
}) |> dplyr::left_join(csid, by = "csid")
reactable::reactable(cas2, searchable = TRUE)
```
Effectuer la résolution de la nomenclature des composées par l'utilisation du service ChemSpider semble plus prometteur. Après une vérification visuelle, on voit que les composées ne présentent plus d'identifiant unique identique.
## Ajout de l'identifiant PubChem (pubcid)
Afin de permettre le retrait d'informations supplémentaires sur les composées chimiques, une des base de données d'intérêt est PubChem. À partir de cette base de données, on peut effectuer le retrait de certaines propriétés chimiques du composée telles que la masse moléculaire par exemple.
```{r}
pubcid <- webchem::cts_convert(cas2$csid, from = "ChemSpider", to = "PubChem CID", match = "first")
cas3 <- purrr::map2_df(names(pubcid), pubcid, \(n, c){
return(data.frame(csid = n, pubcid = c))
}) |> dplyr::distinct() |>
dplyr::left_join(cas2, by = "csid") |>
dplyr::distinct() |>
# On consolide le tableau final
dplyr::rename(casid = CASNumber) |>
dplyr::mutate(variable = tolower(variable)) |>
dplyr::distinct()
```
## Consolidation de la table de reference des analytes
On a ajouté 3 identifiants pour chaque composée chimique de la base de données. Parmis, ces identifiants nous retrouvons: le [CAS](https://commonchemistry.cas.org/) (casid, identifiant fournis généralement par le laboratoire d'analyse, nomenclature américaine), le [ChemSpider ID](https://www.chemspider.com/) (csid, nomenclature britanique) et enfin le [PubChem ID](https://pubchem.ncbi.nlm.nih.gov/) (pubcid, nomenclature américaine).
On a enfin toutes les informations pour construire la table de référence des composées chimiques. On récupère les composées chimiques pour lesquelles le CAS est renseigné par le laboratoire.
```{r}
contaminants_with_cas <- measurements |>
dplyr::filter(!is.na(CASNumber)) |>
dplyr::select(key, variable, CASNumber) |>
dplyr::rename(casid = CASNumber) |>
dplyr::mutate(variable = tolower(variable)) |>
dplyr::distinct()
```
On va chercher le PubChem ID et et le spiderChem ID pour les contaminants qui avaient déjà un CAS (fournit par le laboratoire).
```{r}
csid <- webchem::cts_convert(contaminants_with_cas$casid, from = "CAS", to = "ChemSpider", match = "first")
csid <- purrr::map2_df(names(csid), csid, \(n, c){
return(data.frame(casid = n, csid = c))
})
pubcid <- webchem::cts_convert(contaminants_with_cas$casid, from = "CAS", to = "PubChem CID", match = "first")
pubcid <- purrr::map2_df(names(pubcid), pubcid, \(n, c){
return(data.frame(casid = n, pubcid = c))
})
contaminants <- contaminants_with_cas |>
dplyr::left_join(csid, by = "casid") |>
dplyr::left_join(pubcid, by = "casid") |>
dplyr::distinct() |>
dplyr::bind_rows(cas3) |>
dplyr::mutate(
url_casid = ifelse(!is.na(casid), paste0("https://commonchemistry.cas.org/detail?cas_rn=", casid), NA),
url_pubcid = ifelse(!is.na(pubcid), paste0("https://pubchem.ncbi.nlm.nih.gov/compound/", pubcid), NA),
url_csid = ifelse(!is.na(csid), paste0("https://www.chemspider.com/Chemical-Structure.", csid, ".html"), NA)
) |>
dplyr::select(-variable) |>
dplyr::distinct()
```
Validation: Est-ce que tous les contaminants dans la table de référence sont présent dans la table des mesures?
```{r}
keys <- measurements$key |>
unique()
contaminants_without_ids <- data.frame(key = keys[!keys %in% contaminants$key], pubcid = NA, csid = NA, casid = NA)
contaminants <- dplyr::bind_rows(contaminants, contaminants_without_ids) |>
dplyr::distinct()
sources <- dplyr::select(measurements, key, source, conpound_family) |>
dplyr::distinct()
```
On écrit le fichier pour pouvoir repasser manuellement dessus.
```{r}
writexl::write_xlsx(list(contaminants, sources), path = "data/tbl_contaminants_ref.xlsx")
```
### Ajout des unités à la table de référence
On utilise les données contenues dans le fichier `Z:/07-Données BD/intermediate_files/analytes_consolidation_27032024.xlsx` et qui contient les unités pour un certains nombres de composées. Ce tableau est une fusion des informations documentés dans l'onglet "Analytes informations" des bases de données COEI, HERG et GBHE.
```{r}
tbl_analytes <- readxl::read_excel("data/tbl_contaminants_ref_manual.xlsx") |>
tidyr::separate_rows(original_ids, sep = ";")
analytes_units <- readxl::read_excel("Z:/07-Données BD/intermediate_files/analytes_consolidation_27032024.xlsx") |>
dplyr::mutate(
key = janitor::make_clean_names(Analyte, allow_dupes = TRUE, case = "none") |> tolower()
) |>
dplyr::select(key, Units) |>
dplyr::distinct()
tbl_analytes <- tbl_analytes |> dplyr::left_join(analytes_info, by = c("original_ids" = "key")) |>
dplyr::group_by_at(dplyr::vars(-original_ids, -Units)) |>
dplyr::summarize(original_ids = paste(original_ids, collapse = ";"), Units = paste(Units, collapse = ";"))
writexl::write_xlsx(tbl_analytes, path = "data/tbl_contaminants_ref.xlsx")
```