Resource specific interaction attributes
Denes Turei
Institute for Computational Biomedicine, Heidelberg Universityturei.denes@gmail.com Source:
vignettes/extra_attrs.Rmd
extra_attrs.RmdAbstract
OmniPath provides a broad variety of protein annotations, but
for interactions, until recently, only a standard set of essential
attributes (direction, effect, etc) and a handful of others
(e.g. DoRothEA confidence level) were available. The newly
introduced extra_attrs column consists of JSON
encoded custom, resource specific attributes from network
databases. We also revised the processing of these resources to
ensure that we include as many useful attributes as possible. In
the OmnipathR package we added a few new functions to support the
processing of the JSON encoded column: to scan it for keys and
values, and to extract specific variables of interest into new
columns. We give a brief overview of these here.
Loading a network
First we retrieve the complete directed PPI network. Importantly, the
extra attributes are only included if the
fields = "extra_attrs" argument is provided.
i <- post_translational(fields = 'extra_attrs')
dplyr::select(i, source_genesymbol, target_genesymbol, extra_attrs)## # A tibble: 139,054 x 3
## source_genesymbol target_genesymbol extra_attrs
## <chr> <chr> <list>
## 1 CALM3 TRPC1 <named list [1]>
## 2 CALM1 TRPC1 <named list [1]>
## 3 CALM2 TRPC1 <named list [1]>
## 4 CAV1 TRPC1 <named list [1]>
## 5 DRD2 TRPC1 <named list [1]>
## 6 MDFI TRPC1 <named list [1]>
## 7 ITPR2 TRPC1 <named list [1]>
## 8 MARCKS TRPC1 <named list [1]>
## 9 TRPC1 GRM1 <named list [0]>
## 10 GRM1 TRPC1 <named list [1]>
## # i 139,044 more rows
Above we see, the extra_attrs column is a list type
column. Each list is a nested list itself, containing the extra
attributes from all resources, as it was extracted from the JSON.
Which extra attributes are available?
Which attributes present in the network depends only on the
interactions: if none of the interactions is from the SPIKE
database, obviously the SPIKE_mechanism won’t be present.
The names of the extra attributes consist of the name of the resource
and the name of the attribute, separated by an underscore. The resource
name never contains underscore, while some attribute names do. To list
the extra attributes available in a particular data frame use the
extra_attrs function:
extra_attrs(i)## [1] "TRIP_method" "SIGNOR_mechanism"
## [3] "PhosphoSite_noref_evidence" "PhosphoPoint_category"
## [5] "PhosphoSite_evidence" "HPRD-phos_mechanism"
## [7] "Li2012_mechanism" "Li2012_route"
## [9] "SPIKE_effect" "SPIKE_mechanism"
## [11] "SPIKE_LC_effect" "SPIKE_LC_mechanism"
## [13] "CA1_effect" "CA1_type"
## [15] "Macrophage_type" "Macrophage_location"
## [17] "ACSN_effect" "Cellinker_type"
## [19] "CellChatDB_category" "talklr_putative"
## [21] "CellPhoneDB_type" "CellPhoneDB_is_ppi"
## [23] "Ramilowski2015_source" "ARN_effect"
## [25] "ARN_is_direct" "ARN_is_directed"
## [27] "NRF2ome_effect" "NRF2ome_is_direct"
## [29] "NRF2ome_is_directed"
The labels listed here are the top level keys in the lists in the
extra_attrs column. Note, the coverage of these variables
varies a lot, typically in agreement with the size of the resource.
Inspecting one attribute
The values of each extra attribute, in theory, can be arbitrarily
complex nested lists, but in reality, these are most often simple
numeric, logical or character values or vectors. To see the unique
values of one attribute use the extra_attr_values function.
Let’s see the values of the SIGNOR_mechanism attribute:
extra_attr_values(i, SIGNOR_mechanism)## [1] "phosphorylation" "binding"
## [3] "dephosphorylation" "Phosphorylation"
## [5] "ubiquitination" "N/A"
## [7] "Physical Interaction" "Proteolytic Processing"
## [9] "cleavage" "Ubiquitination"
## [11] "polyubiquitination" "deubiquitination"
## [13] "Deubiqitination" "relocalization"
## [15] "Dephosphorylation" "Other"
## [17] "guanine nucleotide exchange factor" "Transcription Regulation"
## [19] "gtpase-activating protein" "Indirect"
## [21] "" "sumoylation"
## [23] "Sumoylation" "palmitoylation"
## [25] "Acetylation" "acetylation"
## [27] "demethylation" "Demethylation"
## [29] "mRNA stability" "methylation"
## [31] "Methylation" "trimethylation"
## [33] "hydroxylation" "monoubiquitination"
## [35] "Deacetylation" "deacetylation"
## [37] "Translational Regulation" "Protein Degradation"
## [39] "Glycosylation" "s-nitrosylation"
## [41] "post transcriptional regulation" "phosphomotif_binding"
## [43] "chemical activation" "Proteolytic Cleavage"
## [45] "glycosylation" "Carboxylation"
## [47] "carboxylation" "ADP-ribosylation"
## [49] "catalytic activity" "neddylation"
## [51] "translation regulation" "tyrosination"
## [53] "post translational modification" "isomerization"
## [55] "desumoylation" "destabilization"
## [57] "chemical inhibition" "lipidation"
## [59] "deglycosylation" "chemical modification"
## [61] "stabilization" "oxidation"
## [63] "Neddylation" "Alkylation"
The values are provided as they are in the original resource, including potential typos and inconsistencies, e.g. see above the capitalized vs. lowercase forms of each value.
Converting extra attributes to columns
To make use of the attributes, it is convenient to extract the
interesting ones into separate columns of the data frame. With the
extra_attrs_to_cols function multiple attributes can be
converted in a single call. Custom column names can be passed by
argument names. As an example, let’s extract two attributes:
i0 <- extra_attrs_to_cols(
i,
si_mechanism = SIGNOR_mechanism,
ma_mechanism = Macrophage_type,
keep_empty = FALSE
)
dplyr::select(
i0,
source_genesymbol,
target_genesymbol,
si_mechanism,
ma_mechanism
)## # A tibble: 65,433 x 4
## source_genesymbol target_genesymbol si_mechanism ma_mechanism
## <chr> <chr> <list> <list>
## 1 PRKG1 TRPC3 <list [1]> <NULL>
## 2 FYN TRPC6 <list [1]> <NULL>
## 3 PRKG1 TRPC6 <list [1]> <NULL>
## 4 SRC TRPC6 <list [1]> <NULL>
## 5 PRKG1 TRPC7 <list [1]> <NULL>
## 6 CDK5 TRPV1 <list [1]> <NULL>
## 7 OS9 TRPV4 <list [1]> <NULL>
## 8 PTPN1 TRPV6 <list [1]> <NULL>
## 9 RACK1 TRPM6 <list [1]> <NULL>
## 10 TRPM6 TRPM7 <list [1]> <NULL>
## # i 65,423 more rows
Above we disabled the keep_empty option, otherwise the
new columns would have NULL values for most of the records,
simply because out of the 80k interactions in the data frame only a few
thousands are from either SIGNOR or Macrophage. The new columns are list
type, individual values are character vectors. Let’s look into one
value:
dplyr::pull(i0, si_mechanism)[[7]]## [[1]]
## [1] "binding"
Here we have two values, but only because the inconsistent names in the resource.
Depending on downstream methods, atomic columns might be preferable
instead of lists. In this case one interaction record might yield
multiple rows in the resulted data frame, depending on the number of
attributes it has. To have atomic columns, use the flatten
option:
i1 <- extra_attrs_to_cols(
i,
si_mechanism = SIGNOR_mechanism,
ma_mechanism = Macrophage_type,
keep_empty = FALSE,
flatten = TRUE
)
dplyr::select(
i1,
source_genesymbol,
target_genesymbol,
si_mechanism,
ma_mechanism
)## # A tibble: 67,704 x 4
## source_genesymbol target_genesymbol si_mechanism ma_mechanism
## <chr> <chr> <list> <list>
## 1 PRKG1 TRPC3 <chr [1]> <NULL>
## 2 FYN TRPC6 <chr [1]> <NULL>
## 3 PRKG1 TRPC6 <chr [1]> <NULL>
## 4 SRC TRPC6 <chr [1]> <NULL>
## 5 PRKG1 TRPC7 <chr [1]> <NULL>
## 6 CDK5 TRPV1 <chr [1]> <NULL>
## 7 OS9 TRPV4 <chr [1]> <NULL>
## 8 PTPN1 TRPV6 <chr [1]> <NULL>
## 9 RACK1 TRPM6 <chr [1]> <NULL>
## 10 TRPM6 TRPM7 <chr [1]> <NULL>
## # i 67,694 more rows
Filtering records based on extra attributes
Another useful application of extra attributes is filtering the
records of the interactions data frame. The
with_extra_attrs function filters to records which have
certain extra attributes. For example, to have only interactions with
SIGNOR_mechanism given:
nrow(with_extra_attrs(i, SIGNOR_mechanism))## [1] 65144
This results around 11 thousands rows. Filtering for multiple attributes the records which have at least one of them will be selected. Adding some more attributes results more interactions:
nrow(with_extra_attrs(i, SIGNOR_mechanism, CA1_effect, Li2012_mechanism))## [1] 66037
It is possible to filter the records not only by the names but the values of the extra attributes. Let’s select the interactions which are phosphorylation according to SIGNOR:
phos <- c('phosphorylation', 'Phosphorylation')
si_phos <- filter_extra_attrs(i, SIGNOR_mechanism = phos)
dplyr::select(si_phos, source_genesymbol, target_genesymbol)## # A tibble: 6,585 x 2
## source_genesymbol target_genesymbol
## <chr> <chr>
## 1 PRKG1 TRPC3
## 2 FYN TRPC6
## 3 PRKG1 TRPC6
## 4 SRC TRPC6
## 5 PRKG1 TRPC7
## 6 CDK5 TRPV1
## 7 TRPM6 TRPM7
## 8 PRKACA MCOLN1
## 9 MAPK14 MAPKAPK2
## 10 MAPKAPK2 HNRNPA0
## # i 6,575 more rows
Example: finding ubiquitination interactions
First let’s search for the word “ubiquitination” in the attributes. Below is a slow but simple solution:
keys <- extra_attrs(i)
keys_ubi <- purrr::keep(
keys,
function(k){
any(stringr::str_detect(extra_attr_values(i, !!k), 'biqu'))
}
)
keys_ubi## [1] "SIGNOR_mechanism" "HPRD-phos_mechanism" "SPIKE_mechanism"
## [4] "SPIKE_LC_mechanism" "CA1_type" "Macrophage_type"
We found five attributes that have at least one value which matches “biqu”. Next take a look at their values:
ubi <- rlang::set_names(
purrr::map(
keys_ubi,
function(k){
stringr::str_subset(extra_attr_values(i, !!k), 'biqu')
}
),
keys_ubi
)
ubi## $SIGNOR_mechanism
## [1] "ubiquitination" "Ubiquitination" "polyubiquitination"
## [4] "deubiquitination" "monoubiquitination"
##
## $`HPRD-phos_mechanism`
## [1] "Ubiquitination"
##
## $SPIKE_mechanism
## [1] "Ubiquitination" "Polyubiquitination"
##
## $SPIKE_LC_mechanism
## [1] "Ubiquitination" "Polyubiquitination"
##
## $CA1_type
## [1] "Ubiquitination"
##
## $Macrophage_type
## [1] "Ubiquitination"
Actually to match all ubiquitination interactions, it’s enough to filter for “ubiquitination” in its lowercase and capitalized forms (note, we could also include deubiqutination and polyubiquitination):
ubi_kws <- c('ubiquitination', 'Ubiquitination')
i_ubi <-
dplyr::distinct(
dplyr::bind_rows(
purrr::map(
keys_ubi,
function(k){
filter_extra_attrs(i, !!k := ubi_kws, na_ok = FALSE)
}
)
)
)
dplyr::select(i_ubi, source_genesymbol, target_genesymbol)## # A tibble: 49,709 x 2
## source_genesymbol target_genesymbol
## <chr> <chr>
## 1 NUMB NOTCH1
## 2 BTRC_CUL1_SKP1 PER2
## 3 PRKN SEPTIN5
## 4 PRKN RANBP2
## 5 PRKN SNCAIP
## 6 PRKN SNCA
## 7 FBXW7 MYC
## 8 MIB1 DAPK1
## 9 UBE2T FANCL
## 10 FANCL UBE2T
## # i 49,699 more rows
We found 405 ubiquitination interactions. We had to use
map, bind_rows and distinct
because otherwise filter_extra_attrs would return the
intersection of the matches, instead of their union.
In this data frame we have 150 unique ubiquitin E3 ligases:
## [1] 435
UniProt annotates E3 ligases by the “Ubl conjugation” keyword. We can check how many of those 150 proteins have this annotation:
uniprot_kws <- annotations(
resources = 'UniProt_keyword',
entity_type = 'protein',
wide = TRUE
)## Warning in readLines(con = path, encoding = encoding): incomplete final line
## found on 'https://omnipathdb.org/resources'
e3_ligases <- dplyr::pull(
dplyr::filter(uniprot_kws, keyword == 'Ubl conjugation'),
genesymbol
)
length(e3_ligases)## [1] 2738
## [1] 144
## [1] 291
We retrieved 2503 E3 ligases from UniProt. 83 of these has substrates in the interaction database, while 67 of the effectors of the interactions are not annotated in UniProt.
In the OmniPath enzyme-substrate database we collect ubiquitination interactions from enzyme-PTM resources. However, these contain only a small number of interactions:
es_ubi <- enzyme_substrate(types = 'ubiquitination')
es_ubi## # A tibble: 164 x 12
## enzyme substrate enzyme_genesymbol substrate_genesymbol residue_type
## <chr> <chr> <chr> <chr> <chr>
## 1 Q9Y385 Q92813 UBE2J1 DIO2 K
## 2 Q9Y385 Q92813 UBE2J1 DIO2 K
## 3 P38398 O75367 BRCA1 MACROH2A1 K
## 4 P63279 O75030 UBE2I MITF K
## 5 Q9UNE7 Q01860 STUB1 POU5F1 K
## 6 P63208 Q13426 SKP1 XRCC4 K
## 7 Q13616 Q13426 CUL1 XRCC4 K
## 8 Q969H0 Q13426 FBXW7 XRCC4 K
## 9 P63208 P35659 SKP1 DEK K
## 10 P63208 P35659 SKP1 DEK K
## # i 154 more rows
## # i 7 more variables: residue_offset <dbl>, modification <chr>, sources <chr>,
## # references <chr>, curation_effort <dbl>, n_references <int>,
## # n_resources <int>
With only two exception, all these have been recovered by using the extra attributes from the network database:
es_i_ubi <-
dplyr::inner_join(
es_ubi,
i_ubi,
by = c(
'enzyme_genesymbol' = 'source_genesymbol',
'substrate_genesymbol' = 'target_genesymbol'
)
)
nrow(dplyr::distinct(dplyr::select(es_i_ubi, enzyme, substrate, residue_offset)))## [1] 110
Session information
## R version 4.4.0 (2024-04-24)
## Platform: aarch64-apple-darwin20
## Running under: macOS 15.6.1
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
##
## locale:
## [1] C
##
## time zone: Asia/Shanghai
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] OmnipathR_3.19.1 BiocStyle_2.34.0
##
## loaded via a namespace (and not attached):
## [1] xfun_0.56 bslib_0.9.0 httr2_1.2.2
## [4] htmlwidgets_1.6.4 websocket_1.4.4 processx_3.8.6
## [7] tzdb_0.5.0 ps_1.9.1 vctrs_0.7.0
## [10] tools_4.4.0 generics_0.1.4 curl_7.0.0
## [13] tibble_3.3.1 RSQLite_2.4.5 blob_1.2.4
## [16] pkgconfig_2.0.3 R.oo_1.27.1 checkmate_2.3.3
## [19] desc_1.4.3 readxl_1.4.5 lifecycle_1.0.5
## [22] stringr_1.6.0 compiler_4.4.0 textshaping_1.0.4
## [25] progress_1.2.3 chromote_0.5.1 htmltools_0.5.9
## [28] sass_0.4.10 yaml_2.3.12 tidyr_1.3.2
## [31] pillar_1.11.1 pkgdown_2.1.3 later_1.4.5
## [34] crayon_1.5.3 jquerylib_0.1.4 R.utils_2.13.0
## [37] cachem_1.1.0 sessioninfo_1.2.3 zip_2.3.3
## [40] tidyselect_1.2.1 rvest_1.0.5 digest_0.6.39
## [43] stringi_1.8.7 dplyr_1.1.4 purrr_1.2.1
## [46] bookdown_0.44 fastmap_1.2.0 cli_3.6.5
## [49] logger_0.4.1 magrittr_2.0.4 utf8_1.2.6
## [52] XML_3.99-0.20 withr_3.0.2 readr_2.1.6
## [55] promises_1.5.0 prettyunits_1.2.0 backports_1.5.0
## [58] rappdirs_0.3.4 bit64_4.6.0-1 lubridate_1.9.4
## [61] timechange_0.3.0 rmarkdown_2.30 httr_1.4.7
## [64] igraph_2.2.1 bit_4.6.0 otel_0.2.0
## [67] cellranger_1.1.0 ragg_1.5.0 R.methodsS3_1.8.2
## [70] hms_1.1.4 memoise_2.0.1 evaluate_1.0.5
## [73] knitr_1.51 tcltk_4.4.0 rlang_1.1.7
## [76] Rcpp_1.1.1 glue_1.8.0 DBI_1.2.3
## [79] selectr_0.5-1 BiocManager_1.30.27 xml2_1.5.2
## [82] vroom_1.6.7 jsonlite_2.0.0 R6_2.6.1
## [85] systemfonts_1.3.1 fs_1.6.6