R/ontology.R

Defines functions relations_list_to_table relations_table_to_list

Documented in relations_list_to_table relations_table_to_list

#!/usr/bin/env Rscript

#
#  This file is part of the `OmnipathR` R package
#
#  Copyright
#  2018-2024
#  Saez Lab, Uniklinik RWTH Aachen, Heidelberg University
#
#  File author(s): Alberto Valdeolivas
#                  Dénes Türei (turei.denes@gmail.com)
#                  Attila Gábor
#
#  Distributed under the MIT (Expat) License.
#  See accompanying file `LICENSE` or find a copy at
#      https://directory.fsf.org/wiki/License:Expat
#
#  Website: https://r.omnipathdb.org/
#  Git repo: https://github.com/saezlab/OmnipathR
#


#' Nested list from a table of ontology relations
#'
#' @param relations A data frame of ontology relations (the "relations"
#'     element of the list returned by \code{\link{obo_parser}} in case
#'     its argument `tables` is \code{TRUE}).
#'
#' @return The relations converted to a nested list.
#'
#' @examples
#' goslim_url <-
#'     "http://current.geneontology.org/ontology/subsets/goslim_generic.obo"
#' path <- tempfile()
#' httr::GET(goslim_url, httr::write_disk(path, overwrite = TRUE))
#' obo <- obo_parser(path, tables = TRUE)
#' unlink(path)
#' rel_list <- relations_table_to_list(obo$relations)
#'
#' @importFrom magrittr %>%
#' @importFrom rlang !! sym set_names
#' @importFrom tidyr chop replace_na
#' @importFrom purrr map2
#' @importFrom dplyr mutate
#' @importFrom logger log_trace
#'
#' @export
#'
#' @seealso \itemize{
#'     \item{\code{\link{relations_list_to_table}}}
#'     \item{\code{\link{swap_relations}}}
#'     \item{\code{\link{obo_parser}}}
#' }
relations_table_to_list <- function(relations){

    # NSE vs. R CMD check workaround
    relation <- NULL

    direction <- c('parents', 'children')
    to_str <-
        intersect(names(relations), direction)[1] %>%
        replace_na('side2')
    to_sym <- sym(to_str)
    direction <- `if`(
        to_str == 'parents',
        direction,
        `if`(
            to_str == 'children',
            rev(direction),
            NULL
        )
    )

    log_trace('Converting ontology relations from table to list.')

    relations %>%
    chop(c('relation', to_str)) %>%
    mutate(value = map2(!!to_sym, relation, set_names)) %>%
    term_value_list %>%
    `attr<-`('direction', direction)

}


#' Table from a nested list of ontology relations
#'
#' Converting the nested list to a table is a more costly operation, it takes
#' a few seconds. Best to do it only once, or pass \code{tables = TRUE} to
#' \code{\link{obo_parser}}, and convert the data frame to list, if you
#' also need it in list format.
#'
#' @param relations A nested list of ontology relations (the "relations"
#'     element of the list returned by \code{\link{obo_parser}} in case
#'     its argument `tables` is \code{FALSE}).
#' @param direction Override the direction (i.e. child -> parents or parent
#'     -> children). The nested lists produced by functions in the current
#'     package add an attribute "direction" thus no need to pass this value.
#'     If the attribute and the argument are both missing, the column will
#'     be named simply "side2" and it won't be clear whether the relations
#'     point from "term" to "side2" or the other way around. The direction
#'     should be a character vector of length 2 with the values "parents"
#'     and "children".
#'
#' @return The relations converted to a data frame (tibble).
#'
#' @examples
#' goslim_url <-
#'     "http://current.geneontology.org/ontology/subsets/goslim_generic.obo"
#' path <- tempfile()
#' httr::GET(goslim_url, httr::write_disk(path, overwrite = TRUE))
#' obo <- obo_parser(path, tables = FALSE)
#' unlink(path)
#' rel_tbl <- relations_list_to_table(obo$relations)
#'
#' @importFrom magrittr %>%
#' @importFrom rlang !! sym %||%
#' @importFrom tibble tibble
#' @importFrom dplyr mutate
#' @importFrom tidyr unnest_longer
#' @importFrom logger log_trace
#'
#' @export
#'
#' @seealso \itemize{
#'     \item{\code{\link{swap_relations}}}
#'     \item{\code{\link{relations_table_to_list}}}
#'     \item{\code{\link{obo_parser}}}
#' }
relations_list_to_table <- function(relations, direction = NULL){

    # NSE vs. R CMD check workaround
    rel <- term <- relation <- NULL

    direction <-
        direction %||%
        attr(relations, 'direction') %||%
        c('side1', 'side2')
    to_str <- direction[2]
    to_sym <- sym(to_str)

    log_trace('Converting ontology relations from list to table.')

    relations %>%
    tibble(rel = .) %>%
    mutate(term = names(rel)) %>%
    unnest_longer(
        rel,
        values_to = to_str,
        indices_to = 'relation'
    ) %>%
    select(term, relation, !!to_sym)

}


