PetrMolek
PetrMolek

Reputation: 23

Creating an igraph from weighted correlation matrix csv

First of all, I'd like to say that I'm completely new to R, and I'm just trying to accomplish this one task. So, what I'm trying to do is that I'd like to create an network diagram from a weighted matrix. I made an example:

The CSV is a simple correlation matrix that looks like this:

,A,B,C,D,E,F,G
A,1,0.9,0.64,0.43,0.38,0.33,0.33
B,0.9,1,0.64,0.33,0.43,0.38,0.38
C,0.64,0.64,1,0.59,0.69,0.64,0.64
D,0.43,0.33,0.59,1,0.28,0.23,0.28
E,0.38,0.43,0.69,0.28,1,0.95,0.9
F,0.33,0.38,0.64,0.23,0.95,1,0.9
G,0.33,0.38,0.64,0.28,0.9,0.9,1

I tried to draw the wanted result by myself and came up with this: enter image description here

To be more precise, I draw the diagram first, then, using a ruler, I took note of the distances, calculated an equation to get the weights and made the CSV table.

The higher the value is, the closer the two points are to each other.

However, whatever I do, the best result I get is this:

enter image description here

And this is how I'm trying to accomplish it, using this tutorial:

First of all, I import my matrix:

> matrix <- read.csv(file = 'test_dataset.csv')

But after printing the matrix out with head(), this already somehow cuts the last line of the matrix:

> head(matrix)
  ï..    A    B    C    D    E    F    G
1   A 1.00 0.90 0.64 0.43 0.38 0.33 0.33
2   B 0.90 1.00 0.64 0.33 0.43 0.38 0.38
3   C 0.64 0.64 1.00 0.59 0.69 0.64 0.64
4   D 0.43 0.33 0.59 1.00 0.28 0.23 0.28
5   E 0.38 0.43 0.69 0.28 1.00 0.95 0.90
6   F 0.33 0.38 0.64 0.23 0.95 1.00 0.90
> dim(matrix)
[1] 7 8

I then proceed with removing the first column so the matrix is square again...

> matrix <- data.matrix(matrix)[,-1]
> head(matrix)
        A    B    C    D    E    F    G
[1,] 1.00 0.90 0.64 0.43 0.38 0.33 0.33
[2,] 0.90 1.00 0.64 0.33 0.43 0.38 0.38
[3,] 0.64 0.64 1.00 0.59 0.69 0.64 0.64
[4,] 0.43 0.33 0.59 1.00 0.28 0.23 0.28
[5,] 0.38 0.43 0.69 0.28 1.00 0.95 0.90
[6,] 0.33 0.38 0.64 0.23 0.95 1.00 0.90
> dim(matrix)
[1] 7 7

Then I create the graph and try to plot it:

> network <- graph_from_adjacency_matrix(matrix, weighted=T, mode="undirected", diag=F)
> plot(network)

And the result above appears...

So, after spending the last few hours googling and trying way, way more things, this is the closest I've been able to get to.

So I'm asking for your help, thank you very much!

Upvotes: 0

Views: 527

Answers (2)

pat5rg
pat5rg

Reputation: 25

This can be done using Multidimensional Scaling, for example with the package "smacof". First, you have to convert your correlations to distances:

dista <- sim2diss(matrix)

Then run the Multidimensional Scaling on the distances:

MDS <- mds(dista, type="mspline")

Alternative types are ordinal, intervall, and ratio.

Coordinates can be found at MDS$conf. When plotting, your diagramm is nicely reproduced.

plot(MDS$conf,cex=4)
text(MDS$conf,c('A','B','C','D','E','F','G'))

Results for MDS

Note that orientation is arbitrary. You can rotate the coordinated using Rotation from the package "spdep".

Upvotes: 0

pseudospin
pseudospin

Reputation: 2777

This is all fine.

head() just prints out the first 6 rows of a matrix or dataframe, if you want to see all of it use print() or just the name of the matrix variable.

graph_from_adjacency_matrix produces a link between two nodes if the value is non-zero. That's why you are getting every node linked to every other node.

To get what that tutorial is doing you need to add a line like

matrix[matrix<0.5] <- 0

to remove the edges for correlations below a cut off before you create the graph.

It's still not going to produce a chart like your hand drawn one (where closeness is roughly the correlation), just clump them together if they are above 0.5 correlation.

Upvotes: 0

Related Questions