require(DCFd) require(ggplot2) require(dplyr) require(igraph)
This is an attempt to provide a simple interface for drawing networks using ggplot()
. I'm trying to get igraph
to do the layout, then let edge properties be set by ggplot.
These are connections among NCI60 cell types, using the correlation between probe expression. They came from the cellCor
data frame in 2013-08-03-DTK-103.Rmd
.
CellEdges <- read.csv("nciNetwork.csv") CellEdges <- select(CellEdges, corr=correlation, one=cellLine, two=otherCellLine)
geom_graph <- function( Edges, from, to, Vertices, x=NULL,y=NULL ) { # Each of these will be a function that draws the # edges and vertices respectively. # Use with a plain ggplot() as the base. geom_graph <- list( edge_geom, vertex_geom ) }
}
The user can hand off a dataframe Pos
that specifies the name, x, and y position of each node. If there is no such array, the Edges
array will be used to extract the vertex names and assign them a position.
Pos
must have only two columns.
For development purposes:
SmallEdges <- head(select(CellEdges,one,two),10) SmallEdges <- mutate(SmallEdges,one=as.character(one), two=as.character(two)) SmallVertices <- with(SmallEdges,data.frame( vertex.names=unique(c(one,two)))) SmallVertices$width = 1:nrow(SmallVertices) SmallVertices$x <- rnorm(nrow(SmallVertices)) SmallVertices$y <- rnorm(nrow(SmallVertices)) SmallNet <- graph.data.frame( SmallEdges )
getGraphPos <- function( Edges, Pos=NULL ) { JustEdges <- Edges[,c(1,2)] origNames <- names(JustEdges)[1:2] names(JustEdges) <- c("FROM","TO") if ( is.null( Pos ) ) { # Construct the locations using igraph # make the graph Net <- graph.data.frame( JustEdges ) where <- layout.fruchterman.reingold( Net ) Pos <- data.frame( x = where[,1], y = where[,2] ) Pos$name <- vertex.attributes( Net )$name } # add the position information to the FROM <- inner_join( JustEdges["FROM"], select(Pos,FROM=name,x,y)) TO <- inner_join( JustEdges["TO"], select(Pos,TO=name,xend=x,yend=y)) FROM$Group <- 1:nrow(FROM) return( cbind(FROM,TO) ) }
Trying to make a dplyr style interface. I want to have the dataframe, then the from
and to
variables identified.
Return an aes() or a geom_segment() that can be used with segments.
testing <- function(.edges, from, to, .vertices=NULL, name, x, y, layout=layout.circle ){ vars <- structure(as.list(match.call()[-1]), class = "uneval") if (missing(from) || missing(to)) stop("Must provide 'from' and 'to' variable names.") From <- eval( vars$from, envir=.edges ) To <- eval( vars$to, envir=.edges ) Edges <- data.frame( from=From, to=To) if ( !is.null(.vertices) ) { if (missing(x) || missing(y)) stop( "Must provide 'name', 'x' and 'y' variable names for vertices.") # User has specified the vertices together with x and/or y positions X <- eval( vars$x, envir=.vertices ) Y <- eval( vars$y, envir=.vertices ) Names <- eval( vars$name, envir=.vertices ) Pos <- data.frame( from=Names, .x.start = Y, .y.start = Y ) } else { # get the positions automatically Net <- graph.data.frame( Edges ) where <- layout.fruchterman.reingold( Net ) Pos <- data.frame( x = where[,1], y = where[,2] ) Pos$name <- vertex.attributes( Net )$name } positionedEdges <- getGraphPos(Edges,Pos) # these should become GEOMS, one for the edges, one for the nodes. return(list(edges=Edges,nodes=Pos)) }
vertexPosition <- function(edges) { # where should the vertices be located. }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.