#' Graph from a table of ontology relations
#'
#' @param relations A data frame of ontology relations (the "relations"
#'     element of the list returned by \code{\link{obo_parser}} in case
#'     its argument `tables` is \code{TRUE}).
#'
#' @return The relations converted to an igraph graph object.
#'
#' @details
#' By default the relations point from child to parents, the edges in the
#' graph will be of the same direction. Use \code{\link{swap_relations}}
#' on the data frame to reverse the direction.
#'
#' @examples
#' \dontrun{
#' go <- get_db('go_basic')
#' go_graph <- relations_table_to_graph(go$relations)
#' }
#'
#' @importFrom logger log_trace
#' @importFrom magrittr %>%
#' @importFrom dplyr rename
#' @importFrom tidyr unnest
#' @importFrom igraph graph_from_data_frame
#' @export
relations_table_to_graph <- function(relations){

    .slow_doctest()

    # NSE vs. R CMD check workaround
    term2 <- term <- relation <- NULL

    log_trace('Converting ontology relations from table to graph.')

    relations %>%
    rename(term2 = 3) %>%
    unnest(term2) %>%
    select(term, term2, relation) %>%
    graph_from_data_frame

}


#' Reverse the direction of ontology relations
#'
#' @param relations The `relations` component of the data returned by
#'     \code{\link{obo_parser}} or any `...ontology_download` function
#'     such as \code{\link{go_ontology_download}}. Depending on the
#'     \code{tables} argument of those functions the `relations` can be
#'     a data frame or a nested list.
#'
#' @return Same type as the input, but the relations swapped: if in the input
#'     these pointed from each child to the parents, in the output they
#'     point from each parent to their children, and vice versa.
#'
#' @examples
#' goslim_url <-
#'     "http://current.geneontology.org/ontology/subsets/goslim_generic.obo"
#' path <- tempfile()
#' httr::GET(goslim_url, httr::write_disk(path, overwrite = TRUE))
#' obo <- obo_parser(path)
#' unlink(path)
#' rel_swapped <- swap_relations(obo$relations)
#'
#' @importFrom magrittr %>%
#' @importFrom rlang sym !! :=
#' @importFrom dplyr select summarize group_by
#' @importFrom tidyr unnest
#' @importFrom logger log_fatal log_trace
#'
#' @export
#'
#' @seealso \itemize{
#'     \item{\code{\link{relations_list_to_table}}}
#'     \item{\code{\link{relations_table_to_list}}}
#'     \item{\code{\link{obo_parser}}}
#' }
swap_relations <- function(relations){

    # NSE vs. R CMD check workaround
    relation <- term <- NULL

    dfclass <- inherits(relations, 'data.frame')

    if(dfclass){
        if('parents' %in% names(relations)){
            c_in <- sym('parents')
            c_out <- sym('children')
        }else if('children' %in% names(relations)){
            c_in <- sym('children')
            c_out <- sym('parents')
        }else if('side2' %in% names(relations)){
            c_in <- sym('side2')
            c_out <- sym('side2')
        }else{
            msg <- paste0(
                'swap_relations: the input data frame must have one of the ',
                'following columns: "parents", "children" or "side2".'
            )
            log_fatal(msg)
            stop(msg)
        }
    }

    log_trace('Swapping direction of ontology relations.')

    `if`(
        dfclass,
        relations %>%
            unnest(!!c_in) %>%
            group_by(!!c_in, relation) %>%
            summarize(term = list(term), .groups = 'drop') %>%
            select(term = !!c_in, relation, !!c_out := term),
        relations %>%
            relations_list_to_table() %>%
            swap_relations() %>%
            relations_table_to_list()
    )

}


