在iGraph(R)

时间:2018-02-16 08:24:52

标签: r igraph graph-theory

根据下图,我想用$ name组合一些边。但是,通过基于它们所连接的顶点进行合并来简化图形很容易,但不能通过某个标签对它们进行分组,在本例中为$ name。

g <- graph(c(1,2, 1,2, 1,2, 2,3, 3,4))
E(g)$weight <- 1:5
E(g)$name <- c("A", "A", "B", "C", "D")

运行simplify函数甚至as.directed\as.undirected时,如果未在edge.attr.comb参数上指定,则删除名称,这非常有意义。但至于指定,我只能选择max或min,或将其转换为字符串。

simplify(g, edge.attr.comb=list(weight = "sum")

我想要的结果是图表中用A标记的边合并/求和,但用B标记的边保持为平行边。 我尝试过几件事都没有成功。

编辑:我知道我可以将图形转换为数据框,将数据分组,然后返回图形。或者在将数据框放入图形之前简单地准备数据框。然而,这太过于摆弄,直接通过igraph更容易。

1 个答案:

答案 0 :(得分:1)

您可以通过转换为数据框然后返回图表来执行此操作:

library(dplyr)
df <- igraph::as_data_frame(g)
df <- df %>% group_by(name) %>% mutate(weight = sum(weight)) %>% unique()
df
# A tibble: 4 x 4
# Groups:   name [4]
from    to weight name 
<dbl> <dbl>  <int> <chr>
1  1.00  2.00      3 A    
2  1.00  2.00      3 B    
3  2.00  3.00      4 C    
4  3.00  4.00      5 D    

g2 <- igraph::graph_from_data_frame(df)

修改

抱歉刚回到这里。是的,我不认为确切的功能存在,这将是很好的。但您可以通过以下两个步骤完成:1)聚合具有共享名称的节点的权重,以及2.)删除重复的边缘

library(dplyr)
library(microbenchmark)
library(igraph)
g <- graph(c(1,2, 1,2, 1,2, 2,3, 3,4))
E(g)$weight <- 1:5
E(g)$name <- c("A", "A", "B", "C", "D")

首先将数据包装到data.frame并返回到函数中:

to_df_and_back <- function(g) {
  df <- igraph::as_data_frame(g)
  df <- df %>% group_by(name) %>% mutate(weight = sum(weight)) %>% unique()
  g2 <- igraph::graph_from_data_frame(df)
  g2
}

现在我们为另一种方法创建一个函数:首先重新计算边缘权重,然后将图形子集合成唯一命名的边缘ID:

add_then_subset <- function(g) {
  E(g)$weight <- ave(E(g)$weight, names(E(g)), FUN=sum)
  g2 <- subgraph.edges(g, eid = E(g)[unique(E(g)$name)])
  g2
}

g1 <- to_df_and_back(g)
g2 <- add_then_subset(g)

identical(E(g1)$weight, E(g2)$weight)
#> [1] TRUE

这里的速度结果意味着重量级和子集策略的速度要快得多(中位数大约是时间的四分之一),但是你想要对你的数据进行测试,因为我不知道不知道它会如何扩展。

microbenchmark(to_df_and_back(g), add_then_subset(g))
#> Unit: milliseconds
#>                expr      min       lq     mean   median       uq       max
#>   to_df_and_back(g) 4.588584 4.851213 6.901448 4.947683 5.130546 182.82945
#>  add_then_subset(g) 1.208795 1.314137 2.138570 1.382700 1.485809  70.16585
#>  neval cld
#>    100   b
#>    100  a