如何根据igraph中的一个边缘选择节点?

时间:2017-11-27 03:36:25

标签: r igraph

如果我有以下代码:

library(igraph)

g <- erdos.renyi.game(20, 50 , type = "gnm" , directed = F , loops = F) %>%
  set_vertex_attr("a", value = 0) %>%
  set_vertex_attr("aa", value = 0) %>%
  set_edge_attr("b", value = 0) %>%
  set_vertex_attr("z", value = 0) 

V(g)$aa <- sample(c(0, .25, .5, .75, 1), vcount(g), replace = TRUE, prob = c(0.3, 0.15, 0.3, 0.15, 0.1))

V(g)$a[V(g)$aa <= V(g)$z & V(g)$a == 0] <- 1

V(g)$z <- sapply(V(g), function(x) { 
    NeighborList = neighbors(g, x) ; 
    ifelse(length(NeighborList) > 0, 
    length(NeighborList[NeighborList$a == 1])/length(NeighborList),0) } )

sum <- sum(head_of(g,E(g))$a==0 & tail_of(g,E(g))$a==0)

E(g)$b[head_of(g,E(g))$a==0 & tail_of(g,E(g))$a==0] <- sample(rep(0:1, c(sum-1, 1)), sum)

g <- delete_edges(g, E(g)[E(g)$b == 1])

在删除单个边缘的情况下,如何更改刚刚丢失连接的节点的属性?因此,如果节点1和5是丢失它们之间边缘的节点,那么如何在不指定1和5的情况下更改其属性值(以便无论删除哪个边缘都可以使用它)

1 个答案:

答案 0 :(得分:1)

一种方法是将列出连接节点的数据框放在一起,然后检查更新图中缺少哪一个。我已经使用igraph,基本R和tidyverse函数的混合完成了这项工作,但可能有更好的方法。下面的代码可以打包成一个函数,它接受一个igraph对象,删除一个边并返回更新的igraph对象和边缘被删除的节点的名称。

首先,让我们重新创建您的图表,但我们将为可重复性设置种子:

set.seed(2)
g <- erdos.renyi.game(20, 50 , type = "gnm" , directed = F , loops = F) %>%
  set_vertex_attr("a", value = 0) %>%
  set_vertex_attr("aa", value = 0) %>%
  set_edge_attr("b", value = 0) %>%
  set_vertex_attr("z", value = 0) 

V(g)$aa <- sample(c(0, .25, .5, .75, 1), vcount(g), replace = TRUE, prob = c(0.3, 0.15, 0.3, 0.15, 0.1))

V(g)$a[V(g)$aa <= V(g)$z & V(g)$a == 0] <- 1

V(g)$z <- sapply(V(g), function(x) { 
  NeighborList = neighbors(g, x) ; 
  ifelse(length(NeighborList) > 0, 
         length(NeighborList[NeighborList$a == 1])/length(NeighborList),0) } )

sum <- sum(head_of(g,E(g))$a==0 & tail_of(g,E(g))$a==0)

E(g)$b[head_of(g,E(g))$a==0 & tail_of(g,E(g))$a==0] <- sample(rep(0:1, c(sum-1, 1)), sum)

现在要检测哪条边被移除了:

library(tidyverse)

创建一个数据框,列出g当前连接的节点:

adj = as.data.frame(get.edgelist(g)) %>% mutate(adj_before=1)

adj
   V1 V2 adj_before
1   1  3          1
2   1  4          1
3   4  5          1
...
13  5 10          1
14  9 10          1
15  1 11          1
...
48  7 20          1
49  9 20          1
50 10 20          1

现在我们将以您指定的方式删除边缘。

g <- delete_edges(g, E(g)[E(g)$b == 1])

现在,我们可以创建一个数据框,列出哪些节点在更新的图表gleft_join中连接到现有的adj数据框。对于边缘已被删除的节点对,行中将有NA

adj = adj %>% 
  left_join(as.data.frame(get.edgelist(g)) %>% 
              mutate(adj_after=1))

adj
   V1 V2 adj_before adj_after
1   1  3          1         1
2   1  4          1         1
3   4  5          1         1
...
13  5 10          1         1
14  9 10          1        NA
15  1 11          1         1
...
48  7 20          1         1
49  9 20          1         1
50 10 20          1         1

要获取向量列出已删除边缘的两个节点,您只需选择adj_afterNA的行:

Vs = unlist(adj[which(is.na(adj$adj_after)), c("V1","V2")])

Vs
V1 V2 
 9 10

现在,假设您要为刚刚删除边缘的节点更改属性a

# Current attribute `a` values:
V(g)$a
[1] 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1
V(g)$a[Vs] = 3

V(g)$a
[1] 1 0 0 1 0 0 0 0 3 3 0 0 1 0 0 0 0 1 1 1