Skip to content

Instantly share code, notes, and snippets.

@coppeliaMLA
Created June 20, 2014 16:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save coppeliaMLA/8528564e394bc8f0bebd to your computer and use it in GitHub Desktop.
Save coppeliaMLA/8528564e394bc8f0bebd to your computer and use it in GitHub Desktop.
Converts a hclust dendrogram into a graph in JSON for input into D3
#Run hclust
hc <- hclust(dist(USArrests[1:40,]), "ave")
#Function for extracting nodes and links
extractGraph<-function(hc){
n<-length(hc$order)
m<-hc$merge
links<-data.frame(source=as.numeric(), target=as.numeric(), value=as.numeric())
for (i in 1:(n-2)){
#Deal with the different kinds of links
#It's not working at the moment because the row numbers for the new nodes don't match the index in the node table
#Will have to track their creation or post hoc adjust them
#and/or because the when two new nodes combine they need to make another new node - in fact in all cases there needs to be another node
n1<-m[i,1]
n2<-m[i,2]
if(n1<0 & n2<0) {links.add<-rbind(c(-n1-1, i+n-1, 1), c(-n2-1, i+n-1, 1))}
else if (n1>0 & n2<0) {links.add<-rbind( c(n+n1-1,i+n-1, 1), c(-n2-1,i+n-1, 1)) }
else if (n1<0 & n2>0) {links.add<-rbind( c(-n1-1,i+n-1, 1), c(n+n2-1,i+n-1, 1)) }
else {links.add<-rbind( c(n+n2-1,i+n-1, 1), c(n+n1-1,i+n-1, 1))}
links<-rbind(links, links.add)
}
names(links)<-c("source", "target", "value")
new.nodes<-paste("node ", (1:max(m))+n)
nodes<-data.frame(name=c(hc$labels, new.nodes), group=c(rep(1, max(m)), rep(2, n)))
return(list(links=links, nodes=nodes))
}
#Load packages for convertinng to JSON
library(rjson)
library(stringr)
#Function for converting to JSON
dfToJSON<-function(df, mode='vector'){
colToList<-function(x, y){
col.json<-list()
#Build up a list of coordinates
for (i in 1:length(x)){
ni<-list(x=x[i], y=y[i])
col.json[[length(col.json)+1]]<-ni
}
return(col.json)
}
if (mode=='vector'){
for.json<-list()
for (j in 1:ncol(df)){
for.json[[length(for.json)+1]]<-list(name=colnames(df)[j] , data=df[,j])
}
}
if (mode=='coords') {
for.json<-list()
for (j in 2:ncol(df)){
for.json[[length(for.json)+1]]<-list(name=colnames(df)[j] , data=colToList(x=df[,1], y=df[,j]))
}
}
if (mode=='rowToObject') {
for.json<-list()
for (j in 1:nrow(df)){
# for.json[[length(for.json)+1]]<-list(df[j,])
for.json[[length(for.json)+1]]<-df[j,]
}
}
jj<-toJSON(for.json)
return(jj)
}
eg<-extractGraph(hc)
e<-dfToJSON(eg$links, 'rowToObject')
n<-dfToJSON(eg$nodes, 'rowToObject')
fileConn<-file("/path/hcGraph.jsonp")
writeLines(paste0("graphIG={ \"nodes\":", n, ", \"links\": ", e, "}"), fileConn)
close(fileConn)
@famibelle
Copy link

Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment