brendaDb aims to make importing and analyzing data from the BRENDA database easier. The main functions include:
tibble
For bug reports or feature requests, please go to the GitHub repository.
brendaDb is a Bioconductor package and can be installed through BiocManager::install()
.
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("brendaDb", dependencies=TRUE)
Alternatively, install the development version from GitHub.
if(!requireNamespace("brendaDb")) {
devtools::install_github("y1zhou/brendaDb")
}
After the package is installed, it can be loaded into the R workspace by
library(brendaDb)
Download the BRENDA database as a text file here. Alternatively, download the file in R (file updated 2019-04-24):
brenda.filepath <- DownloadBrenda()
#> Please read the license agreement in the link below.
#>
#> https://www.brenda-enzymes.org/download_brenda_without_registration.php
#>
#> Found zip file in cache.
#> Extracting zip file...
The function downloads the file to a local cache directory. Now the text file can be loaded into R as a tibble
:
df <- ReadBrenda(brenda.filepath)
#> Reading BRENDA text file...
#> Converting text into a list. This might take a while...
#> Converting list to tibble and removing duplicated entries...
#> If you're going to use this data again, consider saving this table using data.table::fwrite().
As suggested in the function output, you may save the df
object to a text file using data.table::fwrite()
or to an R object using save(df)
, and load the table using data.table::fread()
or load()
1 This requires the R package data.table to be installed.. Both methods should be much faster than reading the raw text file again using ReadBrenda()
.
Since BRENDA is a database for enzymes, all final queries are based on EC numbers.
If you already have a list of EC numbers in mind, you may call QueryBrenda
directly:
brenda_txt <- system.file("extdata", "brenda_download_test.txt",
package = "brendaDb")
df <- ReadBrenda(brenda_txt)
#> Reading BRENDA text file...
#> Converting text into a list. This might take a while...
#> Converting list to tibble and removing duplicated entries...
#> If you're going to use this data again, consider saving this table using data.table::fwrite().
res <- QueryBrenda(df, EC = c("1.1.1.1", "6.3.5.8"), n.core = 2)
res
#> A list of 2 brenda.entry object(s) with:
#> - 1 regular brenda.entry object(s)
#> 1.1.1.1
#> - 1 transferred or deleted object(s)
#> 6.3.5.8
res[["1.1.1.1"]]
#> Entry 1.1.1.1
#> ├── nomenclature
#> | ├── ec: 1.1.1.1
#> | ├── systematic.name: alcohol:NAD+ oxidoreductase
#> | ├── recommended.name: alcohol dehydrogenase
#> | ├── synonyms: A tibble with 128 rows
#> | ├── reaction: A tibble with 2 rows
#> | └── reaction.type: A tibble with 3 rows
#> ├── interactions
#> | ├── substrate.product: A tibble with 772 rows
#> | ├── natural.substrate.product: A tibble with 20 rows
#> | ├── cofactor: A tibble with 7 rows
#> | ├── metals.ions: A tibble with 20 rows
#> | ├── inhibitors: A tibble with 207 rows
#> | └── activating.compound: A tibble with 22 rows
#> ├── parameters
#> | ├── km.value: A tibble with 878 rows
#> | ├── turnover.number: A tibble with 495 rows
#> | ├── ki.value: A tibble with 34 rows
#> | ├── pi.value: A tibble with 11 rows
#> | ├── ph.optimum: A tibble with 55 rows
#> | ├── ph.range: A tibble with 28 rows
#> | ├── temperature.optimum: A tibble with 29 rows
#> | ├── temperature.range: A tibble with 20 rows
#> | ├── specific.activity: A tibble with 88 rows
#> | └── ic50: A tibble with 2 rows
#> ├── organism
#> | ├── organism: A tibble with 159 rows
#> | ├── source.tissue: A tibble with 63 rows
#> | └── localization: A tibble with 9 rows
#> ├── molecular
#> | ├── stability
#> | | ├── general.stability: A tibble with 15 rows
#> | | ├── storage.stability: A tibble with 15 rows
#> | | ├── ph.stability: A tibble with 20 rows
#> | | ├── organic.solvent.stability: A tibble with 25 rows
#> | | ├── oxidation.stability: A tibble with 3 rows
#> | | └── temperature.stability: A tibble with 36 rows
#> | ├── purification: A tibble with 48 rows
#> | ├── cloned: A tibble with 46 rows
#> | ├── engineering: A tibble with 60 rows
#> | ├── renatured: A tibble with 1 rows
#> | └── application: A tibble with 5 rows
#> ├── structure
#> | ├── molecular.weight: A tibble with 119 rows
#> | ├── subunits: A tibble with 11 rows
#> | ├── posttranslational.modification: A tibble with 2 rows
#> | └── crystallization: A tibble with 22 rows
#> └── bibliography
#> | └── reference: A tibble with 285 rows
You can also query for certain fields to reduce the size of the returned object.
ShowFields(df)
#> # A tibble: 40 × 2
#> field acronym
#> <chr> <chr>
#> 1 PROTEIN PR
#> 2 RECOMMENDED_NAME RN
#> 3 SYSTEMATIC_NAME SN
#> 4 SYNONYMS SY
#> 5 REACTION RE
#> 6 REACTION_TYPE RT
#> 7 SOURCE_TISSUE ST
#> 8 LOCALIZATION LO
#> 9 NATURAL_SUBSTRATE_PRODUCT NSP
#> 10 SUBSTRATE_PRODUCT SP
#> # ℹ 30 more rows
res <- QueryBrenda(df, EC = "1.1.1.1", fields = c("PROTEIN", "SUBSTRATE_PRODUCT"))
res[["1.1.1.1"]][["interactions"]][["substrate.product"]]
#> # A tibble: 772 × 7
#> proteinID substrate product commentarySubstrate commentaryProduct
#> <chr> <chr> <chr> <chr> <chr>
#> 1 10 n-propanol + NAD+ n-prop… <NA> <NA>
#> 2 10 2-propanol + NAD+ aceton… <NA> <NA>
#> 3 10 n-hexanol + NAD+ n-hexa… <NA> <NA>
#> 4 10 (S)-2-butanol + NAD+ 2-buta… <NA> <NA>
#> 5 10 ethylenglycol + NAD+ ? + NA… <NA> <NA>
#> 6 10 n-butanol + NAD+ butyra… <NA> <NA>
#> 7 10 n-decanol + NAD+ n-deca… <NA> <NA>
#> 8 10 Tris + NAD+ ? + NA… <NA> <NA>
#> 9 10 isopropanol + NAD+ aceton… <NA> <NA>
#> 10 10 5-hydroxymethylfurfu… (furan… #10# mutant enzyme… <NA>
#> # ℹ 762 more rows
#> # ℹ 2 more variables: reversibility <chr>, refID <chr>
It should be noted that most fields contain a fieldInfo
column and a commentary
column. The fieldInfo
column is what’s extracted by BRENDA from the literature, and the commentary
column is usually some context from the original paper. #
symbols in the commentary correspond to the proteinID
s, and <>
enclose the corresponding refID
s. For further information, please see the README file from BRENDA.
Note the difference in row numbers in the following example and in the one where we queried for all organisms.
res <- QueryBrenda(df, EC = "1.1.1.1", organisms = "Homo sapiens")
res$`1.1.1.1`
#> Entry 1.1.1.1
#> ├── nomenclature
#> | ├── ec: 1.1.1.1
#> | ├── systematic.name: alcohol:NAD+ oxidoreductase
#> | ├── recommended.name: alcohol dehydrogenase
#> | ├── synonyms: A tibble with 41 rows
#> | ├── reaction: A tibble with 2 rows
#> | └── reaction.type: A tibble with 3 rows
#> ├── interactions
#> | ├── substrate.product: A tibble with 102 rows
#> | ├── natural.substrate.product: A tibble with 9 rows
#> | ├── cofactor: A tibble with 2 rows
#> | ├── metals.ions: A tibble with 2 rows
#> | └── inhibitors: A tibble with 36 rows
#> ├── parameters
#> | ├── km.value: A tibble with 163 rows
#> | ├── turnover.number: A tibble with 64 rows
#> | ├── ki.value: A tibble with 8 rows
#> | ├── ph.optimum: A tibble with 15 rows
#> | ├── ph.range: A tibble with 2 rows
#> | ├── temperature.optimum: A tibble with 2 rows
#> | └── specific.activity: A tibble with 5 rows
#> ├── organism
#> | ├── organism: A tibble with 3 rows
#> | ├── source.tissue: A tibble with 21 rows
#> | └── localization: A tibble with 1 rows
#> ├── molecular
#> | ├── stability
#> | | ├── general.stability: A tibble with 1 rows
#> | | ├── storage.stability: A tibble with 4 rows
#> | | ├── ph.stability: A tibble with 1 rows
#> | | ├── organic.solvent.stability: A tibble with 1 rows
#> | | └── temperature.stability: A tibble with 2 rows
#> | ├── purification: A tibble with 7 rows
#> | ├── cloned: A tibble with 5 rows
#> | ├── engineering: A tibble with 3 rows
#> | └── application: A tibble with 1 rows
#> ├── structure
#> | ├── molecular.weight: A tibble with 12 rows
#> | ├── subunits: A tibble with 3 rows
#> | └── crystallization: A tibble with 2 rows
#> └── bibliography
#> | └── reference: A tibble with 285 rows
To transform the brenda.entries
structure into a table, use the helper function ExtractField()
.
res <- QueryBrenda(df, EC = c("1.1.1.1", "6.3.5.8"), n.core = 2)
ExtractField(res, field = "parameters$ph.optimum")
#> Deprecated entries in the res object will be removed.
#> # A tibble: 158 × 9
#> ec organism proteinID uniprot org.commentary description fieldInfo
#> <chr> <chr> <chr> <chr> <chr> <chr> <lgl>
#> 1 1.1.1.1 Acetobacter p… 60 <NA> <NA> 5.5 NA
#> 2 1.1.1.1 Acetobacter p… 60 <NA> <NA> 6 NA
#> 3 1.1.1.1 Acetobacter p… 60 <NA> <NA> 8.5 NA
#> 4 1.1.1.1 Acinetobacter… 28 <NA> <NA> 5.9 NA
#> 5 1.1.1.1 Aeropyrum per… 131 Q9Y9P9 <NA> 10.5 NA
#> 6 1.1.1.1 Aeropyrum per… 131 Q9Y9P9 <NA> 8 NA
#> 7 1.1.1.1 Arabidopsis t… 20 <NA> <NA> 10.5 NA
#> 8 1.1.1.1 Aspergillus n… 14 <NA> <NA> 8.1 NA
#> 9 1.1.1.1 Brevibacteriu… 46 <NA> <NA> 10.4 NA
#> 10 1.1.1.1 Brevibacteriu… 46 <NA> <NA> 6 NA
#> # ℹ 148 more rows
#> # ℹ 2 more variables: commentary <chr>, refID <chr>
As shown above, the returned table consists of three parts: the EC number, organism-related information (organism, protein ID, uniprot ID, and commentary on the organism), and extracted field information (description, commentary, etc.).
A lot of the times we have a list of gene symbols or enzyme names instead of EC numbers. In this case, a helper function can be used to find the corresponding EC numbers:
ID2Enzyme(brenda = df, ids = c("ADH4", "CD38", "pyruvate dehydrogenase"))
#> # A tibble: 4 × 5
#> ID EC RECOMMENDED_NAME SYNONYMS SYSTEMATIC_NAME
#> <chr> <chr> <chr> <chr> <chr>
#> 1 ADH4 1.1.1.1 <NA> "aldehy… <NA>
#> 2 CD38 2.4.99.20 <NA> "#1,3,4… <NA>
#> 3 pyruvate dehydrogenase 1.2.1.51 pyruvate dehydrogen… "#1,2# … <NA>
#> 4 pyruvate dehydrogenase 2.7.11.2 [pyruvate dehydroge… "kinase… ATP:[pyruvate …
The EC
column can be then handpicked and used in QueryBrenda()
.
Often we are interested in the enzymes involved in a specific BioCyc pathway. As BioCyc now requires login credentials for using their web service, users are recommended to use the metabolike package for more advanced queries.
By default QueryBrenda
uses all available cores, but often limiting n.core
could give better performance as it reduces the overhead. The following are results produced on a machine with 40 cores (2 Intel Xeon CPU E5-2640 v4 @ 3.4GHz), and 256G of RAM:
EC.numbers <- head(unique(df$ID), 100)
system.time(QueryBrenda(df, EC = EC.numbers, n.core = 0)) # default
# user system elapsed
# 4.528 7.856 34.567
system.time(QueryBrenda(df, EC = EC.numbers, n.core = 1))
# user system elapsed
# 22.080 0.360 22.438
system.time(QueryBrenda(df, EC = EC.numbers, n.core = 2))
# user system elapsed
# 0.552 0.400 13.597
system.time(QueryBrenda(df, EC = EC.numbers, n.core = 4))
# user system elapsed
# 0.688 0.832 9.517
system.time(QueryBrenda(df, EC = EC.numbers, n.core = 8))
# user system elapsed
# 1.112 1.476 10.000
sessionInfo()
#> R version 4.4.0 beta (2024-04-15 r86425)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 22.04.4 LTS
#>
#> Matrix products: default
#> BLAS: /home/biocbuild/bbs-3.19-bioc/R/lib/libRblas.so
#> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: America/New_York
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] brendaDb_1.18.0 BiocStyle_2.32.0
#>
#> loaded via a namespace (and not attached):
#> [1] tidyr_1.3.1 rappdirs_0.3.3 sass_0.4.9
#> [4] utf8_1.2.4 generics_0.1.3 RSQLite_2.3.6
#> [7] stringi_1.8.3 digest_0.6.35 magrittr_2.0.3
#> [10] evaluate_0.23 bookdown_0.39 fastmap_1.1.1
#> [13] blob_1.2.4 jsonlite_1.8.8 DBI_1.2.2
#> [16] BiocManager_1.30.22 httr_1.4.7 purrr_1.0.2
#> [19] fansi_1.0.6 codetools_0.2-20 jquerylib_0.1.4
#> [22] cli_3.6.2 rlang_1.1.3 crayon_1.5.2
#> [25] dbplyr_2.5.0 bit64_4.0.5 withr_3.0.0
#> [28] cachem_1.0.8 yaml_2.3.8 tools_4.4.0
#> [31] parallel_4.4.0 BiocParallel_1.38.0 memoise_2.0.1
#> [34] dplyr_1.1.4 filelock_1.0.3 curl_5.2.1
#> [37] vctrs_0.6.5 R6_2.5.1 BiocFileCache_2.12.0
#> [40] lifecycle_1.0.4 stringr_1.5.1 bit_4.0.5
#> [43] pkgconfig_2.0.3 pillar_1.9.0 bslib_0.7.0
#> [46] glue_1.7.0 Rcpp_1.0.12 xfun_0.43
#> [49] tibble_3.2.1 tidyselect_1.2.1 knitr_1.46
#> [52] htmltools_0.5.8.1 rmarkdown_2.26 compiler_4.4.0