2013-05-16 12 views
9

Mój problem jest bardzo prosty: potrzebuję utworzyć listę/macierz sąsiedztwa z listy krawędzi.Jak utworzyć ważoną listę/macierz sąsiedztwa z listy krawędzi?

Mam listę krawędzi zapisaną w dokumencie csv z kolumną1 = węzeł1 i kolumną2 = węzeł2 i chciałbym przekonwertować to na listę ważonego sąsiedztwa lub macierz ważonego dopasowania.

Aby być bardziej precyzyjnym, oto jak wygląda dane Gdzie numery są po prostu węzeł identyfikatory:

node1,node2 
551,548 
510,512 
548,553 
505,504 
510,512 
552,543 
512,510 
512,510 
551,548 
548,543 
543,547 
543,548 
548,543 
548,542 

Wszelkie wskazówki dotyczące sposobu osiągnięcia tego celu konwersji z ważonej listy sąsiedztwa/matrycy? ten sposób postanowiłem zrobić to wcześniej, bez powodzenia (dzięki uprzejmości Dai Shizuka):

dat=read.csv(file.choose(),header=TRUE) # choose an edgelist in .csv file format 
el=as.matrix(dat) # coerces the data into a two-column matrix format that igraph likes 
el[,1]=as.character(el[,1]) 
el[,2]=as.character(el[,2]) 
g=graph.edgelist(el,directed=FALSE) # turns the edgelist into a 'graph object' 

Dziękujemy!

+2

Czy możesz podać nam mały powtarzalny przykład i możliwe próby kodowania tego? –

+0

[Ten wpis] (http://stackoverflow.com/questions/14332233/using-graph-adjacency-in-r/14332667#14332667) może być pomocny. – Arun

+0

Dzięki @Arun za skierowanie mnie do tego postu. Jest to naprawdę użyteczne, ale jeśli się nie mylę, ich dane są już uporządkowane w sposób matrycowy, podczas gdy jak widzisz ze zredagowanej wersji mojego pytania, mam inny wkład. Edytując post, mam nadzieję, że odpowiedziałem również na Romana. – Milo

Odpowiedz

15

Ta odpowiedź używa tylko bazy R. Wynikiem jest standardowa macierz używana do reprezentowania macierzy sąsiedztwa.

el <- cbind(a=1:5, b=5:1) #edgelist (a=origin, b=destination) 
mat <- matrix(0, 5, 5) 
mat[el] <- 1 
mat 
# [,1] [,2] [,3] [,4] [,5] 
#[1,] 0 0 0 0 1 
#[2,] 0 0 0 1 0 
#[3,] 0 0 1 0 0 
#[4,] 0 1 0 0 0 
#[5,] 1 0 0 0 0 

tutaj mat to matryca przylegania określone na edgelist el, który jest prosty cbind wektorów 1:5 i 5:1.

Jeśli Twój edgelista obejmuje wagi, to potrzebujesz nieco innego rozwiązania.

el <- cbind(a=1:5, b=5:1, c=c(3,1,2,1,1)) # edgelist (a=origin, b=destination, c=weight) 
mat<-matrix(0, 5, 5) 
for(i in 1:NROW(el)) mat[ el[i,1], el[i,2] ] <- el[i,3] # SEE UPDATE 
mat 
#  [,1] [,2] [,3] [,4] [,5] 
#[1,] 0 0 0 0 3 
#[2,] 0 0 0 1 0 
#[3,] 0 0 2 0 0 
#[4,] 0 1 0 0 0 
#[5,] 1 0 0 0 0 

UPDATE

Jakiś czas później sobie sprawę, że do pętli (3. linia) z poprzedniego przykładu ważonej edgelist jest konieczne. Można zastąpić go następującym vectorized pracy:

mat[el[,1:2]] <- el[,3] 
14

post na mojej stronie można wymienić w pytaniu (https://sites.google.com/site/daishizuka/toolkits/sna/sna_data) wykorzystuje pakiet igraph, więc upewnij się, że jest załadowany.

Co więcej, niedawno zdałem sobie sprawę, że igraph zapewnia znacznie prostszy sposób tworzenia macierzy dopasowania z edgelistami za pomocą graph.data.frame(). Zaktualizowałem to na mojej stronie, ale tutaj jest prosty przykład:

library(igraph) 
el=matrix(c('a','b','c','d','a','d','a','b','c','d'),ncol=2,byrow=TRUE) #a sample edgelist 
g=graph.data.frame(el) 
get.adjacency(g,sparse=FALSE) 

To powinno wystarczyć. Argument rozrzedzony = FALSE nakazuje mu pokazywanie 0 w macierzy sąsiedztwa. Jeśli naprawdę nie chcesz używać igraph, myślę, że to jest niezdarny sposób to zrobić:

el=matrix(c('a','b','c','d','a','d','a','b','c','d'),ncol=2,byrow=TRUE) #a sample edgelist 
lab=names(table(el)) #extract the existing node IDs 
mat=matrix(0,nrow=length(lab),ncol=length(lab),dimnames=list(lab,lab)) #create a matrix of 0s with the node IDs as rows and columns 
for (i in 1:nrow(el)) mat[el[i,1],el[i,2]]=mat[el[i,1],el[i,2]]+1 #for each row in the edgelist, find the appropriate cell in the empty matrix and add 1. 
+0

Należy zauważyć, że w przypadku sieci ważonej należy dodać atrybut 'attr = 'weight'' do wywołania' get.adjacency() ', aby zwrócił on ważoną macierz sąsiedztwa zamiast wersji nieważonej. –

+0

świetny link, pokazuje także użycie ramki do importowania listy krawędzi. Nie widzę równoważnego API w Pythonie: / – user305883

0

Inną możliwością z qdapTools pakiet:

library(qdapTools) 

el[rep(seq_len(nrow(el)), el[,'c']), c('a', 'b')] %>% 
    {split(.[,'b'], .[,'a'])} %>% 
    mtabulate() 

## 1 2 3 4 5 
## 1 0 0 0 0 3 
## 2 0 0 0 1 0 
## 3 0 0 2 0 0 
## 4 0 1 0 0 0 
## 5 1 0 0 0 0 
1

start z danymi krawędzie ramy i zastosowanie igraph uzyskać macierz sąsiedztwa:

głowicy (krawędzie)

node1 node2 
1 551 548 
2 510 512 
3 548 553 
4 505 504 
5 510 512 
6 552 543 

library(igraph) 
as.matrix(get.adjacency(graph.data.frame(edges))) 

    551 510 548 505 552 512 543 553 504 547 542 
551 0 0 2 0 0 0 0 0 0 0 0 
510 0 0 0 0 0 2 0 0 0 0 0 
548 0 0 0 0 0 0 2 1 0 0 1 
505 0 0 0 0 0 0 0 0 1 0 0 
552 0 0 0 0 0 0 1 0 0 0 0 
512 0 2 0 0 0 0 0 0 0 0 0 
543 0 0 1 0 0 0 0 0 0 1 0 
553 0 0 0 0 0 0 0 0 0 0 0 
504 0 0 0 0 0 0 0 0 0 0 0 
547 0 0 0 0 0 0 0 0 0 0 0 
542 0 0 0 0 0 0 0 0 0 0 0 
Powiązane problemy