rigraph
rigraph copied to clipboard
R: API for combining attributes from different graphs
From @gaborcsardi on January 4, 2015 13:44
E.g. when taking their union or use some other operator.
Copied from original issue: igraph/igraph#800
:+1:
Any progress on this?
I have been having problems with merging graphs and the resulting attributes. I ended up creating a union2 function. It can merge graphs with overlapping nodes and overlapping attributes. It is probably a bit rough at the moment but may be a helpful start.
https://stackoverflow.com/questions/46172807/maintain-attribute-names-when-merging-igraphs/46338136#46338136
library(dplyr)
union2<-function(g1, g2){
#Creates the union of two networks, and merges attributes with the same name.
#In the case where there are overlapping nodes the attributes of g1 take precedence
#g1 & g2: Igraph networks which should be merged.
g <- union(g1, g2)
#Looks to see which attributes need cleaning
CleanEdgeAttr <- get.edge.attribute(g) %>% names() %>% grepl("(_\\d)$", . )
EdgeNames <- get.edge.attribute(g) %>% names() %>% gsub("(_\\d)$", "", .)
#Looks to see which attributes need cleaning
CleanVertexAttr <- get.vertex.attribute(g) %>% names() %>% grepl("(_\\d)$", . )
VertexNames <- get.vertex.attribute(g) %>% names() %>% gsub("(_\\d)$", "", .)
#Clean up Edges
for( i in unique(EdgeNames[CleanEdgeAttr])){
attr1 <- get.edge.attribute(g, paste0(i, "_1"))
attr2 <- get.edge.attribute(g, paste0(i, "_2"))
g <- set.edge.attribute(g, i, value = ifelse(is.na(attr1), attr2, attr1))
g <- remove.edge.attribute(g, paste0(i, "_1"))
g <- remove.edge.attribute(g, paste0(i, "_2"))
}
#Clean up vertices
for( i in unique(VertexNames[CleanVertexAttr])){
attr1 <- get.vertex.attribute(g, paste0(i, "_1"))
attr2 <- get.vertex.attribute(g, paste0(i, "_2"))
g <- set.vertex.attribute(g, i, value = ifelse(is.na(attr1), attr2, attr1))
g <- remove.vertex.attribute(g, paste0(i, "_1"))
g <- remove.vertex.attribute(g, paste0(i, "_2"))
}
return(g)
}
Would be great to see this implemented, I'm wrestling with my own workarounds for this issue right now. I could see something inspired by the vertex.attr.comb
and edge.attr.comb
arguments to contract()
and simplify()
, although I could only really see the options being either "concat"
, "ignore"
, or "keep"
to preserve the current behavior.
Alternatively, there could be new functions like simplify_edge_attr()
and simplify_node_attr()
which could take a list of attributes to combine, e.g., passing list("length" = c("length_1", "length_2")
would combine length_1
and length_2
into a single attribute length
. This solution is sub-optimal as it would require the user to figure out which attributes to combine first.