Correlation network

I came up with an idea to draw correlation network to get a grasp about relationship between a list of stocks. An alternative way to show correlation matrix would be head map, which can have limitations with big matrices (>100).
Unfortunately,  ggplot2 package doesn’t have a easy way to draw the networks, so I was left with igraph or network. I tried both, but somehow chose igraph. If you want to master either package I highly recommend to start from theoretical part – it is very well written and it will save your time trying to understand the package’s conception.

Here is correlation matrix of stocks, which correlation coef. is more than 0.5:
correlation_network

?View Code RSPLUS
require(xts)
require(quantmod)
require(igraph)
cor_mat<- matrix( runif(100), nr=10 )
cor_mat[ lower.tri(cor_mat, diag=TRUE) ]<- 0
cor_mat[ abs(cor_mat) < 0.5]<- 0
 
graph <- graph.adjacency(cor_mat>0.5, weighted=TRUE, mode="upper")
E(graph)$weight<-t(cor_mat)[abs(t(cor_mat))>0.5]
E(graph)[ weight>0.7 ]$color <- "black" E(graph)[ weight>=0.65 &amp; weight<0.7 ]$color <- "red" E(graph)[ weight>=0.6 &amp;weight<0.65 ]$color <- "green" E(graph)[ weight>=0.55 &amp;weight<0.6 ]$color <- "blue"
E(graph)[ weight<0.55  ]$color <- "yellow"
V(graph)$label<- seq(1:10)#V(graph)$name
graph$layout <- layout.fruchterman.reingold
factor<-as.factor(cut(E(graph)$weight*10,c(4,5,6,7,8),labels=c(1,10,20,30))) png('corr_network.png',width=500) plot(decompose.graph(graph)[[which.max(sapply(decompose.graph(graph), vcount))]],edge.width =as.numeric(factor)*1.5,frame=T) legend("bottomleft", title="Colors", cex=0.75, pch=16, col=c("black", "blue","red", "green","pink"), legend=c(">70%", "65-70","60-65","55-60","50-55"), ncol=2)
dev.off()

The code can be found on github.

10 Comments »

  1. Justas said,

    March 22, 2011 @ 19:57

    How many days/months did you take for calculating correlations?

  2. Dzidorius Martinaitis said,

    March 22, 2011 @ 20:18

    60 working days

  3. Tal Galili said,

    March 23, 2011 @ 7:25

    Great idea!
    I wonder how it might be improved…

    Best,
    Tal

  4. Justas said,

    March 23, 2011 @ 9:19

    Well, it might be improved by using some other visualization tools to see how correlations change over time. For instance, start from Year X and and end at Year Z and we would see how relationships vary.

  5. Jens said,

    March 23, 2011 @ 16:50

    Thank you, nice idea!

    I adapted this immediately to an analysis of couple behaviours and attitudes.One point that gave me a headache was labeling the vertices, that part was missing from your code example. I accomplished this by (simplified code snippet) :

    g <- decompose.graph(graph)[[which.max(sapply(decompose.graph(graph), vcount))]]
    plot(g, vertex.label=V(g)$name)

    Regards, jens

  6. Dzidorius Martinaitis said,

    March 23, 2011 @ 17:01

    Jens,
    it is hidden on this line:
    V(graph)$label<- seq(1:10)#V(graph)$name

    For my personal use I generated correlation matrix from the real data, but then I wrote this post, I generated random matrix and assigned the names like seq(1:10). If you want the nice labels on vertices, you can do your way or this way:
    V(graph)$label<-V(graph)$name
    Thanks for pointing out the problems!

  7. DavidC said,

    March 24, 2011 @ 3:35

    This is great. Thanks!

  8. Tal Galili said,

    March 24, 2011 @ 8:47

    Hi there,
    I just found a way for plotting a network in ggplot2:
    http://www.r-bloggers.com/basic-ggplot2-network-graphs-ver2/

    I’d be glad to see you use it for the correlation networks :)

    Cheers,
    Tal

  9. Sacha Epskamp said,

    March 26, 2011 @ 14:36

    You might also be interested in my package which is focussed around doing just this :)

    https://sites.google.com/site/qgraphproject/examples

  10. zubin said,

    April 24, 2011 @ 23:08

    the qgraph package referenced above is amazing. just tried it out, correlation networks are extremely intuitive.

RSS feed for comments on this post · TrackBack URI

Leave a Comment