igraph: сохраняются только ребра, содержащие вершины с разными значениями атрибута вершины - PullRequest
0 голосов
/ 27 октября 2019

net является объектом igraph:

IGRAPH f6d0c20 UN-- 60 150 -- 
+ attr: name (v/c), group (v/c), group1_flag (v/n), teams (v/c), ppl (v/c), ids
| (v/c), value (e/n)
+ edges from f6d0c20 (vertex names):
 [1] 132--115 132--113 132--131 132--141 132--133 173--174 173--122 173--175 173--172
[10] 173--152 173--161 173--121 173--171 173--293 173--292 105--103 105--112 105--102
[19] 105--113 105--101 105--121 105--104 105--322 105--321 105--343 103--102 103--162
[28] 103--101 103--111 103--171 103--104 103--322 103--263 103--261 114--112 114--115
[37] 114--174 114--113 114--175 114--111 114--171 114--203 114--225 114--345 112--115
[46] 112--164 112--113 112--175 112--111 112--171 142--115 142--153 142--171 142--141
[55] 115--174 115--122 115--113 115--151 115--101 115--111 115--171 115--293 115--304
+ ... omitted several edges

Вершины имеют двоичный дихотомический атрибут, называемый group1_flag. Удобно, что идентификаторы вершин хранят эту информацию: любой трехзначный идентификатор, начинающийся с 1, будет иметь group1_flag = 1;другие имеют group1_flag = 0. Например, первое ребро (132--115) должно быть полностью исключено из графика, но должно быть включено последнее ребро, напечатанное выше (115--304).

Я пытался получить этот результат с помощью subset_edges():

crossgroupnet <- subgraph.edges(net, which(V(net)$group>"1"), delete.vertices = T)

но

  1. Я не уверен, что мне следует указывать информацию о вершинах в функции (но нет атрибута ребра кросс-группы),и
  2. результат включает в себя множество связей в группе (не должно) и пропускает множество связей между группами (например, 115--304):

plot(crossgroupnet, vertex.color = rainbow(2)[factor(V(crossgroupnet)$group1_flag)], vertex.label = V(crossgroupnet)$ids)

enter image description here

Чего мне не хватает?

1 Ответ

1 голос
/ 28 октября 2019

По крайней мере, как вы описали проблему, ваш код не имеет смысла. Вы генерируете подграф, используя:

crossgroupnet <- subgraph.edges(net, which(V(net)$group>"1"), delete.vertices = T)

Второй аргумент subgraph.edges должен быть списком ребер, которые вы хотите включить, но which(V(net)$group>"1") будет генерировать порядковые номера на основе вершин.

Вы на самом деле не предоставляете свою сеть (список ребер урезан), но я буду использовать ваш усеченный список в качестве моего примера (данные под ответом). Вот результирующий график.

plot(net, vertex.color=V(net)$group_flag+1)

Full graph

ОК, теперь нам нужно выбрать те ребра, концы которых находятся в разных группах. Мы можем использовать ends по краям, чтобы получить соответствующие вершины, а затем проверить, находятся ли они в одной группе. Сохраняя ребра с вершинами в разных группах, мы можем сгенерировать искомый подграф.

CrossEdges = which(sapply(E(net), function(x) {
    length(unique(V(net)[ends(net, x)]$group_flag)) != 1 }))
SUB = subgraph.edges(net, CrossEdges)

plot(SUB, vertex.color=V(SUB)$group_flag+1)

Subgraph

Данные

EL = read.table(text= "V1 V2
132 115 
132 113 
132 131 
132 141 
132 133 
173 174 
173 122 
173 175 
173 172
173 152 
173 161 
173 121 
173 171 
173 293 
173 292 
105 103 
105 112 
105 102
105 113 
105 101 
105 121 
105 104 
105 322 
105 321 
105 343 
103 102 
103 162
103 101 
103 111 
103 171 
103 104 
103 322 
103 263 
103 261 
114 112 
114 115
114 174 
114 113 
114 175 
114 111 
114 171 
114 203 
114 225 
114 345 
112 115
112 164 
112 113 
112 175 
112 111 
112 171 
142 115 
142 153 
142 171 
142 141
115 174 
115 122 
115 113 
115 151 
115 101 
115 111 
115 171 
115 293 
115 304", 
header=T)
EL$V1 =  as.character(EL$V1)
EL$V2 =  as.character(EL$V2)
EL = as.matrix(EL)

net = graph_from_edgelist(EL, directed = F)
V(net)$group_flag = as.numeric(floor(as.numeric(V(net)$name)/100) == 1)
...