我是否有一种简单的方法可以在igraph中创建简单,加权,定向网络的网状版本?这是相互边缘被替换为承载重量之间的差异的单个边缘的方向,并且方向使得重量总是正的。一个简单的例子:
gGross <- graph_from_literal(A++B)
E(gGross)$weight <- c(12, 20)
gNet <- graph_from_literal(A+-B)
E(gNet)$weight <- c(8)
在矩阵表示法中,这将是
N_ {ij} =(A_ {ij} - A_ {ji})_ +
其中+表示保留正元素。
一个好的起点类似于which_mutual
,它给出了返回边的索引。我可以想象在R中编写一个很长的函数,但这似乎很慢。
答案 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)