R/knnGraph.R

#' @include scTools.R
NULL

#' Execute the spRing algorithm
#'
#' \code{spRing} takes a matrix of samples X features and computes a
#' per-sample distance vector before selecting the k nearest neighbors.
#' This is done iteratively in \code{Rcpp} to minimize the memory
#' footprint while optimizing speed. Force directed layout is implemented
#' from \code{igraphs layout_with_drl} function. If either/both knngraph
#' or igraph is TRUE, this function will return an S3 object (list) with
#' the coordinates and either/both of these objects. Otherwise, a
#' two dimensional vector specifying the coordinates will be returned.
#'
#' @param x Data matrix
#' @param k = 10
#' @param method = "pearson" The distance metric for the data.
#' @param knngraph = FALSE Return knn graph generated by the data?
#' @param igraph = FALSE Return igraph network associated with knn graph?
#'
#' @return One or more outputs. See above
#' @importFrom igraph graph_from_adjacency_matrix layout_with_drl get.adjacency
#' @examples
#' x <- matrix(rnorm(100), nrow = 20) # 20 samples
#' coords <- spRing(x, k = 2, method = "euclidean")
#' # plot(coords)

#' @export
setGeneric(name = "spRing", def = function(x, k = 10, method = "pearson", knngraph = FALSE, igraph = FALSE)
    standardGeneric("spRing"))

#' @rdname spRing
setMethod("spRing", signature("ANY", "numeric", "ANY", "ANY", "ANY"),
          definition = function(x, k = 10, method = "pearson", knngraph = FALSE, igraph = FALSE) {

          stopifnot(method %in% c("euclidean", "pearson"))
          stopifnot(dim(x)[1] > k)
          stopifnot(k > 1)
          if(method == "pearson"){
            knng <- calcKNNgraph_pearson(x, k)
          } else if (method == "euclidean"){
            knng <- calcKNNgraph_euclidean(x, k)
          }
          mat <- cbind(rep(knng[,1], k - 1),as.numeric(knng[,-1]))
          igraphObj <- igraph::graph_from_adjacency_matrix(igraph::get.adjacency(igraph::graph.edgelist(mat, directed=TRUE)), mode = "directed")
          l <- igraph::layout_with_drl(igraphObj, options=list(simmer.attraction=0))
          if(knngraph | igraph){
            outList <- list()
            outList[["coordinates"]] <- l
            if(knngraph) outList[["knngraph"]] <- knng
            if(igraph) outList[["igraph"]] <- igraphObj
            return(outList)
          } else {
            return(l)
          }
})
caleblareau/scTools documentation built on May 13, 2019, 11:01 a.m.