igraph:基于节点属性的折扣边权重

igraph: discount edge weights based on node attributes

我有一个带边权重的无向网络。 每个节点都有一个属性“组”。 我想更改现有权重,对同一组内节点之间的那些边进行折扣。

例如 如果 node1 和 node2 的边权重为 10 并且它们的属性“group”都等于“A”,那么我想将权重除以 - 让我们说 - 2,如果不是(它们属于不同的组)它们的权重应该保持 10.

我不确定如何进行。

我可以使用 E(g)$weight 可视化权重,使用 V(g)$group 可视化属性,但我想不出一种方法来使用顶点属性来更改边权重。

您可以使用 igraph::%--% 运算符来提供帮助。如您的示例所示:如果两个顶点都在 A 组中,则将权重除以 2

v_a <- which(V(g)$group == "A")  # All vertices in group A
e_a <- E(g)[v_a %--% v_a]  # All edges between those vertices

edge_attr(g)$weight[e_a] <- edge_attr(g)$weight[e_a] / 2

如果每个组都以类似的方式处理,则可以使用 for 循环。在此示例中,您将权重除以某个常数,具体取决于其顶点所在的组。

group_constants <- c("A" = 2, "B" = 20, "C" = 200)

for (i in unique(V(g)$group)) {
  v_a <- which(V(g)$group == i)
  e_a <- E(g)[v_a %--% v_a]
  
  edge_attr(g)$weight[e_a] <- edge_attr(g)$weight[e_a] / group_constants[i]
}

这是我使用的数据。这是一个具有顶点组和边权重的无向图。

verts <- letters[1:10]

g_df <- data.frame(
  from = sample(verts, 15, replace = TRUE),
  to = sample(verts, 15, replace = TRUE),
  weight = sample(1:10, 15, replace = TRUE)
)

g_df_v <- data.frame(
  name = verts,
  group = sample(LETTERS[1:3], 10, replace = TRUE)
)

g <- graph_from_data_frame(g_df, directed = FALSE, vertices = g_df_v)

# Edges
#    from to weight
# 1     h  i      5
# 2     i  e      9
# 3     d  i      8
# 4     c  a     10
# 5     f  c      7
# 6     a  b      5
# 7     j  i      1
# 8     j  b      8
# 9     a  f      4
# 10    h  i      7
# 11    g  a      7
# 12    f  b      6
# 13    e  c      8
# 14    b  f      4
# 15    g  c      8

# Vertices
#    name group
# 1     a     C
# 2     b     B
# 3     c     C
# 4     d     B
# 5     e     A
# 6     f     A
# 7     g     A
# 8     h     B
# 9     i     B
# 10    j     B