W igraph
, po zastosowaniu algorytmu modularyzacji w celu znalezienia komunika- tów grafów, chciałbym narysować układ sieci, który wyraźnie uwidoczni odrębne społeczności i ich połączenia. Coś takiego jak "układ atrybutów grupowych" w Cytoscape: chcę pokazać członków każdej grupy/społeczności blisko siebie i zachować pewien dystans między grupami/społecznościami. Nie mogłem znaleźć żadnej funkcji w igraph
dostarczającej tę funkcję po wyjęciu z pudełka. Wysyłając to pytanie, znalazłem już proste rozwiązanie w wersji d.i.y, zamierzam je opublikować jako odpowiedź. Ale zastanawiam się, czy jest jakaś lepsza możliwość, czy bardziej dopracowane rozwiązanie?Jak pogrupować układ w igraph?
Odpowiedz
Aby rozwinąć na sugestię Gabor, Stworzyłem tę funkcję:
weight.community=function(row,membership,weigth.within,weight.between){
if(as.numeric(membership[which(names(membership)==row[1])])==as.numeric(membership[which(names(membership)==row[2])])){
weight=weigth.within
}else{
weight=weight.between
}
return(weight)
}
Wystarczy zastosować ją na wierszach macierzy krawędziach grafu (podane przez get.edgelist(your_graph))
ustawić nowe ciężary krawędź (członkostwo jest wektor członków z wyniku dowolnego algorytmu detekcji społeczność):
E(g)$weight=apply(get.edgelist(g),1,weight.community,membership,10,1)
Następnie wystarczy użyć algorytmu układu, który akceptuje ciężary brzegowych, takich jak fruchterman.reingold jak sugeruje Gabor można dostosować argumenty wag do ob. tain wykres, który chcesz. Na przykład:
E(g)$weight=apply(get.edgelist(g),1,weight.community,membership,10,1)
g$layout=layout.fruchterman.reingold(g,weights=E(g)$weight)
plot(g)
E(g)$weight=apply(get.edgelist(g),1,weight.community,membership,1000,1)
g$layout=layout.fruchterman.reingold(g,weights=E(g)$weight)
plot(g)
Uwaga 1: przezroczystości/kolory krawędzi są inne parametry moich wykresach. Mam kolorowe węzły społeczności, aby pokazać, że rzeczywiście działa.
Uwaga 2: upewnij się, aby skorzystać membership(comm)
i nie comm$membership
, gdzie comm
jest wynikiem algorytmu detekcji społeczność (np comm=leading.eigenvector.community(g)
). Powodem jest to, że w pierwszym przypadku otrzymujesz wektor liczbowy z nazwami (czego chcemy), aw drugim przypadku ten sam wektor bez nazw.
Aby uzyskać consensus wielu algorytmów wykrywania społeczności, patrz: function.
Funkcja layout.modular
zapewnia zgrupowanego układ na wykresie z wyników jakiegokolwiek sposobu wykrywania społeczność igraph:
c <- fastgreedy.community(G)
layout.modular <- function(G,c){
nm <- length(levels(as.factor(c$membership)))
gr <- 2
while(gr^2<nm){
gr <- gr+1
}
i <- j <- 0
for(cc in levels(as.factor(c$membership))){
F <- delete.vertices(G,c$membership!=cc)
F$layout <- layout.kamada.kawai(F)
F$layout <- layout.norm(F$layout, i,i+0.5,j,j+0.5)
G$layout[c$membership==cc,] <- F$layout
if(i==gr){
i <- 0
if(j==gr){
j <- 0
}else{
j <- j+1
}
}else{
i <- i+1
}
}
return(G$layout)
}
G$layout <- layout.modular(G,c)
V(G)$color <- rainbow(length(levels(as.factor(c$membership))))[c$membership]
plot(G)
Jednym rozwiązaniem jest ustawienie grubości krawędzi wykresu, na podstawie modułowości. Ustaw krawędzie wewnątrz modułu na pewną dużą masę, a krawędzie między modułami na niewielką wagę. Następnie zadzwoń pod numer layout.fruchterman.reingold()
lub dowolny algorytm obsługujący grubości krawędzi.
Być może trzeba trochę pogodzić z rzeczywistymi wartościami ciężaru, ponieważ zależy to od wykresu.
Cześć Gabor, czy mógłbyś rzucić okiem na ten powiązany [wątek] (http://stackoverflow.com/questions/31432176/potential-issue-with-new-igraph-layout-algorithms-r). Z góry dziękuję. – Antoine
Inspirowane na sugestię Antoine, stworzyłem tę funkcję:
edge.weights <- function(community, network, weight.within = 100, weight.between = 1) {
bridges <- crossing(communities = community, graph = network)
weights <- ifelse(test = bridges, yes = weight.between, no = weight.within)
return(weights)
}
Funkcja robi to samo; po prostu umieść swój obiekt społecznościowy w slocie społeczności, a twój wykres w sieci. Zostawiłam weight.between = 1
i dostroiłam wartość weight.within
.
następnie przenieść ciężar do gniazda weight
w węzłach:
E(graph)$weight <- edge.weights(community, graph)
Wreszcie użyć algorytmu układu, który wykorzystuje ciężary jak layout_with_fr
(nową nazwą fruchterman.reingold
w igraph 1.0.1
).
Korzystam z sieci karate klubu Zachary jako przykładu.
library(igraph)
library(igraphdata)
#I load the network
data(karate)
#for reproducible purposes
set.seed(23548723)
karateLayout <- layout_with_fr(karate)
par(mar = c(0,0,2,0))
plot(karate, vertex.size = 10, vertex.color = "steelblue4", edge.width = 1,
vertex.label = NA, edge.color = "darkgrey", layout = karateLayout,
main = "Zachary's karate club network")
wykryć społeczności poprzez optymalizację wielopoziomowego modularność z cluster_louvain
funkcję:
Communitykarate <- cluster_louvain(karate)
Kolejnym jest to osobiste preferencje ciągu domyślne:
prettyColors <- c("turquoise4", "azure4", "olivedrab","deeppink4")
communityColors <- prettyColors[membership(Communitykarate)]
Wykres ze społecznościami wyróżnione poprzez kolory to:
plot(x = Communitykarate, y = karate, edge.width = 1, vertex.size = 10,
vertex.label = NA, mark.groups = NULL, layout = karateLayout, col = communityColors,
main = "Communities in Zachary's karate club network",
edge.color = c("darkgrey","tomato2")crossing(Communitykarate, karate) + 1])
Teraz sens dlaczego to pytanie istnieje.
E(karate)$weight <- edge.weights(Communitykarate, karate)
# I use the original layout as a base for the new one
karateLayoutA <- layout_with_fr(karate, karateLayout)
# the graph with the nodes grouped
plot(x = Communitykarate, y = karate, edge.width = 1, vertex.size = 10,
mark.groups = NULL, layout = karateLayoutA, vertex.label = NA, col = communityColors,
c("darkgrey","tomato2")[crossing(Communitykarate, karate) + 1],
main = "Communities in Zachary's karate club network (grouped)")
Jeśli spróbujesz z większą wagę będzie trzeba mieć:
E(karate)$weight <- edge.weights(Communitykarate, karate, weight.within = 1000)
karateLayoutB <- layout_with_fr(karate, karateLayout)
plot(x = Communitykarate, y = karate, edge.width = 1, vertex.size = 10,
mark.groups = NULL, layout = karateLayoutB, vertex.label = NA, col = communityColors,
c("darkgrey","tomato2")[crossing(Communitykarate, karate) + 1],
main = "Communities in Zachary's karate club network (grouped)")
- 1. Eliksir - jak pogrupować mapy?
- 2. Jak pogrupować data.frame według daty?
- 3. Jak pogrupować daty według tygodni?
- 4. Jak pogrupować tę tablicę skrótów?
- 5. Jak pogrupować dane według tytułu?
- 6. Ruby: Jak pogrupować tablicę Ruby?
- 7. Jak pogrupować serie według wartości w pandach?
- 8. Jak pogrupować dane w Angular 2?
- 9. Jak pogrupować podobne elementy w strumieniu aktywności
- 10. Jak pogrupować datę co kwartał w MongoDB
- 11. Który układ powinienem użyć, aby uzyskać niepokrywające się krawędzie w igraph?
- 12. generowanie wykresu społeczności w igraph
- 13. python + igraph "plotowanie niedostępne"
- 14. Objective-C: jak pogrupować serię stałych łańcuchowych?
- 15. Jak mogę pogrupować tablicę obiektów według miesiąca?
- 16. Jak podzielić igraph na połączone podgrafy?
- 17. Jak pogrupować DataFrame przez pewien okres czasu?
- 18. Jak pogrupować wiersze według ich DATEDIFF?
- 19. Jak pogrupować pandas DataFrame według różnych dat?
- 20. Jak pogrupować tablicę obiektów według klucza
- 21. Jak pogrupować zdarzenia przychodzące z nieskończonego strumienia?
- 22. Podzbiór wykresu igraph według etykiety
- 23. Określone długości krawędzi w siecix/igraph (Python)
- 24. Poprawnie kolorowe wierzchołki w R igraph
- 25. pobierz podłączone komponenty używając igraph w R
- 26. rysuj wiele dyskretnych sieci w R używając igraph
- 27. Jak kopać dla motywów w R z iGraph
- 28. Jak przypisać różne obrazy do różnych wierzchołków w kodzie igraph?
- 29. Jak pogrupować równoważne elementy na liście w Pythonie?
- 30. Jak pogrupować liczbę użytkowników według przedziałów wiekowych w mysql
pojawia się błąd, gdy próbuję swoją metodę. Dodałem tylko dwa wiersze powyżej kodu, aby zasymulować sieć, tj .: 'library (igraph); G <- barabasi.game (100, directed = FALSE) '. Komunikat o błędzie mówi: "Błąd w układzie G $ [członkostwo c == cc,] <- Układ F $: niepoprawna liczba indeksów na macierzy" – majom
Otrzymuję również podobny błąd. – imbenzene
Niestety, dzieje się tak, ponieważ 'G $ layout' to' NULL'. Jeśli wypełnisz ją dowolną macierzą o odpowiednich wymiarach lub po prostu z układem 'G $ <- layout.fruchterman.reingold (G)', to kod działa dobrze. – deeenes