Проблемы с прокладкой сети в igraph - PullRequest
1 голос
/ 21 марта 2019

У меня возникли проблемы с реализацией двудольной сети в R с библиотекой igraph.Вот мой сценарий:

library(igraph)
library(reshape2)
setwd("....")
getwd()
library(readxl)
network=read_excel("network1.xlsx")
print(network)
subjects=as.character(unlist(network[,1]))
agents=colnames(network[-1])
print(network)
network = network[,-1]
g=graph.incidence(network, weighted = T)
V(g)$type
V(g)$name=c(subjects,agents)
V(g)$color = V(g)$type
V(g)$color=gsub("FALSE","red",V(g)$color)
V(g)$color=gsub("TRUE","lightblue",V(g)$color)
plot(g, edge.arrow.width = 0.3,
     vertex.size = 5, 
     edge.arrow.size = 0.5,
     vertex.size2 = 5,
     vertex.label.cex = 1,
     vertex.label.color="black",
     asp = 0.35, 
     margin = 0,
     edge.color="grey",
     edge.width=(E(g)$weight),
     layout=layout_as_bipartite)

Сеть правильно построена

, как вы можете видеть

as you can see

однако у меня есть две проблемы

(1) Я не понимаю, в каком порядке показаны вершины на графике.Они не в том же порядке файла Excel, ни в алфавитном или числовом порядке.Кажется, они в случайном порядке.Как я могу выбрать порядок, в котором должна быть размещена вершина?

(2) Я не понимаю, почему некоторые вершины ближе друг к другу, а некоторые - гораздо дальше друг от друга.Я бы все вершины на одном расстоянии.Как я мог это сделать?

Большое спасибо за неоценимую помощь.

Ответы [ 2 ]

1 голос
/ 24 марта 2019

Поскольку вы не предоставляете свои данные, я проиллюстрирую это на вымышленном примере.

Пример графических данных

library(igraph)
set.seed(123)
EL = matrix(c(sample(8,18, replace=T),
    sample(LETTERS[1:6], 18, replace=T)), ncol=2)
g = simplify(graph_from_edgelist(EL))
V(g)$type = bipartite_mapping(g)$type 
VCol = c("#FF000066", "#0000FF66")[as.numeric(V(g)$type)+1]
plot(g, layout=layout_as_bipartite(g), vertex.color=VCol)

Raw graph

Как и в случае с вашим графиком, здесь есть две проблемы.Узлы упорядочены произвольно, а нижний ряд странно разнесен.Давайте решать эти проблемы по одному.Для этого нам нужно взять под контроль макет, а не использовать какие-либо функции автоматического макета.Компоновка - это просто матрица vcount(g) * 2, дающая координаты xy вершин для построения.Здесь я помещу один тип узлов в верхнюю строку, указав координату y как 1, а другие узлы в нижней строке, указав y = 0.Мы хотим указать порядок по рангу (в алфавитном порядке) внутри каждой группы.Итак,

LO = matrix(0, nrow=vcount(g), ncol=2)
LO[!V(g)$type, 2] = 1
LO[V(g)$type, 1]  = rank(V(g)$name[V(g)$type]) 
LO[!V(g)$type, 1] = rank(V(g)$name[!V(g)$type])
plot(g, layout=LO, vertex.color=VCol)

Ordered graph, but unbalanced

Теперь обе строки упорядочены и расположены равномерно, но поскольку в нижнем ряду меньше вершин, это непривлекательно,неуравновешенный взгляд.Мы можем исправить это, растянув нижний ряд.Я считаю, что проще сделать правильный масштабный коэффициент, если координаты идут от 0 до (количество узлов) - 1, а не от 1 до (количество узлов), как указано выше.При этом мы получаем

LO[V(g)$type, 1]  = rank(V(g)$name[V(g)$type]) - 1
LO[!V(g)$type, 1] = (rank(V(g)$name[!V(g)$type]) - 1) * 
    (sum(V(g)$type) - 1)  /  (sum(!V(g)$type) - 1)
