如果我有以下代码:
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的情况下更改其属性值(以便无论删除哪个边缘都可以使用它)
答案 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])
现在,我们可以创建一个数据框,列出哪些节点在更新的图表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
要获取向量列出已删除边缘的两个节点,您只需选择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