2017-09-12 28 views
2

问题

我有两个单独的网络,没有重叠的节点或边,它们都具有相同的属性。我想将这两个网络组合成一个网络,然后由两个不同的组件组成。合并Igraph时维护属性名称

但是,当我尝试使用union命令合并它们时,属性从“属性”重命名为“attribute_1”和“attribute_2”。这会发生在命令帮助文件中,但我找不到合并这两个网络的明显方法。

的情况在下面的代码块

library(igraph) 

#create a 4 node network of two components 
adjmat <- rep(0, 16) 
adjmat[c(2,5,12,15)] <- 1 
g <- graph.adjacency(matrix(adjmat, nrow = 4) , mode = "undirected") 

#give attributes naming the nodes and the edges 
g <- set_vertex_attr(g, "name", value = paste0("Node_", 1:4)) 
g <- set_edge_attr(g, "name", value = paste0("Edge_",1:2)) 

#I am interested in the type attribute 
g <- set_edge_attr(g, "type", value = c("foo", "bar")) 

plot(g) 

#Decompose into seperate networks 
gList <- decompose(g) 

g2 <-union(gList[[1]], gList[[2]]) 

#vertices are fine but edges have been renamed as stated in the helpfile for union. 
get.edge.attribute(g2) 
get.vertex.attribute(g2) 

解决方法

显示目前的两个独立的网络来自同一个原始的网络,所以我已经能够使黑客然而,这”不是个起源总是这样,我想要一个更潦草的方式来融合两者。

的黑客低于

#To solve this problem I do the following 

#Create two dataframes from the edge characteristics of the network and combine into a 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 are now correct 
get.edge.attribute(g3)matrix(adjmat, nrow = 4) 
get.vertex.attribute(g3) 

是否有IGRAPH功能,将两个独立的网络合并成一个单一的网络,同时保持的属性是什么?

回答

1

我制作了以下版本的联合体,它接受具有任意数量的重叠属性的两个图形,并将它们合并到单个图形中,其中属性没有“_x”后缀。这些图可以完全独立或具有重叠的节点。 在重叠的情况下,节点1图表占先

library(dplyr) 
library(igraph) 

union2<-function(g1, g2){ 

#Internal function that cleans the names of a given attribute 
CleanNames <- function(g, target){ 
    #get target names 
    gNames <- parse(text = (paste0(target,"_attr_names(g)"))) %>% eval 
    #find names that have a "_1" or "_2" at the end 
    AttrNeedsCleaning <- grepl("(_\\d)$", gNames) 
    #remove the _x ending 
    StemName <- gsub("(_\\d)$", "", gNames) 

    NewnNames <- unique(StemName[AttrNeedsCleaning]) 
    #replace attribute name for all attributes 
    for(i in NewnNames){ 

    attr1 <- parse(text = (paste0(target,"_attr(g,'", paste0(i, "_1"),"')"))) %>% eval 
    attr2 <- parse(text = (paste0(target,"_attr(g,'", paste0(i, "_2"),"')"))) %>% eval 

    g <- parse(text = (paste0("set_",target,"_attr(g, i, value = ifelse(is.na(attr1), attr2, attr1))"))) %>% 
      eval 

    g <- parse(text = (paste0("delete_",target,"_attr(g,'", paste0(i, "_1"),"')"))) %>% eval 
    g <- parse(text = (paste0("delete_",target,"_attr(g,'", paste0(i, "_2"),"')"))) %>% eval 

    } 

    return(g) 
} 


g <- igraph::union(g1, g2) 
#loop through each attribute type in the graph and clean 
for(i in c("graph", "edge", "vertex")){ 
g <- CleanNames(g, i) 
} 

return(g) 

} 

的属性使用前面的例子

g4 <-union2(gList[[1]], gList[[2]]) 

#As we would like 
get.edge.attribute(g4) 
get.vertex.attribute(g4) 
+0

大的答案。这可以扩展到接受'n'图表的列表吗? – Chuck

+1

使用Reduce(union2,list(...))。然后,列表中的每个图形将合并到一个图中。我认为我们有一个非常类似的问题! –