合并 Igraph 时维护属性名称
Maintain attribute names when merging Igraphs
问题
我有两个独立的网络,没有重叠的节点或边,它们都具有相同的属性。我想将这两个网络组合成一个网络,然后由两个不同的组件组成。
然而,当我尝试使用 union
命令合并它们时,属性从 "attribute" 重命名为 "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)
解决方法
目前这两个独立的网络源自同一个原始网络,所以我已经能够破解,但情况并非总是如此,我想要一种更 igraph 的方式来合并两者。
黑客在下面
#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 中是否有一个函数可以将两个独立的网络合并为一个网络,同时保持属性不变?
我制作了以下版本的 union,它接受两个具有任意数量重叠属性的图,并将它们合并为一个图,其中属性没有“_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)
问题
我有两个独立的网络,没有重叠的节点或边,它们都具有相同的属性。我想将这两个网络组合成一个网络,然后由两个不同的组件组成。
然而,当我尝试使用 union
命令合并它们时,属性从 "attribute" 重命名为 "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)
解决方法
目前这两个独立的网络源自同一个原始网络,所以我已经能够破解,但情况并非总是如此,我想要一种更 igraph 的方式来合并两者。
黑客在下面
#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 中是否有一个函数可以将两个独立的网络合并为一个网络,同时保持属性不变?
我制作了以下版本的 union,它接受两个具有任意数量重叠属性的图,并将它们合并为一个图,其中属性没有“_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)