You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将图转换为指定类型(非dgCMatrix)的稀疏邻接矩阵?

igraph转换为指定类型稀疏邻接矩阵的解决方案

问题1:如何将图转换为dgCMatrix以外指定类型的稀疏邻接矩阵?

igraph的as_adjacency_matrix()(或简写as_adj())在设置sparse=TRUE时,默认返回dgCMatrix类型的稀疏矩阵。要得到其他稀疏矩阵类型,有两种可行方式:

方式1:先获取dgCMatrix再转换

先通过默认方法得到dgCMatrix,再用Matrix包的as()函数转换为目标类型,比如转换为dgRMatrix(行稀疏矩阵):

library(igraph)
library(Matrix)

# 创建示例图
g <- make_ring(5)
# 获取默认的dgCMatrix
adj_c <- as_adjacency_matrix(g, sparse = TRUE)
# 转换为dgRMatrix
adj_r <- as(adj_c, "RsparseMatrix")
class(adj_r)
# [1] "dgRMatrix"
# attr(,"package")
# [1] "Matrix"

方式2:自定义函数直接生成目标类型

如果需要一步生成,可复制igraph内部的get.adjacency.sparse()函数并修改,直接输出指定类型的稀疏矩阵。比如修改后直接返回dgTMatrix:

# 复制并修改igraph的get.adjacency.sparse函数
get_adjacency_dgT <- function(graph, type = c("both", "upper", "lower", "plus"),
                             attr = NULL, edges = TRUE, names = TRUE,
                             binary = FALSE, sparse = TRUE) {
  type <- match.arg(type)
  if (!igraph::is_igraph(graph)) {
    stop("Not a graph object")
  }
  n <- igraph::vcount(graph)
  if (is.null(attr)) {
    if (edges) {
      el <- igraph::get.edgelist(graph, names = FALSE)
      if (type == "upper") {
        el <- el[el[, 1] < el[, 2], , drop = FALSE]
      } else if (type == "lower") {
        el <- el[el[, 1] > el[, 2], , drop = FALSE]
      } else if (type == "plus") {
        el <- rbind(el, cbind(el[, 2], el[, 1]))
      }
      x <- rep(1, nrow(el))
      if (!binary && !igraph::is_directed(graph) && type == "both") {
        x <- c(x, x)
        el <- rbind(el, cbind(el[, 2], el[, 1]))
      }
    } else {
      el <- matrix(integer(0), ncol = 2)
      x <- numeric(0)
    }
  } else {
    el <- igraph::get.edgelist(graph, names = FALSE)
    x <- igraph::get.edge.attribute(graph, attr)
    if (!is.numeric(x)) {
      stop("Edge attribute must be numeric")
    }
    if (type == "upper") {
      keep <- el[, 1] < el[, 2]
      el <- el[keep, , drop = FALSE]
      x <- x[keep]
    } else if (type == "lower") {
      keep <- el[, 1] > el[, 2]
      el <- el[keep, , drop = FALSE]
      x <- x[keep]
    } else if (type == "plus") {
      el <- rbind(el, cbind(el[, 2], el[, 1]))
      x <- c(x, x)
    } else if (!igraph::is_directed(graph)) {
      el <- rbind(el, cbind(el[, 2], el[, 1]))
      x <- c(x, x)
    }
  }
  # 关键修改:直接构造dgTMatrix
  mat <- Matrix::sparseMatrix(i = el[, 1], j = el[, 2], x = x,
                              dims = c(n, n), giveCsparse = FALSE)
  if (names) {
    dn <- list(igraph::V(graph)$name, igraph::V(graph)$name)
    dimnames(mat) <- dn
  }
  mat
}

# 使用自定义函数一步得到dgTMatrix
adj_t <- get_adjacency_dgT(g, type = "both")
class(adj_t)
# [1] "dgTMatrix"
# attr(,"package")
# [1] "Matrix"

问题2:如何一步将图转换为稀疏dgTMatrix?

除了上面自定义函数的方式,也可以通过直接构造稀疏矩阵的方式一步实现:

方法1:基于边列表直接构造dgTMatrix

直接从图的边列表出发,用sparseMatrix()函数并指定giveCsparse=FALSE来生成dgTMatrix:

library(igraph)
library(Matrix)

g <- make_ring(5)
# 获取边列表(不含顶点名称)
el <- get.edgelist(g, names = FALSE)
# 处理无向图的双向边(如果需要type="both")
if (!is_directed(g)) {
  el <- rbind(el, cbind(el[,2], el[,1]))
}
# 构造dgTMatrix
adj_t <- sparseMatrix(i = el[,1], j = el[,2], x = 1, dims = c(vcount(g), vcount(g)), giveCsparse = FALSE)
class(adj_t)
# [1] "dgTMatrix"
# attr(,"package")
# [1] "Matrix"
# 若需要顶点名称,可添加dimnames
dimnames(adj_t) <- list(V(g)$name, V(g)$name)

方法2:使用修改后的自定义函数

即前面问题1中提到的get_adjacency_dgT()函数,调用后可一步得到dgTMatrix,同时支持边属性、类型选择等参数,功能更贴近原生as_adjacency_matrix()。


内容的提问来源于stack exchange,提问作者clp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:18:23