#' Creates an igraph object which helps to control transformations of
#' ontology relation data structures
#'
#' @importFrom igraph graph_from_literal as.directed V E V<- E<-
#' @importFrom igraph get.edgelist delete_edges
#' @importFrom purrr pmap_chr
#' @importFrom stringr str_sub
#' @importFrom magrittr %>% %<>%
#' @importFrom tibble as_tibble
#'
#' @noRd
get_ontology_db_variants_graph <- function(){

    # NSE vs. R CMD check workaround
    rel_tbl_c2p <- rel_tbl_p2c <- rel_lst_c2p <-
    rel_lst_p2c <- rel_gra_c2p <- rel_gra_p2c <- NULL

    g <-
        graph_from_literal(
            rel_tbl_c2p-rel_tbl_p2c,
            rel_tbl_c2p-rel_lst_c2p,
            rel_tbl_p2c-rel_lst_p2c,
            rel_tbl_c2p-rel_gra_c2p,
            rel_tbl_p2c-rel_gra_p2c
        ) %>%
        as.directed

    V(g)$fmt <- str_sub(V(g)$name, 5, 7)
    V(g)$c2p <- grepl('c2p', V(g)$name)
    E(g)$fun <-
        g %>%
        get.edgelist %>%
        `colnames<-`(c('from', 'to')) %>%
        as_tibble %>%
        pmap_chr(
            function(from, to){
                if(str_sub(from, -3) != str_sub(to, -3)){
                    'swap_relations'
                }else if(
                    str_sub(from, 5, 7) == 'tbl' &&
                    str_sub(to, 5, 7) == 'lst'
                ){
                    'relations_table_to_list'
                }else if(
                    str_sub(from, 5, 7) == 'lst' &&
                    str_sub(to, 5, 7) == 'tbl'
                ){
                    'relations_list_to_table'
                }else if(
                    str_sub(from, 5, 7) == 'tbl' &&
                    str_sub(to, 5, 7) == 'gra'
                ){
                    'relations_table_to_graph'
                }else(
                    NA
                )
            }
        )

    g %<>% delete_edges(E(g)$fun %>% is.na %>% which)

    E(g)$weight <-
        ifelse(E(g)$fun == 'swap_relations', 1, 2)

    return(g)

}


.ontology_db_variants_graph <- get_ontology_db_variants_graph()


#' Finds the most efficient way to transform ontology relationships into the
#' desired format
#'
#' @param db An ontology database (as produced by \code{\link{obo_parser}}
#'     and accessed by \code{\link{get_db}}.
#' @param fmt Character: the data structure should be 1) "tbl" a data frame,
#'     2) "lst" a list or 3) "gra" a graph.
#' @param c2p Logical: the data structure should contain child-to-parents
#'     (\code{TRUE}) or parent-to-children (\code{FALSE}) relations.
#'
#'
#' @return A list with the following elements: "operations" character
#'     vector with the function names; "start" name of the starting data
#'     structure; "end" name of the target data structure. Note: if the
#'     target data structure already exists "operations" a zero length
#'     vector.
#'
#' @importFrom magrittr %>% equals extract
#' @importFrom igraph V shortest_paths degree
#' @importFrom purrr map_dbl
#'
#' @noRd
ontology_db_transformations <- function(db, fmt, c2p){

    g <- .ontology_db_variants_graph

    to <- (V(g)$fmt == fmt & V(g)$c2p == c2p) %>% which
    from <-
        setdiff(
            V(g)$name %in% names(db) %>% which,
            setdiff(
                g %>% degree(mode = 'out') %>% equals(0L) %>% which,
                # `to` must can stay in the set,
                # even if it has no outgoing edges
                to
            )
        )

    paths <- shortest_paths(g, to, from, mode = 'in', output = 'both')
    idx <- paths$epath %>% map_dbl(function(e){sum(e$weight)}) %>% which.min

    operations <- paths$epath[[idx]]$fun %>% rev
    start <- paths$vpath[[idx]] %>% rev %>% extract(1L) %>% `$`('name')
    end <- paths$vpath[[idx]] %>% extract(1L) %>% `$`('name')

    list(
        operations = operations,
        start = start,
        end = end
    )

}


