rsparse-matrixigraphadjacency-matrix

How to convert a graph into a sparse adjacency matrix having a given type (other then "dgCMatrix")


How to convert a graph to a sparse ‘dgTmatrix’ in one step?

library(igraph)
library(Matrix)
g <- make_ring(5)
adj <- as_adjacency_matrix(g, sparse = TRUE)
class(adj)
# [1] "dgCMatrix"
# attr(,"package")
# [1] "Matrix"

How to specify a matrix class other then "dgCMatrix", which seem to be the default?

adt <- as(adj, "TsparseMatrix")
class(adt)
# [1] "dgTMatrix"
# attr(,"package")
# [1] "Matrix"
cbind(adt@i, adt@j, adt@x)

I tried: class(as_adj(g, type="both", igraph_opt("dgTMatrix"))) but this creates a "dgCMatrix".

Update
If really needed then making a private copy of get.adjacency.sparse() would be an option.


Solution

  • I think it is hard-coded in its source code, you may not be able to annotate it from the inside

    get.adjacency.sparse <- function(graph, type = c("both", "upper", "lower"),
                                     attr = NULL, edges = FALSE, names = TRUE) {
      ensure_igraph(graph)
    
      type <- igraph.match.arg(type)
    
      vc <- vcount(graph)
    
      el <- as_edgelist(graph, names = FALSE)
      use.last.ij <- FALSE
    
      if (edges) {
        value <- seq_len(nrow(el))
        use.last.ij <- TRUE
      } else if (!is.null(attr)) {
        attr <- as.character(attr)
        if (!attr %in% edge_attr_names(graph)) {
          stop("no such edge attribute")
        }
        value <- edge_attr(graph, name = attr)
        if (!is.numeric(value) && !is.logical(value)) {
          stop(
            "Sparse matrices must be either numeric or logical,",
            "and the edge attribute is not"
          )
        }
      } else {
        value <- rep(1, nrow(el))
      }
    
      if (is_directed(graph)) {
        res <- Matrix::sparseMatrix(dims = c(vc, vc), i = el[, 1], j = el[, 2], x = value, use.last.ij = use.last.ij)
      } else {
        if (type == "upper") {
          ## upper
          res <- Matrix::sparseMatrix(
            dims = c(vc, vc), i = pmin(el[, 1], el[, 2]),
            j = pmax(el[, 1], el[, 2]), x = value, use.last.ij = use.last.ij
          )
        } else if (type == "lower") {
          ## lower
          res <- Matrix::sparseMatrix(
            dims = c(vc, vc), i = pmax(el[, 1], el[, 2]),
            j = pmin(el[, 1], el[, 2]), x = value, use.last.ij = use.last.ij
          )
        } else if (type == "both") {
          ## both
          res <- Matrix::sparseMatrix(
            dims = c(vc, vc), i = pmin(el[, 1], el[, 2]),
            j = pmax(el[, 1], el[, 2]), x = value, symmetric = TRUE, use.last.ij = use.last.ij
          )
          res <- as(res, "generalMatrix")
        }
      }
    
      if (names && "name" %in% vertex_attr_names(graph)) {
        colnames(res) <- rownames(res) <- V(graph)$name
      }
    
      res
    }