2013-05-16 41 views
9

Mein Problem ist sehr einfach: Ich muss eine Adjazenzliste/Matrix aus einer Liste von Kanten erstellen.Wie erstellt man eine gewichtete Adjazenzliste/Matrix aus der Kantenliste?

Ich habe eine Kantenliste in einem CSV-Dokument mit Spalte1 = Knoten1 und Spalte2 = Knoten2 gespeichert und möchte dies in eine gewichtete Adjazenzliste oder eine gewichtete Adjazenzmatrix umwandeln.

Genauer gesagt, ist hier zu sein, wie die Daten wie folgt aussehen -wo die Zahlen sind einfach Knoten-IDs:

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 

Irgendwelche Tipps, wie die Umwandlung von dieser zu einer gewichteten Adjazenzliste/Matrix zu erreichen? Dies ist, wie ich beschlossen, es früher zu tun, ohne Erfolg (mit freundlicher Genehmigung von 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' 

Thank you!

+2

Können Sie uns ein kleines reproduzierbares Beispiel geben und Ihre möglichen Versuche, dies zu codieren? –

+0

[Dieser Beitrag] (http://stackoverflow.com/questions/14332233/using-graph-adjacency-in-r/14332667#14332667) kann hilfreich sein. – Arun

+0

Danke @Arun für das Zeigen auf diesen Beitrag. Es ist in der Tat nützlich, aber wenn ich mich nicht irre, sind ihre Daten bereits in einer Matrix angeordnet, während, wie Sie aus der bearbeiteten Version meiner Frage sehen können, ich eine andere Eingabe habe. Ich hoffe, dass ich durch die Bearbeitung des Posts auch auf Roman geantwortet habe. – Milo

Antwort

15

Diese Antwort verwendet nur Base R. Das Ergebnis ist eine Standardmatrix zur Darstellung der Adjazenzmatrix.

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 

Hier mat ist Ihre Adjazenzmatrix von Kantenliste definiert el, die eine einfache cbind der Vektoren 1:5 und 5:1 ist.

Wenn Ihre Edgeliste Gewichte enthält, benötigen Sie eine etwas andere Lösung.

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

Einige Zeit später erkannte ich, dass die for-Schleife (3. Zeile) im vorherigen gewichteten Kantenliste Beispiel nicht notwendig ist. Sie können sie mit folgendem vektorisiert Betrieb ersetzen:

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

Der Beitrag auf meiner Website, die Sie in der Frage erwähnen (https://sites.google.com/site/daishizuka/toolkits/sna/sna_data) verwendet das IGRAPH Paket, so stellen Sie sicher, dass geladen wird.

Außerdem habe ich kürzlich festgestellt, dass igraph eine viel einfachere Möglichkeit bietet, eine gewichtete Adjazenzmatrix aus Edge-Listen zu erstellen, indem man graph.data.frame() verwendet. Ich habe dies auf meiner Website aktualisiert, aber hier ist ein einfaches Beispiel:

Das sollte es tun. Das Sparse = FALSE-Argument sagt ihm, die 0 in der Adjazenzmatrix anzuzeigen. Wenn Sie wirklich IGRAPH nicht verwenden wollen, ich denke, das ein klobig Weg, es zu tun:

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

Beachten Sie, dass Sie für ein gewichtetes Netzwerk eine 'attr = 'Gewichtung' zum Aufruf 'get.adjacency()' hinzufügen müssen, damit eine gewichtete Adjazenzmatrix anstelle einer ungewichteten Version zurückgegeben wird. –

+0

großer Link, es zeigt auch die Verwendung von Rahmen, um eine Liste von Kanten zu importieren. Ich sehe nicht gleichwertige API in Python obwohl: / – user305883

0

Eine weitere Möglichkeit mit den qdapTools Paket:

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

beginnt mit Ihren Daten Rahmenkanten und verwenden IGRAPH zu erhalten Adjazenzmatrix:

Kopf (Kanten)

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 
Verwandte Themen