You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What is the feature or improvement you would like to see?
I would like to make a multilayer network, implemented as an edge-colored multigraph, with a single function call in igraph. Specifically, I would like to make a multigraph M from from several graphs or digraphs {g1, g2, ...} which includes all vertices from {V1, V2, ...} and all edges from {E1, E2, ...}. M should contain an edge (u, v) if any {E1, E2, ...} contains (u, v). Additionally, if several (u, v) exist, I would like to retain all such edges in M. I would like to retain vertex and edge information from {g1, g2, ...} and also add a label to each edge in M specifying its originating graph.
I think my request is related to #1345 but I would like to (a) retain node and edge attributes, and (b) keep all component edges rather than merge multiple edges between the same vertices.
My attempt is below. The function works by adding a "layer" attribute to each edge, which is the name of the graph if present, then using rbind() on the vertex and edge data frames. The resulting multigraph is directed if any of the component networks is.
make_edge_colored_graph<-function(..., list=character()) {
if(length(list) >0) {
gl<-list
} else {
gl<-list(...)
}
## Need all original vertex and edge attributes to be the same in order to use the rbind solution, belowvattr<- lapply(gl, vertex_attr_names)
eattr<- lapply(gl, edge_attr_names)
## https://stackoverflow.com/questions/18813526/check-whether-all-elements-of-a-list-are-in-equal-in-ridenticalValue<-function(x,y) if (identical(x,y)) xelseFALSEif(isFALSE(Reduce(identicalValue, vattr))) stop("Vertices in all graphs must have the same attributes.")
if(isFALSE(Reduce(identicalValue, eattr))) stop("Edges in all graphs must have the same attributes.")
## The new graph should have an edge attribute called "layer" that labels each edge by its originating graphuse.graph.names<- all(sapply(gl, function(g) !is.null(g$name)))
if(use.graph.names) {
gl<- lapply(gl, function(g) {
E(g)$layer<-g$nameg
})
} else {
gl<- mapply(
function(g, int) {
E(g)$layer<-intg
}, gl, seq_along(gl)
)
}
## From here I can use data frames, but is there a better way to do this?edfs<- lapply(gl, as_data_frame, "edges")
edf<- do.call(rbind, edfs)
vdfs<- lapply(gl, as_data_frame, "vertices")
vdfs<- lapply(vdfs, function(df) {
old<- colnames(df)
if(!("name"%in% colnames(df))) { # Make a "name" attribute if not present to support !duplicated(), belowdf$name<- rownames(df)
df<-df[, c("name", old)]
}
df
})
vdf<- do.call(rbind, vdfs)
vdf<-vdf[!duplicated(vdf), ]
g<- graph_from_data_frame(edf, vertices=vdf, directed= any(sapply(gl, is_directed)))
return(g)
}
Use cases for the feature
As I understand it, igraph doesn't support multilayer networks per se and probably won't at least in the near future. However, it seems that edge-colored multigraphs are possible. For the time being, I just wanted to make an edge-colored multigraph to visualize several layers of a social network. I don't know if my implementation, above, is good enough to be useful for algorithms, but maybe it could be improved?
It looks like other people are interested in doing something similar:
What is the feature or improvement you would like to see?
I would like to make a multilayer network, implemented as an edge-colored multigraph, with a single function call in igraph. Specifically, I would like to make a multigraph M from from several graphs or digraphs {g1, g2, ...} which includes all vertices from {V1, V2, ...} and all edges from {E1, E2, ...}. M should contain an edge (u, v) if any {E1, E2, ...} contains (u, v). Additionally, if several (u, v) exist, I would like to retain all such edges in M. I would like to retain vertex and edge information from {g1, g2, ...} and also add a label to each edge in M specifying its originating graph.
I think my request is related to #1345 but I would like to (a) retain node and edge attributes, and (b) keep all component edges rather than merge multiple edges between the same vertices.
My attempt is below. The function works by adding a "layer" attribute to each edge, which is the name of the graph if present, then using rbind() on the vertex and edge data frames. The resulting multigraph is directed if any of the component networks is.
And here is a demonstration:
Use cases for the feature
As I understand it, igraph doesn't support multilayer networks per se and probably won't at least in the near future. However, it seems that edge-colored multigraphs are possible. For the time being, I just wanted to make an edge-colored multigraph to visualize several layers of a social network. I don't know if my implementation, above, is good enough to be useful for algorithms, but maybe it could be improved?
It looks like other people are interested in doing something similar:
References
Kivelä, Mikko, et al. "Multilayer networks." Journal of Complex Networks 2.3 (2014): 203-271.
The text was updated successfully, but these errors were encountered: