rigraph icon indicating copy to clipboard operation
rigraph copied to clipboard

R: API for combining attributes from different graphs

Open gaborcsardi opened this issue 10 years ago • 4 comments

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

gaborcsardi avatar Jan 14 '15 21:01 gaborcsardi

:+1:

gaborcsardi avatar Jan 11 '16 15:01 gaborcsardi

Any progress on this?

tomkom avatar Jun 14 '17 01:06 tomkom

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)

}

JonnoB avatar Sep 21 '17 07:09 JonnoB

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.

mkoohafkan avatar Mar 29 '21 02:03 mkoohafkan