我如何 select 基于其在 igraph 中的边之一的节点?
How do I select a node based on one of its edges in 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 的情况下更改 a 的属性值(这样无论删除什么边都可以使用它)
一种方法是将列出连接节点的数据框放在一起,然后检查更新图中缺少哪个节点。我混合使用 igraph
、基本 R 和 tidyverse
函数来完成此操作,但可能有更好的方法。下面的代码可以打包成一个函数,它接受一个 igraph 对象,删除一条边和 returns 更新的 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])
现在我们可以创建一个数据框,列出哪些节点在更新的图中 g
和 left_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
要获得一个列出边被删除的两个节点的向量,您只需要 select adj_after
所在的行 NA
:
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
如果我有如下代码:
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 的情况下更改 a 的属性值(这样无论删除什么边都可以使用它)
一种方法是将列出连接节点的数据框放在一起,然后检查更新图中缺少哪个节点。我混合使用 igraph
、基本 R 和 tidyverse
函数来完成此操作,但可能有更好的方法。下面的代码可以打包成一个函数,它接受一个 igraph 对象,删除一条边和 returns 更新的 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])
现在我们可以创建一个数据框,列出哪些节点在更新的图中 g
和 left_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
要获得一个列出边被删除的两个节点的向量,您只需要 select adj_after
所在的行 NA
:
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