#' Access an ontology database
#'
#' Retrieves an ontology database with relations in the desired data
#' structure. The database is automatically loaded and the requested data
#' structure is constructed if necessary. The databases stay loaded up to a
#' certain time period (see the option \code{omnipath.db_lifetime}). Hence
#' the first one of repeated calls to this function might take long and the
#' subsequent ones should be really quick.
#'
#' @param key Character: key of the ontology database. For the available keys
#'     see \code{\link{omnipath_show_db}}.
#' @param rel_fmt Character: the data structure of the ontology relations.
#'     Posible values are 1) "tbl" a data frame, 2) "lst" a list or 3) "gra"
#'     a graph.
#' @param child_parents Logical: whether the ontology relations should point
#'     from child to parents (\code{TRUE}) or from parent to children
#'     (\code{FALSE}).
#'
#' @return A list with the following elements: 1) "names" a table with
#'     term IDs and names; 2) "namespaces" a table to connect term IDs
#'     and namespaces they belong to; 3) "relations" a table with
#'     relations between terms and their parent terms; 4) "subsets" a
#'     table with terms and the subsets they are part of; 5) "obsolete"
#'     character vector with all the terms labeled as obsolete.
#'
#' @examples
#' go <- get_ontology_db('go_basic', child_parents = FALSE)
#'
#' @importFrom magrittr %<>%
#' @importFrom igraph V
#' @export
#' @seealso \itemize{
#'     \item{\code{\link{omnipath_show_db}}}
#'     \item{\code{\link{get_db}}}
#' }
get_ontology_db <- function(key, rel_fmt = 'tbl', child_parents = TRUE){

    .slow_doctest()

    db <- get_db(key)

    transf <- ontology_db_transformations(db, rel_fmt, child_parents)

    relations <- db[[transf$start]]

    for(op in transf$operations){

        relations %<>% (get(op))

    }

    db[[transf$end]] <- relations

    if(rel_fmt == 'gra'){

        db[[sprintf('%s_v', transf$end)]] <- V(relations)

    }

    omnipath.env$db[[key]]$db <- db

    get_db(key)

}


#' All nodes of a subtree starting from the selected nodes
#'
#' Starting from the selected nodes, recursively walks the ontology tree
#' until it reaches either the root or leaf nodes. Collects all visited
#' nodes.
#'
#' @param terms Character vector of ontology term IDs or names. A mixture of
#'     IDs and names can be provided.
#' @param ancestors Logical: if \code{FALSE} the ontology tree is traversed
#'     towards the leaf nodes; if \code{TRUE}, the tree is traversed until
#'     the root. The former returns the ancestors (parents), the latter
#'     the descendants (children).
#' @param db_key Character: key to identify the ontology database. For the
#'     available keys see \code{\link{omnipath_show_db}}.
#' @param ids Logical: whether to return IDs or term names.
#' @param method Character: either "gra" or "lst". The implementation to use
#'     for traversing the ontology tree. The graph based implementation is
#'     faster than the list based, the latter will be removed in the future.
#' @param relations Character vector of ontology relation types. Only these
#'     relations will be used.
#'
#' @return Character vector of ontology IDs. If the input terms are all
#'     leaves or roots \code{NULL} is returned. The starting nodes won't
#'     be included in the result unless they fall onto the traversal path
#'     from other nodes.
#'
#' @details
#' Note: this function relies on the database manager, the first call might
#' take long because of the database load process. Subsequent calls within
#' a short period should be faster. See \code{\link{get_ontology_db}}.
#'
#' @examples
#' walk_ontology_tree(c('GO:0006241', 'GO:0044211'))
#' # [1] "GO:0006139" "GO:0006220" "GO:0006221" "GO:0006241" "GO:0006725"
#' # [6] "GO:0006753" "GO:0006793" "GO:0006796" "GO:0006807" "GO:0008150"
#' # ... (truncated)
#' walk_ontology_tree(c('GO:0006241', 'GO:0044211'), ancestors = FALSE)
#' # [1] "GO:0044210" "GO:0044211"
#' walk_ontology_tree(
#'     c('GO:0006241', 'GO:0044211'),
#'     ancestors = FALSE,
#'     ids = FALSE
#' )
#' # [1] "'de novo' CTP biosynthetic process" "CTP salvage"
#'
#' @importFrom magrittr %>% %<>%
#' @importFrom igraph delete_edges
#' @export
#' @seealso \itemize{
#'     \item{\code{\link{omnipath_show_db}}}
#'     \item{\code{\link{get_ontology_db}}}
#' }
walk_ontology_tree <- function(
    terms,
    ancestors = TRUE,
    db_key = 'go_basic',
    ids = TRUE,
    method = 'gra',
    relations = c(
        'is_a', 'part_of', 'occurs_in', 'regulates',
        'positively_regulates', 'negatively_regulates'
    )
){

    .slow_doctest()

    db <- get_ontology_db(
        key = db_key,
        rel_fmt = method,
        child_parents = ancestors
    )

    rel_key <- `if`(ancestors, 'rel_gra_c2p', 'rel_gra_p2c')

    rel <- db[[rel_key]]

    if(method == 'gra'){

        rel %<>%
            delete_edges(
                E(rel)$relation %in% relations %>% `!` %>% which
            )

    }

    terms %<>% ontology_ensure_id(db_key = db_key)

    fun <- `if`(
        method == 'gra',
        .walk_ontology_tree_graph,
        .walk_ontology_tree
    )

    fun(terms, rel, relations) %>%
    ontology_name_id(ids = ids, db_key = db_key)

}


