【问题标题】:summing weights of edges that are k distances from a subset of nodes in igraph将距 igraph 中节点子集 k 距离的边的权重相加
【发布时间】:2022-01-16 08:25:57
【问题描述】:

我有一个复杂的有向图,在顶点之间有 2 种方式的移动(请参阅下面的虚拟示例)。我正在尝试生成一个输出,该输出将为我提供指向特定目标顶点集的边权重的总和(在下面的示例中,顶点 =“22”,图中为紫色)和那些目标顶点的邻居.我想为目标顶点的 k1(蓝色)和 k2(绿色)邻居确定这一点。

换句话说,对于每个顶点,我试图确定指向目标顶点的所有“外”边缘值的总和以及随后指向目标顶点的 k1 个邻居的所有边缘值的总和。

我拥有的网络很大(905,352 个边和 141,861 个顶点),所以我希望用 igraph 函数解决问题,因为我认为这是最快的方法,但也许我错了。

library(igraph)

# create sample data for reproducible example
from   <- c(1,2,3,3,4,4,4,4,5,6,6,7,8,8,9,9,10,10,11,11,12,12,13,13,13,13,13,13,13,14,15,15)
to     <- c(13,4,7,11,2,6,11,22,4,4,14,13,13,22,13,22,13,22,3,22,5,22,1,7,8,9,10,22,15,6,13,22)
set.seed(22)
weight <-sample(2:200,length(to))

#create dataframe & convert to igraph
graph_df <- data.frame(from,to,weight)
graph <- graph_from_data_frame(graph_df)

#distance to target vertex "22"
dist <- distances(graph,v="22",mode="in",weights=NA)

ggraph(graph, layout = "graphopt") +              
  geom_edge_link(arrow = arrow(length = unit(3, 'mm')), 
                 end_cap = circle(3, 'mm'),
                 aes(width = weight), alpha = 0.8) + 
  scale_edge_width(range = c(0.1, 2)) +
  geom_node_point(aes(color=factor(-dist),size = factor(-dist))) +
  labs(edge_width = "size movement") +
  theme_graph()

期望的输出是:

vertex  1   2   3    4   5   6   7   8   9  10  11  12  13  14  15 22
k1      0   0   0  129   0   0   0  63  66 115 111 162  86   0  92  0  
k2    138  89  45  102  68 177  17 187  32  94   0   0 482   0 118  0
total 138  89 120  416  68 294  17 250  98 209 161 184 658 152 210  0

在哪里

  k1    = sum of edge weights per  vertex on edges from k1 neighbors to target
  k2    = sum of edge weights per vertex on edges from k1 neighbors to target
  total = sum of all outgoing edge weights per vertex (i.e. the weighted out strength)

我尝试使用带有权重的 distances() 函数,它为 k1 邻居提供正确的总和,但不适用于 k2 或更大的总和。

distances(graph,v="22",mode="in")
#result of distances
     1   2   3   4   5   6   7  8  9  10  11  12 13  14 15 22
   224 218 156 129 197 306 103 63 66 115 111 162 86 458 92  0

我在边缘列表数据帧上使用 dplyr 获得了一些运气,但我的假设是有更快的方法来解决这个问题:

#dataframe of k1 neighbors  & summed weight
k1<- graph_df %>%
  mutate(k1 = ifelse(to=="22",weight,NA)) %>%
  group_by(from) %>%
  summarise(total=sum(weight,na.rm=TRUE),
            k1=sum(k1,na.rm=TRUE))

#data frame of k2 neighbors & summed weight
k2 <- graph_df %>% 
  mutate(k2=ifelse(to %in% k1$from[k1$k1>0],weight,NA)) %>%
  group_by(from) %>%
  summarise(k2 =sum(k2,na.rm=TRUE)) 

#join
out <- left_join(k1,k2,by="from") %>% rename(vertex=from) 

# A tibble: 15 × 4
   vertex total    k1    k2
    <dbl> <int> <int> <int>
 1      1   138     0   138
 2      2    89     0    89
 3      3   120     0    45
 4      4   416   129   102
 5      5    68     0    68
 6      6   294     0   177
 7      7    17     0    17
 8      8   250    63   187
 9      9    98    66    32
10     10   209   115    94
11     11   161   111     0
12     12   184   162     0
13     13   658    86   482
14     14   152     0     0
15     15   210    92   118

【问题讨论】:

    标签: r graph igraph


    【解决方案1】:

    也许你可以试试这个

    graph_df %>%
      group_by(from) %>%
      summarise(total = sum(weight)) %>%
      full_join(
        graph_df %>%
          filter(to %in% 22) %>%
          group_by(from) %>%
          summarise(K1 = sum(weight)) %>%
          full_join(
            graph_df %>%
              filter(to %in% neighbors(graph, "22", mode = "in")) %>%
              group_by(from) %>%
              summarise(K2 = sum(weight))
          )
      ) %>%
      arrange(from) %>%
      replace(is.na(.), 0) %>%
      rename(vertex = from)
    

    给了

       vertex total    K1    K2
        <dbl> <int> <int> <int>
     1      1   138     0   138
     2      2    89     0    89
     3      3   120     0    45
     4      4   416   129   102
     5      5    68     0    68
     6      6   294     0   177
     7      7    17     0    17
     8      8   250    63   187
     9      9    98    66    32
    10     10   209   115    94
    11     11   161   111     0
    12     12   184   162     0
    13     13   658    86   482
    14     14   152     0     0
    15     15   210    92   118
    

    【讨论】:

    • 这很棒而且超级快。我想也许在这里使用 tidyverse 比 igraph 的工具更好
    • @samalevy 我没有测试速度,我使用了tidyverseigraph的组合
    猜你喜欢
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2016-05-23
    • 2021-11-03
    • 1970-01-01
    相关资源
    最近更新 更多