Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create weighted adjacency list/matrix from edge list?

My problem is very simple: I need to create an adjacency list/matrix from a list of edges.

I have an edge list stored in a csv document with column1 = node1 and column2 = node2 and I would like to convert this to a weighted adjacency list or a weighted adjacency matrix.

To be more precise, here's how the data looks like -where the numbers are simply node 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

Any tips on how to achieve the conversion from this to a weighted adjacency list/matrix? This is how I resolved to do it previously, without success (courtesy of 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!

like image 431
Milo Avatar asked May 16 '13 10:05

Milo


People also ask

How can we store the edge weight in an adjacency list?

For storing an adjacency list with edge weights, the (apparently) standard way is to store a vector of vector of pairs (vertex end, weight).

How do you add an edge to adjacency matrix?

Inserting an edge: To insert an edge between two vertices suppose i and j, set the corresponding values in the adjacency matrix equal to 1, i.e. g[i][j]=1 and g[j][i]=1 if both the vertices i and j exists.

How do you find the adjacency matrix of a weighted graph?

To store weighted graph using adjacency matrix form, we call the matrix as cost matrix. Here each cell at position M[i, j] is holding the weight from edge i to j. If the edge is not present, then it will be infinity. For same node, it will be 0.

What is a weighted adjacency matrix?

The adjacency matrix of a weighted graph can be used to store the weights of the edges. If an edge is missing a special value, perhaps a negative value, zero or a large value to represent "infinity", indicates this fact.


3 Answers

Start with your data frame edges and use igraph to obtain adjacency matrix:

head(edges)

  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
like image 138
Sandipan Dey Avatar answered Sep 29 '22 06:09

Sandipan Dey


This response uses base R only. The result is a standard matrix used to represent the adjacency matrix.

 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

Here mat is your adjacency matrix defined from edgelist el, which is a simple cbind of the vectors 1:5 and 5:1.

If your edgelist includes weights, then you need a slightly different solution.

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

Some time later I realized that the for loop (3rd line) in the previous weighted edgelist example is unnecessary. You can replace it with the following vectorized operation:

mat[el[,1:2]] <- el[,3]
like image 18
ndoogan Avatar answered Oct 12 '22 11:10

ndoogan


The post on my website you mention in the question (https://sites.google.com/site/daishizuka/toolkits/sna/sna_data) uses the igraph package, so make sure that is loaded.

Moreover, I recently realized that igraph provides a much easier way to create a weighted adjacency matrix from edgelists, using graph.data.frame(). I've updated this on my site, but here is a simple example:

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)

That should do it. The sparse=FALSE argument tells it to show the 0s in the adjacency matrix. If you really don't want to use igraph, I think this is a clunky way to do it:

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.
like image 16
Dai Shizuka Avatar answered Oct 12 '22 09:10

Dai Shizuka