首页 > 解决方案 > 使用 purr 通过 tidygraph 将计算映射到不同的网络

问题描述

tidygraph软件包非常适合计算网络统计信息。但是,我有一个具有时间维度的网络,我想计算每个网络的网络统计信息(例如中心性)。(例如,计算每个日期的中心度。)

我想有一种方法可以通过 purrr 和 map 来做到这一点,但我正在努力使用确切的语法。任何帮助在这里表示赞赏。下面的 Repex 示例。

library(tidygraph)
library('purrr')
library(dplyr)
library(tidyr)

# example network data with temporal dimension
edges <- tibble(
  from = c(1, 2, 2, 3, 4, 1, 2, 3, 4, 4, 4, 2), 
  to =   c(2, 3, 4, 2, 1, 2, 3, 4, 3, 2, 1, 3),
  date = c(rep(1,4), rep(2,4), rep(3,4))
)

nodes <- tibble(id = 1:4)

# calculate centrality over all time periods of network
graph <- 
  tbl_graph(
    nodes = nodes,
    edges = edges,
    directed = FALSE
  )

graph_out <- 
  graph %>% 
  mutate(cent_alpha = centrality_alpha()))


# calculate centrality for each time period of the network? 
edges_list <- 
  split(edges, edges$date)

# this doesn't work for me
graph_list <- 
  lmap(edges_list, 
      ~ tbl_graph(nodes = nodes, edges = .x, directed = FALSE))

## Yikes... no idea 
graph_out <-

标签: rpurrrtidygraph

解决方案


我能想到的最快方法是使用该split函数创建一个列表,如果列表中的每个元素都是给定日期的图形结构,则其中的每个元素。然后您可以使用为每个日期map创建一个tidygraph对象,最后为每个日期创建一个中心性度量:

edges %>%
  split(.$date) %>%
  map(~tbl_graph(edges = ., nodes = nodes, directed = FALSE)) %>%
  map(~igraph::alpha_centrality(.))

# $`1`
# [1]  0 -1 -1  0

# $`2`
# [1] -1 -1 -1 -1

# $`3`
# [1]  0 -1 -1 -1

如果您希望一路保存每个步骤,则可以创建一个嵌套表:

df <- 
   edges %>%
   group_by(date) %>%
   nest() %>%
   rename(edges = data) %>%
   mutate(
     graph = map(edges, ~tbl_graph(edges = ., nodes = nodes, directed = FALSE)),
     cent_alpha = map(graph, ~igraph::alpha_centrality(.))
   )


df

## A tibble: 3 x 5
## Groups:   date [3]
#   date edges            graph      cent_alpha  
#  <dbl> <list>           <list>     <list>     
#1     1 <tibble [4 × 2]> <tbl_grph> <dbl [4]>  
#2     2 <tibble [4 × 2]> <tbl_grph> <dbl [4]>  
#3     3 <tibble [4 × 2]> <tbl_grph> <dbl [4]>  

df$cent_alpha

# [[1]]
# [1]  0 -1 -1  0

# [[2]]
# [1] -1 -1 -1 -1

# [[3]]
# [1]  0 -1 -1 -1

最后一种方法的好处是,您可以将有关每个日期的图表的任何类型的数据存储在行中,甚至是绘图:

library(ggraph)
plot_fun <- function(gr){
  gr %>%
    ggraph(layout = "kk") +
    geom_edge_link() + 
    geom_node_point(size = 6, colour = 'steelblue') +
    geom_node_text(aes(label = id), colour = 'white', vjust = 0.4) +
    theme_void()
}

df <-
  df %>%
  mutate(plot = map(graph, ~plot_fun(.)))

cowplot::plot_grid(plotlist = df$plot, labels = df$date, vjust = 5)

图表

如果我们只给定tidygraph对象而不是边缘/节点数据帧,我们可以轻松地创建这些数据帧,如下所示:

edges <- 
  graph %>%
  activate(edges) %>%
  data.frame()

nodes <- 
  graph %>%
  activate(nodes) %>%
  data.frame()

推荐阅读