2.2.1 Undirected and Directed Graphs无向图和有向图
节点的数量order称作阶数 边的数量size称作规模
手动输入小图
# 函数可用于小图 graph_from_literal,用符号文字指定边缘 # 可以是数字 g <- graph_from_literal(1-2,1-3,2-3,2-4,3-5,4-5,4-6,4-7,5-6,6-7) > V(g) 7/7 vertices, named, from 52663b7: [1] 1 2 3 4 5 6 7 > E(g) 10/10 edges from 52663b7 (vertex names): [1] 1--2 1--3 2--3 2--4 3--5 4--5 4--6 4--7 5--6 6--7
输出图的属性
(1)summary.igraph 打印顶点数、边数以及图是否有向。
> summary(g)
IGRAPH 52663b7 UN-- 7 10 --
(2)print_all 打印顶点数、边数以及图是否有向,还列出边,以及可选的图形、顶点和/或边属性。
> print_all(g)
IGRAPH 52663b7 UN-- 7 10 --
+ attr: name (v/c)
+ edges (vertex names):
1 -- 2, 3
2 -- 1, 3, 4
3 -- 1, 2, 5
4 -- 2, 5, 6, 7
5 -- 3, 4, 6
6 -- 4, 5, 7
7 -- 4, 6
(每个节点后,列出所有邻居) (3)str()方法
> str(g)
Class 'igraph' hidden list of 10
$ : num 7
$ : logi FALSE
$ : num [1:10] 1 2 2 3 4 4 5 6 5 6
$ : num [1:10] 0 0 1 1 2 3 3 3 4 5
$ : num [1:10] 0 1 2 3 4 5 6 8 7 9
$ : num [1:10] 0 1 2 3 4 5 6 7 8 9
$ : num [1:8] 0 0 1 3 4 6 8 10
$ : num [1:8] 0 2 4 5 8 9 10 10
$ :List of 4
..$ : num [1:3] 1 0 1
..$ : Named list()
..$ :List of 1
.. ..$ name: chr [1:7] "1" "2" "3" "4" ...
..$ : Named list()
$ :<environment: 0x0000012676236510>
(4)plot(g)
具体如下图:
无向:undirected,定义边的两个节点彼此没有顺序 有向:directed, {u, v} 与 {v, u} 不同 弧:arc,有向边又叫弧 双向:mutual
创建有向图
+表示箭头方向
graph_from_literal(1-+2,2-+3,1-+3) %>% plot()
注意,手动创建有向图时,表示方向的“-+”必须有“+”,否则R会直接忽略不带“+”的边
graph_from_literal(1--2,2-+3,1-+3) %>% plot()
连续两个“++“没有”-"是可以的
graph_from_literal(1++2,2-+3,1-+3) %>% plot()
创建有标签的图
用int作为节点编号,是igraph默认的方式,此时,编号同时作为节点的标签。现实中,我们需要节点有中文标签
# 可以是字母,也可以是汉字
graph_from_literal("a"-"b","b"-"c") %>% plot()
graph_from_literal("张三"-"李四","李四"-"王五","王五"-4,4-a,"张三"-a) %>% plot()
或者,可以在最初创建图形后通过修改图形对象的名称属性来更改顶点标签
> g <- graph_from_literal(1-+2,2-+3,1-+3)
> plot(g)
> V(g)$name
[1] "1" "2" "3"
> V(g)$name <- c("Sam", "Mary", "Tom")
> V(g)$name
[1] "Sam" "Mary" "Tom"
> plot(g)
注意是name不是names
2.2.2 Representations for Graphs 图的表示
有三种基本格式:邻接表adjacency lists、边列表edge list和邻接矩阵 adjacency matrices。
(1)邻接表adjacency lists
图 G 的邻接表表示只是一个大小为 N v N_v Nv 的数组array ,按照 V 中顶点的顺序排序,其中每个元素都是一个列表,其中第 i 个列表包含从 i 到 j 有一条边的所有顶点 j 集合。 print_all 输出的就是邻接表形式。
> print_all(g)
IGRAPH 52663b7 UN-- 7 10 --
+ attr: name (v/c)
+ edges (vertex names):
1 -- 2, 3
2 -- 1, 3, 4
3 -- 1, 2, 5
4 -- 2, 5, 6, 7
5 -- 3, 4, 6
6 -- 4, 5, 7
7 -- 4, 6
(2)边列表edge list
边列表是简单两列列表,由边连接的所有顶点对组成。在 igraph 中,边列表是隐含的,可以用函数 E()
展示
> E(g)
+ 3/3 edges from b2269a0 (vertex names):
[1] Sam ->Mary Sam ->Tom Mary->Tom
但结果放在同一行上,很不直观,可以用as_edgelist()
,结果是两列矩阵
> g <- sample_gnp(10, 2/10)
> as_edgelist(g)
[,1] [,2]
[1,] 4 6
[2,] 1 7
[3,] 3 7
[4,] 1 8
[5,] 2 8
[6,] 7 8
[7,] 5 9
(3)邻接矩阵 adjacency matrices
> g <- graph_from_literal(1-2,1-3,2-3,2-4,3-5,4-5,4-6,4-7,5-6,6-7)
> as_adjacency_matrix(g)
7 x 7 sparse Matrix of class "dgCMatrix"
1 2 3 4 5 6 7
1 . 1 1 . . . .
2 1 . 1 1 . . .
3 1 1 . . 1 . .
4 . 1 . . 1 1 1
5 . . 1 1 . 1 .
6 . . . 1 1 . 1
7 . . . 1 . 1 .
(4)igraph与pajek数据互通
write.graph(g,"g.net",format = "pajek")
用read_graph("g.net",format = "pajek")
根据文件内容格式不同,有的导入失败
> read_graph("Dormitory.net",format = "pajek")
Error in read.graph.pajek(file, ...) :
At core/io/pajek.c:168 : Parse error in Pajek file, line 1 (syntax error, unexpected ALNUM, expecting NEWLINE or NUM), Parse error
但可以用pajek直接打开R
- 在pajek中,单击 Tools> R> Locate R 命令并找到文件 rgui.exe 或 rterm.exe
- Tools> R>Send to R >Current Network
因为无法直接在Rstudio中打开,所有可以save.image()
,再在Rstudio中编辑
2.2.3 Operations on Graphs 图的操作
提取图的一部分,删除节点,增加边,合并多个图
(1)导出子图
如果 V H ⊆ V G & E H ⊆ E G V_H ⊆ V_G \& E_H ⊆ E_G VH⊆VG&EH⊆EG ,则图 H = (V H , E H ) 是图 G = (VG , E G ) 的。 图 G 的:即子图 G′ = (V′, E′),其中 V′ ⊆ V 是预先指定的节点子集, E′ ⊆ E 是G中这些节点间存在的所有边的集合。
h <- induced.subgraph(g,1:5)
plot(h)
print_all(h)
print_all(g)
因为导出子图实际是先选择要保留的顶点、进而根据这些顶点再确定边,所以,也可用原图减去vertice
和edges
实现
m <- g-vertices(c(6,7))
> print_all(m)
IGRAPH b0ad7f7 UN-- 5 6 --
+ attr: name (v/c)
+ edges from b0ad7f7 (vertex names):
[1] 1--2 1--3 2--3 2--4 3--5 4--5
> print_all(h)
IGRAPH a0acc4a UN-- 5 6 --
+ attr: name (v/c)
+ edges from a0acc4a (vertex names):
[1] 1--2 1--3 2--3 2--4 3--5 4--5
但用导出子图无法逆推原图,加vertice
会只加节点,边需要另外增加
(h+vertices(c(6,7))) %>% plot()
增加边:每条边用两个顶点表示,并用c()
连接:
h <- h+vertices(c(6,7))
(h+edges(c(1,6),c(7,5),c(7,3))) %>% plot()
注意+vertices()
,里面的节点ID是任意的,不必连续
(h+vertices(c(9,15))) %>% plot()
(2)基于集合的操作
并union、可区分的并disjoint union、交intersection、差difference都可用于图 在使用union时要注意,如果使用节点编号作为标签,如果两个图的标签相同,则视为同一节点,如
> m <- graph_from_literal(1-2,1-3,1-4,2-3,3-4)
> graph.union(h,m) %>% plot()
> m <- graph_from_literal(4-5,4-6,4-7,5-6,6-7)
> graph.union(h,m) %>% plot()
但虽然用int创建图,后赋予不同的标签,虽然创建时节点ID相同,因为标签不同,igraph也认为是不同节点
> V(h)$name <- letters[1:5]
> m <- graph_from_literal(1-2,1-3,1-4,2-3,3-4)
> V(m)$name <- letters[7:10]
> graph.union(h,m) %>% plot()
如果不想创建标签,同时让igraph把两个图中的相同数字作为不同的节点,需要用disjoint uion
> g1 <- make_star(10, mode="undirected")
> g2 <- make_ring(10)
> par(mfrow=c(1,2))
> (g1 %du% g2) %>% plot()
> (g1 %u% g2) %>% plot()
交集必须两个图的节点和边都相同
> (g1 %s% g2) %>% plot()
> V(g1)$name <- letters[1:10]
> V(g2)$name <- letters[11:20]
> (g1 %s% g2) %>% plot()
2.3 Decorating Network Graphs修饰网络图
图代表的是一种结构,由节点和边构成,但在实际中这远远不够,所以,把其他数据作为图的属性出现,而把图和属性装备equip with起来的过程,就是图的修饰。
(1)节点、边和图的属性
节点、边和图本身都是对象,都可用有自己的属性,对象与属性之间,用$
操作符
> V(g1)$name
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
属性可以视为变量,可用任意命名
> V(dg)$gender <- c("M","F","M")
> V(g)$color <- "red"
(2)含权图 weighted graph
边具有权重的图,叫含权图
> is.weighted(g)
[1] FALSE
> E(g)$weight <- runif(ecount(g))
> is.weighted(g)
[1] TRUE
(3) 使用数据框
手动输入只限于小图,大图需要通过数据框或文件输入。 用数据框输入,可用两个文件:一个文件用来规定节点属性,其中第一列是节点名,其他列是节点属性;另一个文件用来规定边的属性,其中前两列是边的两个节点,其余的列是边的属性
> library(sand)
> data("elist.lazega")
> elist.lazega
V1 V2
1 V1 V17
2 V2 V7
3 V2 V16
4 V2 V17
其中规定边属性的data frame只需限定图的网络结构即可
> g <- graph_from_data_frame(elist.lazega)
> vcount(g)
[1] 34
> ecount(g)
[1] 115
> vertex.attributes(g)
$name
[1] "V1" "V2" "V3" "V4" "V5" "V6" "V7" "V9" "V10" "V11" "V12" "V13" "V14" "V15" "V16"
[16] "V17" "V18" "V19" "V20" "V21" "V22" "V24" "V25" "V26" "V28" "V29" "V30" "V31" "V32" "V33"
[31] "V34" "V35" "V36" "V27"
> vertex_attr_names(g)
[1] "name"
节点属性,可用节点的data frame来设置
> v.attr.lazega
Name Seniority Status Gender Office Years Age Practice School
1 V1 1 1 1 1 31 64 1 1
2 V2 2 1 1 1 32 62 2 1
3 V3 3 1 1 2 13 67 1 1
4 V4 4 1 1 1 31 59 2 3
5 V5 5 1 1 2 31 59 1 2
生成图时直接引用即可
> g <- graph_from_data_frame(elist.lazega,directed = FALSE,vertices = v.attr.lazega) > vertex.attributes(g) $name 标签:
400v25kvar电容电抗器