r - Maintain attribute names when merging Igraphs -
problem
i have 2 separate networks no overlapping nodes or edges, both have same attributes. want combine these 2 networks single network made of 2 distinct components.
however when try merge them using union
command attributes renamed "attribute" "attribute_1" , "attribute_2". happen stated in command file, cannot find obvious way merge these 2 networks.
the situation shown in below code block
library(igraph) #create 4 node network of 2 components adjmat <- rep(0, 16) adjmat[c(2,5,12,15)] <- 1 g <- graph.adjacency(matrix(adjmat, nrow = 4) , mode = "undirected") #give attributes naming nodes , edges g <- set_vertex_attr(g, "name", value = paste0("node_", 1:4)) g <- set_edge_attr(g, "name", value = paste0("edge_",1:2)) #i interested in type attribute g <- set_edge_attr(g, "type", value = c("foo", "bar")) plot(g) #decompose seperate networks glist <- decompose(g) g2 <-union(glist[[1]], glist[[2]]) #vertices fine edges have been renamed stated in helpfile union. get.edge.attribute(g2) get.vertex.attribute(g2)
work around
currently 2 separate networks originate same original network have been able make hack isn't case , more igraph way of merging two.
the hack below
#to solve problem following #create 2 dataframes edge characteristics of network , combine single dataframe p <- rbind(as_data_frame(glist[[1]]), as_data_frame(glist[[2]])) g3 <- set.edge.attribute(g, "type", value = p$type[match(p$name, get.edge.attribute(g, "name"))]) #edges correct get.edge.attribute(g3)matrix(adjmat, nrow = 4) get.vertex.attribute(g3)
is there function in igraph merge 2 seperate networks single network whilst maintaining attributes is?
i have made below version of union, accepts 2 graphs arbitrary number of overlapping attributes , merges them single graph attributes not have "_x" suffix. graphs can entirely independent or have overlapping nodes. in case of overlapping nodes attributes of graph 1 take precedence
library(dplyr) union2<-function(g1, g2){ #creates union of 2 networks, , merges attributes same name. #in case there overlapping nodes attributes of g1 take precedence #g1 & g2: igraph networks should merged. g <- union(g1, g2) #looks see attributes need cleaning cleanedgeattr <- get.edge.attribute(g) %>% names() %>% grepl("(_\\d)$", . ) edgenames <- get.edge.attribute(g) %>% names() %>% gsub("(_\\d)$", "", .) #looks see attributes need cleaning cleanvertexattr <- get.vertex.attribute(g) %>% names() %>% grepl("(_\\d)$", . ) vertexnames <- get.vertex.attribute(g) %>% names() %>% gsub("(_\\d)$", "", .) #clean edges for( 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 vertices for( 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) }
using previous example
g4 <-union2(glist[[1]], glist[[2]]) #as get.edge.attribute(g4) get.vertex.attribute(g4)
Comments
Post a Comment