2013-03-21 14 views
5

Ho un semplice insieme di relazioni direzionali (genitore-> figlio) che voglio disegnare. I miei dati sono strutturati in modo tale che ci siano molte sottoreti discrete. Ecco alcuni dati falsi che assomigliano ai miei.disegnare più reti discrete in R utilizzando igraph

require(igraph) 
parents<-c("A","A","C","C","F","F","H","I") 
children<-c("B","C","D","E","G","H","I","J") 
begats<-data.frame(parents=parents,children=children) 
graph_begats<-graph.data.frame(begats) 
plot(graph_begats) 

Ci sono due distinte sottoreti nei dati falsi, ognuno dei quali è strettamente un lignaggio genitore-figlio. Ho bisogno di disegnare entrambi i lignaggi come reti di alberi nella stessa finestra (idealmente stesso sistema di coordinate dei vertici). Ho provato a usare layout.reingold.tilford(), ma nel migliore dei casi tutto ciò che posso disegnare è uno degli alberi, con tutti gli altri vertici che tracciano in cima al vertice della radice, come questo.

lo<-layout.reingold.tilford(graph_begats,root=1) 
plot(graph_begats,layout=lo) 

Qualche idea per fare questo per un numero arbitrario di linee discrete?

+0

Se ho potuto capire come A) calcolare il numero di linee discreti nell'insieme di dati, e B) assegnare ciascun vertice dei suoi ascendenti, sarei 75% del modo di un soluzione al mio problema. –

+1

Separa la rete, usando 'clusters()' o 'decompose.graph()', quindi calcola il layout separatamente per ciascuno, quindi uniscili, spostando una delle matrici di layout. –

+0

Sì! 'decompose.graph()' è ciò di cui ho bisogno. Sto ancora lavorando al cambio matrice, ma ci sto arrivando. –

risposta

6

Quindi, come ho detto nel commento sopra, una soluzione è calcolare il layout separatamente per ciascun componente. È abbastanza semplice, anche se è necessario del codice per farlo correttamente. Il codice seguente dovrebbe funzionare per un numero arbitrario di componenti. Il primo vertice nell'ordinamento topologico viene utilizzato come nodo radice per ogni albero.

require(igraph) 

## Some data 
parents <- c("A", "A", "C", "C", "F", "F", "H", "I") 
children <- c("B", "C", "D", "E", "G", "H", "I", "J") 
begats <- data.frame(parents=parents, children=children) 
graph_begats <- graph.data.frame(begats) 

## Decompose the graph, individual layouts 
comp <- decompose.graph(graph_begats) 
roots <- sapply(lapply(comp, topological.sort), head, n=1) 
coords <- mapply(FUN=layout.reingold.tilford, comp, 
       root=roots, SIMPLIFY=FALSE) 

## Put the graphs side by side, roots on the top 
width <- sapply(coords, function(x) { r <- range(x[, 1]); r[2] - r[1] }) 
gap <- 0.5 
shift <- c(0, cumsum(width[-length(width)] + gap)) 
ncoords <- mapply(FUN=function(mat, shift) { 
    mat[,1] <- mat[,1] - min(mat[,1]) + shift 
    mat[,2] <- mat[,2] - max(mat[,2]) 
    mat 
}, coords, shift, SIMPLIFY=FALSE) 

## Put together the coordinates for the original graph, 
## based on the names of the vertices 
lay <- matrix(0, ncol=2, nrow=vcount(graph_begats)) 
for (i in seq_along(comp)) { 
    lay[match(V(comp[[i]])$name, V(graph_begats)$name),] <- ncoords[[i]] 
} 

## Plot everything 
par(mar=c(0,0,0,0)) 
plot(graph_begats, layout=lay) 

plot

+0

Grazie mille, Gabor. Questo è esattamente! –

Problemi correlati