#' See \code{\link{walk_ontology_tree}}
#'
#' @importFrom igraph V ego
#' @importFrom stats na.omit
#' @noRd
.walk_ontology_tree_graph <- function(terms, rel, relations){

    V(rel)[terms, na_ok = TRUE] %>%
    na.omit %>%
    {ego(rel, order = 16, nodes = ., mode = 'out')} %>%
    unlist %>%
    names %>%
    unique

}


#' See \code{\link{walk_ontology_tree}}
#'
#' @importFrom magrittr %>% %<>%
#' @importFrom purrr map
#' @noRd
.walk_ontology_tree <- function(
    terms,
    rel,
    relations
){

    if(length(terms) == 1L){

        if(!terms %in% names(rel)){

            return(NULL)

        }else{

            related_terms <- rel[[terms]][relations] %>% unlist
            c(
                related_terms,
                rel %>% names %>% intersect(related_terms) %>%
                .walk_ontology_tree(rel = rel, relations = relations)
            ) %>%
            unname %>%
            unique

        }

    }else{

        terms %>% map(
            .walk_ontology_tree,
            rel = rel,
            relations = relations
        ) %>%
        unlist %>%
        unique

    }

}


#' All descendants in the ontology tree
#'
#' Starting from the selected nodes, recursively walks the ontology tree
#' until it reaches the leaf nodes. Collects all visited nodes, which are
#' the descendants (children) of the starting nodes.
#'
#' @param terms Character vector of ontology term IDs or names. A mixture of
#'     IDs and names can be provided.
#' @param db_key Character: key to identify the ontology database. For the
#'     available keys see \code{\link{omnipath_show_db}}.
#' @param ids Logical: whether to return IDs or term names.
#' @param relations Character vector of ontology relation types. Only these
#'     relations will be used.
#'
#' @return Character vector of ontology IDs. If the input terms are all
#'     leaves \code{NULL} is returned. The starting nodes won't be included
#'     in the result unless some of them are descendants of other starting
#'     nodes.
#'
#' @details
#' Note: this function relies on the database manager, the first call might
#' take long because of the database load process. Subsequent calls within
#' a short period should be faster. See \code{\link{get_ontology_db}}.
#'
#' @examples
#' descendants('GO:0005035', ids = FALSE)
#' # [1] "tumor necrosis factor-activated receptor activity"
#' # [2] "TRAIL receptor activity"
#' # [3] "TNFSF11 receptor activity"
#'
#' @importFrom rlang exec !!!
#' @export
descendants <- function(
    terms,
    db_key = 'go_basic',
    ids = TRUE,
    relations = c(
        'is_a', 'part_of', 'occurs_in', 'regulates',
        'positively_regulates', 'negatively_regulates'
    )
){

    .slow_doctest()

    exec(walk_ontology_tree, ancestors = FALSE, !!!as.list(environment()))

}


#' All ancestors in the ontology tree
#'
#' Starting from the selected nodes, recursively walks the ontology tree
#' until it reaches the root. Collects all visited nodes, which are the
#' ancestors (parents) of the starting nodes.
#'
#' @param terms Character vector of ontology term IDs or names. A mixture of
#'     IDs and names can be provided.
#' @param db_key Character: key to identify the ontology database. For the
#'     available keys see \code{\link{omnipath_show_db}}.
#' @param ids Logical: whether to return IDs or term names.
#' @param relations Character vector of ontology relation types. Only these
#'     relations will be used.
#'
#' @return Character vector of ontology IDs. If the input terms are all
#'     root nodes, \code{NULL} is returned. The starting nodes won't be
#'     included in the result unless some of them are ancestors of other
#'     starting nodes.
#'
#' @details
#' Note: this function relies on the database manager, the first call might
#' take long because of the database load process. Subsequent calls within
#' a short period should be faster. See \code{\link{get_ontology_db}}.
#'
#' @examples
#' ancestors('GO:0005035', ids = FALSE)
#' # [1] "molecular_function"
#' # [2] "transmembrane signaling receptor activity"
#' # [3] "signaling receptor activity"
#' # [4] "molecular transducer activity"
#'
#' @importFrom rlang exec !!!
#' @export
ancestors <- function(
    terms,
    db_key = 'go_basic',
    ids = TRUE,
    relations = c(
        'is_a', 'part_of', 'occurs_in', 'regulates',
        'positively_regulates', 'negatively_regulates'
    )
){

    .slow_doctest()

    exec(walk_ontology_tree, ancestors = TRUE, !!!as.list(environment()))

}


