在igraph(R)

时间:2015-08-10 13:56:08

标签: r igraph

我是否有一种简单的方法可以在igraph中创建简单,加权,定向网络的网状版本?这是相互边缘被替换为承载重量之间的差异的单个边缘的方向,并且方向使得重量总是正的。一个简单的例子:

gGross <- graph_from_literal(A++B)
E(gGross)$weight <- c(12, 20)

gNet <- graph_from_literal(A+-B)
E(gNet)$weight <- c(8)

Gross network on the left, desired net matrix on the right

在矩阵表示法中,这将是

N_ {ij} =(A_ {ij} - A_ {ji})_ +

其中+表示保留正元素。

一个好的起点类似于which_mutual,它给出了返回边的索引。我可以想象在R中编写一个很长的函数,但这似乎很慢。

1 个答案:

答案 0 :(得分:0)

我觉得我可以做得比这更好,但我至少有一种工作方法。改进最受欢迎。编辑以反映Tamás的评论并允许使用任何属性

nettedGraph <- function(g, col="weight") {

  if(!(col %in% edge_attr_names(g))) {
    stop(col, " not and edge attribute")
  }

  # Get a matrix of mutual edges (by vertex ids)
  me <- ends(g, E(g)[which_mutual(g)], names=FALSE)

  # Only keep one of the mutual edges
  me <- me[me[,1] < me[,2], ] 

  toDel <- vector(mode="integer", length=nrow(me))

  for (i in 1:nrow(me)) {

    # Get edge ids going each way
    e1 <- get.edge.ids(g, c(me[i,1],me[i,2]))
    e2 <- get.edge.ids(g, c(me[i,2],me[i,1]))

    weightDiff <- edge_attr(g,col, e1) - edge_attr(g,col, e2)

    if(weightDiff > 0) {
      # Update the edge we're keeping
      edge_attr(g,col, e1) <- weightDiff
      # Delete the one we're not
      toDel[i] <- e2
    } else {
      # Update the edge we're keeping
      edge_attr(g,col, e2) <- -weightDiff
      # Delete the one we're not
      toDel[i] <- e1
    }

  }

  # Now delete all the unneeded edges
  g <- g - E(g)[toDel]

  return(g)
}

set.seed(123)

g <- graph_from_literal(A-+B, B++C, A++C)
E(g)$weight <- round(runif(ecount(g),1,20))
weight0 <- E(g)$weight

gNet <- nettedGraph(g)