r - 使用 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 <-
解决方案
我能想到的最快方法是使用该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()