plot(g, layout=LO, vertex.color=VCol)

Balanced, ordered graph

0 голосов
/ 24 марта 2019

большое спасибо.Я выполнил ваш очень очень полезный пример, и на первом этапе я сделал все правильно, работая со своими данными, сохраняя разную толщину ребер и все как на моем графике, но в правильном порядке.Это очень важно, большое спасибо.Однако у меня есть некоторые проблемы с пониманием того, как правильно масштабировать верхний и нижний ряд с моими данными, потому что они всегда кажутся слишком близкими.наверное я не совсем понял координаты, над которыми мне приходится работать.Вот мои данные.

> `> network=read_excel("network1.xlsx",2)
> dput(network)
structure(list(`NA` = c(2333, 2439, 2450, 2451, 2452, 2453, 2454, 
2455, 2456, 2457, 2458, 2459, 2460, 2461, 2480, 2490, 2491, 2492, 
2493, 2494, 2495), A = c(12, 2, 2, 5, 2, 0, 5, 3, 0, 0, 7, 0, 
0, 0, 6, 2, 10, 7, 1, 2, 5), B = c(0, 1, 0, 1, 0, 0, 2, 0, 0, 
0, 0, 0, 1, 0, 5, 0, 2, 0, 0, 0, 0), C = c(0, 0, 0, 0, 1, 0, 
4, 0, 0, 0, 0, 1, 0, 0, 2, 0, 4, 4, 2, 1, 0), D = c(2, 0, 0, 
0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 0, 1, 4, 0), E = c(11, 
2, 3, 3, 3, 8, 3, 6, 4, 1, 1, 0, 12, 0, 5, 0, 4, 6, 4, 8, 9), 
    F = c(2, 0, 0, 3, 1, 0, 10, 1, 0, 0, 0, 1, 0, 0, 9, 0, 0, 
    1, 1, 3, 3), G = c(0, 3, 1, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 
    0, 1, 0, 0, 2, 0, 1, 0), H = c(0, 0, 2, 0, 0, 0, 1, 0, 0, 
    0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1), I = c(0, 0, 0, 0, 0, 
    0, 3, 0, 6, 3, 0, 0, 1, 0, 7, 0, 0, 4, 1, 2, 0), J = c(0, 
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
    0)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-21L), .Names = c(NA, "A", "B", "C", "D", "E", "F", "G", "H", 
"I", "J"))
> print(network)
     NA  A B C D  E  F G H I J
1  2333 12 0 0 2 11  2 0 0 0 0
2  2439  2 1 0 0  2  0 3 0 0 0
3  2450  2 0 0 0  3  0 1 2 0 0
4  2451  5 1 0 0  3  3 1 0 0 0
5  2452  2 0 1 0  3  1 0 0 0 0
6  2453  0 0 0 0  8  0 0 0 0 1
7  2454  5 2 4 2  3 10 0 1 3 0
8  2455  3 0 0 0  6  1 0 0 0 0
9  2456  0 0 0 0  4  0 0 0 6 0
10 2457  0 0 0 0  1  0 3 0 3 0
11 2458  7 0 0 0  1  0 2 0 0 0
12 2459  0 0 1 0  0  1 0 0 0 0
13 2460  0 1 0 0 12  0 0 0 1 0
14 2461  0 0 0 0  0  0 0 0 0 0
15 2480  6 5 2 7  5  9 1 2 7 1
16 2490  2 0 0 0  0  0 0 0 0 0
17 2491 10 2 4 4  4  0 0 0 0 0
18 2492  7 0 4 0  6  1 2 0 4 0
19 2493  1 0 2 1  4  1 0 0 1 0
20 2494  2 0 1 4  8  3 1 0 2 0
21 2495  5 0 0 0  9  3 0 1 0 0
> `
...