#' Translate between ontology IDs and names
#'
#' Makes sure that the output contains only valid IDs or term names. The
#' input can be a mixture of IDs and names. The order of the input won't
#' be preserved in the output.
#'
#' @param terms Character: ontology IDs or term names.
#' @param ids Logical: the output should contain IDs or term names.
#' @param db_key Character: key to identify the ontology database. For the
#'     available keys see \code{\link{omnipath_show_db}}.
#'
#' @return Character vector of ontology IDs or term names.
#'
#' @examples
#' ontology_name_id(c('mitochondrion inheritance', 'reproduction'))
#' # [1] "GO:0000001" "GO:0000003"
#' ontology_name_id(c('GO:0000001', 'reproduction'), ids = FALSE)
#' # [1] "mitochondrion inheritance" "reproduction"
#'
#' @importFrom magrittr %>%
#' @importFrom dplyr filter pull
#' @importFrom rlang !! sym
#' @importFrom tibble tibble
#' @export
ontology_name_id <- function(terms, ids = TRUE, db_key = 'go_basic'){

    .slow_doctest()

    db <- get_db(db_key)
    to_col <- `if`(ids, 'term', 'name')
    from_col <- `if`(ids, 'name', 'term')

    id_name <- `if`(
        inherits(db$names, 'data.frame'),
        db$names,
        db$names %>% {tibble(term = names(.), name = unlist(.))}
    )

    id_name %>%
    filter(!!sym(from_col) %in% terms) %>%
    pull(!!sym(to_col)) %>%
    union(
        id_name %>%
        pull(!!sym(to_col)) %>%
        intersect(terms)
    )

}


#' Only ontology IDs
#'
#' Converts a mixture of ontology IDs and names to only IDs. If an element
#' of the input is missing from the chosen ontology it will be dropped.
#' This can happen if the ontology is a subset (slim) version, but also if
#' the input is not a valid ID or name.
#'
#' @param terms Character: ontology IDs or term names.
#' @param db_key Character: key to identify the ontology database. For the
#'     available keys see \code{\link{omnipath_show_db}}.
#'
#' @return Character vector of ontology IDs.
#'
#' @examples
#' ontology_ensure_id(c('mitochondrion inheritance', 'GO:0001754'))
#' # [1] "GO:0000001" "GO:0001754"
#'
#' @export
ontology_ensure_id <- function(terms, db_key = 'go_basic'){

    .slow_doctest()

    ontology_name_id(terms, db_key = db_key)

}


#' Only ontology term names
#'
#' Converts a mixture of ontology IDs and names to only names. If an element
#' of the input is missing from the chosen ontology it will be dropped.
#' This can happen if the ontology is a subset (slim) version, but also if
#' the input is not a valid ID or name.
#'
#' @param terms Character: ontology IDs or term names.
#' @param db_key Character: key to identify the ontology database. For the
#'     available keys see \code{\link{omnipath_show_db}}.
#'
#' @return Character vector of ontology term names.
#'
#' @examples
#' ontology_ensure_name(c('reproduction', 'GO:0001754', 'foo bar'))
#' # [1] "eye photoreceptor cell differentiation" "reproduction"
#'
#' @export
ontology_ensure_name <- function(terms, db_key = 'go_basic'){

    .slow_doctest()

    ontology_name_id(terms, ids = FALSE, db_key = db_key)

}


#' Looks like an ontology ID
#'
#' Tells if the input has the typical format of ontology IDs, i.e. a code
#' of capital letters, a colon, followed by a numeric code.
#'
#' @param terms Character vector with strings to check.
#'
#' @return A logical vector with the same length as the input.
#'
#' @examples
#' is_ontology_id(c('GO:0000001', 'reproduction'))
#' # [1]  TRUE FALSE
#'
#' @export
is_ontology_id <- function(terms){

    grepl('^[A-Z]+:[0-9]+$', terms)

}
saezlab/OmnipathR documentation built on May 3, 2024, 5:32 a.m.