AfarX

A Rookie of R.

R语言绘制动态关系网络

Menu
  1. 1. 术语(Nomenclature)
    1. 1.1. 边与节点
    2. 1.2. Adjacancy matrix
  2. 2. 数据结构
    1. 2.1. Edge list
    2. 2.2. Node list
  3. 3. 构建节点列表与边列表
  4. 4. 构建网络
  5. 5. 构建动态网络

目前的一些网络分析软件如 Gephicytoscape
在R中可以使用tidyverse的workflow来进行,同时有igraph/ggraph/tigygraph等包,还可以通过htmwidgets框架实现R到JavaScript的转变。

术语(Nomenclature)

边与节点

  • 节点:nodes、vertices
  • 边:edges、links

Adjacancy matrix

The object classes for network, igraph, and tidygraph are all based on adjacency matrices, also known as sociomatrices.
这和tidyverse常用的dataframe不同,因此为了绘制network,需要进行转换。

数据结构

Edge list

Source Target Weight
From to

Node list

id
Name

构建节点列表与边列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
library(stringr)
library(readr)
library(dplyr)
library(tibble)

#library(tidyverse) 可以用这一句代替

# Load data
letters <- read_csv("E://networkViz//GEPHI//edge.csv",
locale=locale(encoding = "GB18030"))
# 防止中文乱码

################################
## Create node and edge lists ##
################################

### Node list ###
sources <- letters %>%
distinct(Source) %>%
rename(label = Source)

destinations <- letters %>%
distinct(Target) %>%
rename(label = Target)

nodes <- full_join(sources, destinations, by = "label")

# Create id column and reorder columns
nodes <- nodes %>% rowid_to_column("id")

### Edge list ###
per_route <- letters %>%
group_by(Source, Target) %>%
summarise(weight = n()) %>%
ungroup()

# Join with node ids and reorder columns
# 将ID于节点名称对应上

edges <- per_route %>%
left_join(nodes, by = c("Source" = "label")) %>%
rename(from = id)

edges <- edges %>%
left_join(nodes, by = c("Target" = "label")) %>%
rename(to = id)

edges <- select(edges, from, to, weight)

得到节点列表与边列表,用于下一步使用。

构建网络

  1. network包
  2. igraph包
  3. tidygraph包:允许管道操作符
  4. ggraph包:允许ggplot2语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#####################
## network package ##
#####################

library(igraph)
routes_igraph <- graph_from_data_frame(d = edges, vertices = nodes, directed = FALSE)
plot(routes_igraph, edge.arrow.size = 7)
#创建igraph对象

library(tidygraph)
library(ggraph)
#两种方法创建tdl_graph对象
routes_tidy <- tbl_graph(nodes = nodes, edges = edges, directed = TRUE)
routes_igraph_tidy <- as_tbl_graph(routes_igraph)

#排序
routes_tidy %>%
activate(edges) %>%
arrange(desc(weight))

#从排序后的tdl_graph对象创建ggraph对象

ggraph(routes_tidy) + geom_edge_link() + geom_node_point() + theme_graph()

#绘图 graphopt
ggraph(routes_tidy, layout = "graphopt") +
geom_node_point() +
geom_edge_link(aes(width = weight), alpha = 0.8) +
scale_edge_width(range = c(0.2, 2)) +
geom_node_text(aes(label = label), repel = TRUE) +
labs(edge_width = "Letters") +
theme_graph()

#绘图 linear
ggraph(routes_igraph, layout = "linear") +
geom_edge_arc(aes(width = weight), alpha = 0.8) +
scale_edge_width(range = c(0.2, 2)) +
geom_node_text(aes(label = label)) +
labs(edge_width = "Letters") +
theme_graph()

构建动态网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
########################
## Interactive network##
########################

library(visNetwork)
library(networkD3)
#绘制visNetwork
visNetwork(nodes, edges)

#指定宽度
edges <- mutate(edges, width = weight/5 + 1)

visNetwork(nodes, edges) %>%
visIgraphLayout(layout = "layout_with_fr") %>%
visEdges(arrows = "middle")

#使用NodeD3绘图,id从0开始
nodes_d3 <- mutate(nodes, id = id - 1)
edges_d3 <- mutate(edges, from = from - 1, to = to - 1)

forceNetwork(Links = edges_d3, Nodes = nodes_d3, Source = "from", Target = "to",
NodeID = "label", Group = "id", Value = "weight",
opacity = 1, fontSize = 16, zoom = TRUE)

#桑基图
sankeyNetwork(Links = edges_d3, Nodes = nodes_d3, Source = "from", Target = "to",
NodeID = "label", Value = "weight", fontSize = 16, unit = "Letter(s)")

参考文献:

  1. Network visualization with R
    http://kateto.net/network-visualization
  2. Introduction to Network Analysis with R
    https://www.jessesadler.com/post/network-analysis-with-r/