网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
前情回顾:
Gephi网络图极简教程
Network在单细胞转录组数据分析中的应用
网络数据统计分析笔记|| 为什么研究网络
书接上回,我们来看看如何构建网络以及可以对网络做的基本操作,主要用的R包是igraph。

  • 创建网络图
  • 图的表示
  • 图的增删
  • 图的修饰
  • 图的属性
网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
igraph是一个用于创建和操作图以及分析网络的R包。它是用C编写的,也以Python和R包的形式存在。此外,还存在一个Mathematica接口。该软件广泛应用于网络科学及相关领域的学术研究。据谷歌Scholar统计,截止2015年6月5日,介绍该软件的出版物有5623次引用。
创建网络图 网络用节点描述元素,用连线描述元素间关系。一个图是包含节点集合与边集合的数学结构。其中节点数称为图的阶数(order),边的数量称为图的规模(size)。
在创建图之前我们来认识一下igraph包。
# install.packages("pacman") rm(list = ls()) library(sand)# CHUNK 1 library(igraph) library(pacman) length(p_functions(igraph)) [1] 784 grep('graph_from',p_functions(igraph),value = https://www.it610.com/article/T) [1]"graph_from_adj_list""graph_from_adjacency_matrix""graph_from_atlas" [4] "graph_from_data_frame""graph_from_edgelist""graph_from_graphdb" [7] "graph_from_graphnel""graph_from_incidence_matrix""graph_from_isomorphism_class" [10] "graph_from_lcf""graph_from_literal"

可以看到igraph 共有 784个函数,其中读入数据的有11个,功能可谓是全的很啊。我们先从最简单的做起,构建一个手写的图:
g <- graph_from_literal(1-2, 1-3, 2-3, 2-4, 3-5, 4-5, 4-6, 4-7, 5-6, 6-7)plot(g)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片

查看图的属性
V(g) + 7/7 vertices, named, from e2c1098: [1] 1 2 3 4 5 6 7 E(g) + 10/10 edges from e2c1098 (vertex names): [1] 1--2 1--3 2--3 2--4 3--5 4--5 4--6 4--7 5--6 6--7 print_all(g) IGRAPH e2c1098 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

在g的结构描述中,字母U表示该图是无向的(undirected),即一条边的两个节点没方向和次序。简单有向图可以这样构建:
dg <- graph_from_literal(1-+2, 1-+3, 2++3) plot(dg)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
要想使图有意义,我们就需要给图起名字:
par(mfrow=c(1,3)) dg <- graph_from_literal(1-+2, 1-+3, 2++3) plot(dg) dg <- graph_from_literal(Sam-+Mary, Sam-+Tom, +Mary++Tom) print_all(dg)IGRAPH ea00245 DN-- 3 4 --# UN 变成DN + attr: name (v/c) + edges from ea00245 (vertex names): [1] Sam ->Mary Sam ->TomMary->TomTom ->Mary plot(dg)V(dg)$name <- c("Sam1", "Mary1", "Tom_1")E(dg) + 4/4 edges from ea00245 (vertex names): [1] Sam1 ->Mary1 Sam1 ->Tom_1 Mary1->Tom_1 Tom_1->Mary1 > # --- > ## + 4/4 edges from 062bf79 (vertex names): > ## [1] Sam ->Mary Sam ->TomMary->TomTom ->Mary > # --- plot(dg)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
我们无法想象手动用+-号来构建一个成千上百的网络图,一般的图都是在数据文件里,存在三种表示图的格式:
  • 邻接列表
  • 边列表
  • 邻接矩阵
邻接表(graph_adjacency_list):邻接表是图的一种链式存储结构。在邻接表中,对图中每一个顶点建立一个单链表,第i个单链表中的节点表示依附于顶点vi的边(对有向图是以顶点vi为尾的弧)。每一个结点有三个域组成,当中邻接点域指示与顶点vi邻接的点在途中的位置,链域指示下一条边或者弧的结点;数据域存储和边或者弧相关的信息。如权值等。每一个链表上附设一个表头结点。
边列表简单来说就是边跟边的两个顶点。
E(dg) + 4/4 edges from ea00245 (vertex names): [1] Sam1 ->Mary1 Sam1 ->Tom_1 Mary1->Tom_1 Tom_1->Mary1

图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。
设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
as_adjacency_matrix(dg) 3 x 3 sparse Matrix of class "dgCMatrix" Sam1 Mary1 Tom_1 Sam1.11 Mary1..1 Tom_1.1.

三者之间的对应 关系可以用下图表示:
网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
鉴于矩阵是多数编程语言的基本数据对象,邻接矩阵经常作为网络图的存储方式。但是如果是大型的网络,如果不转化为稀疏矩阵,一般的矩阵会非常低效。在文章的开头我们展示了几个其他数据读入igraph的函数,以生成对应的网络。read_graph函数能够从文件或http连接读取各种表示形式的图形。
igraph绘制的网络图导入到gephi
install and load install.packages("rgexf", dependencies=TRUE) library(rgexf) cg1 <- erdos.renyi.game(10, 0.8) nodes <- data.frame(cbind(V(cg1), as.character(V(cg1)))) edges <- t(Vectorize(get.edge, vectorize.args='id')(cg1, 1:ecount(cg1))) write.gexf(nodes, edges)

图的表示 刚生成或者导入的图可能不是我们需要的图,对图的各种操作不可或缺,包括取子图、删节点,增加边,甚至是合并图。在一张图上有了感兴趣的区域,我们一般会采取取子图的操作,子图的定义是某图的边和点均来自母图。如取g前5个节点的子图:
h <- induced_subgraph(g, 1:5) print_all(h) IGRAPH ae29f26 UN-- 5 6 -- + attr: name (v/c) + edges from ae29f26 (vertex names): [1] 1--2 1--3 2--3 2--4 3--5 4--5 plot(h)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
图中节点和边的纳入与删除,可以通过对集合和使用加号或减号操作符实现。上面的图可以:
h <- g - vertices(c(6,7)) print_all(h) plot(h)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
相似地,g也可以由h生成:
h <- h + vertices(c(6,7)) g <- h + edges(c(4,6),c(4,7),c(5,6),c(6,7)) print_all(g) IGRAPH 77655ae 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 plot(g)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
图的并,交,差,补。
图的并集
h1 <- h h2 <- graph_from_literal(4-6, 4-7, 5-6, 6-7) g <- graph.union(h1,h2) print_all(g) IGRAPH 1cc06a7 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 plot(g)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
网络图的修饰 一幅图(graph,network)要有实际的意义,就要有与相应的网络图所关联的值。将一个图与这些属性(attributes)关联在一起的过程称为图的修饰(decorating)。在igraph中节点和边的属性可以通过$符号获得和修改。
V(dg)$name [1] "Sam""Mary" "Tom" V(dg)$gender <- c("M","F","M")V(g)$color <- c("red","blue") plot(g)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
也可以将某些计算的节点特征值用这种方式保存,并用于可视化化或者统计。
同样地,边的属性用于描述元素之间的关系,如强弱,正负等。边的属性在在许多分析中可以认为是权重,有权重的图称为含权图(weighted graph)。
is_weighted(g) [1] FALSEwg <- g E(wg)$weight <- runif(ecount(wg)) is_weighted(wg) [1] TRUE plot(wg)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
其实图本身也可以有属性,如:
g$name <- "Toy Graph"

使用数据框
大型的网络图不可能手动输入,而是采用数据框来存储和读入。igraph的节点和边属性可以存在节点和边文件的数据框中。
library(sand) head(elist.lazega) V1V2 1 V1 V17 2 V2V7 3 V2 V16 4 V2 V17 5 V2 V22 6 V2 V26 head(v.attr.lazega) Name Seniority Status Gender Office Years Age Practice School 1V11111316411 2V22111326221 3V33112136711 4V44111315923 5V55112315912 6V66112295511> g.lazega <- graph_from_data_frame(elist.lazega, +directed="FALSE", +vertices=v.attr.lazega) > g.lazega$name <- "Lazega Lawyers" > # CHUNK 21 > vcount(g.lazega) [1] 36 > # CHUNK 22 > ecount(g.lazega) [1] 115 > # CHUNK 23 > vertex_attr_names(g.lazega) [1] "name""Seniority" "Status""Gender""Office""Years""Age""Practice""School" > # --- > ## [1] "name""Seniority" "Status""Gender" > ## [5] "Office""Years""Age""Practice" > ## [9] "School" > # --- > plot(g.lazega)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
V(g.lazega)$color= V(g.lazega)$Seniority plot(g.lazega)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
关于图 简单图:在无向图中,关联一对顶点的无向边如果多于1条,则称这些边为平行边,平行边的条数称为重数。在有向图中,关联一对顶点的有向边如果多于1条,并且这些边的始点与终点相同(也就是它们的的方向相同),称这些边为平行边。含平行边的图称为多重图,既不含平行边也不包含自环的图称为简单图。
is_simple(g) [1] TRUE

构建多重图
mg <- g + edge(2,3) is_simple(mg) [1] FALSEprint_all(mg) plot(mg)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
在网络数据分析中,常需要将多重图转化为加权的简单图:
E(mg)$weight <- 1 # plot(mg) # ?simplify wg2 <- igraph::simplify(mg) is_simple(wg2) [1] TRUEprint_all(wg2) IGRAPH c219b27 UNW- 7 10 -- + attr: name (v/c), color (v/c), weight (e/n) + 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, 6E(wg2)$weight [1] 1 1 2 1 1 1 1 1 1 1plot(wg2)

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
图的连通性,如果两个节点之间通过一条边链接,我们称两者是邻接的(adjacent),这些节点可以称为邻居(neighbors)。
neighbors(g,5)+ 3/7 vertices, named, from 1cc06a7: [1] 3 4 6

类似地,两条边通过一个节点相连,称两者是邻接的。节点的度(degree)定义为其关联的边的数量。
degree(g) 1 2 3 4 5 6 7 2 3 3 4 3 3 2

如果是有向图,节点度可以进一步分为入度(in-degree)与出度(out-degree)分别代表指向与离开节点边的数量。
degree(dg, mode="in") Sam MaryTom 022 degree(dg, mode="out") Sam MaryTom 211

描述图移动的概念:
通路(walk)是一个节点和边交替的序列
通路的长度length
不存在重复边的通路为迹(trail)
不存在重复节点的通路为路径(path)
起点和终点相同的迹为回路(circuit)
如果图中存在节点到另一个节点的一条通路,则可称节点到是可达的(reachable),若所有节点从任意节点均可达,则称图是连通的(connected)。图的组件(component)是一个最大化的连通子图。
is_connected(g) [1] TRUE clusters(g) $membership 1 2 3 4 5 6 7 1 1 1 1 1 1 1 $csize [1] 7$no [1] 1

对于有向图,有弱连通和强连通之别:
is_connected(dg,mode="weak") [1] TRUEis_connected(dg,mode="strong") [1] FALSE

图中节点的距离(distance),被定义为节点间最短路径长度。图中最长的距离的值称为直径(diameter)
diameter(g, weights=NA) [1] 3

特殊类型的图
g.full <- make_full_graph(7) g.ring <- make_ring(7) g.tree <- make_tree(7, children=2, mode="undirected") g.star <- make_star(7, mode="undirected") par(mfrow=c(2, 2), mai = c(0.2, 0.2, 0.2, 0.2)) plot(g.full,main='compele graph') plot(g.ring,main= 'regular graph') plot(g.tree,main='tree') plot(g.star,main='star')

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
一个无环的有向图称做有向无环图(directed acycline praph)。简称DAG 图。DAG 图是一类较有向树更一般的特殊有向图。
is_dag(dg) [1] FALSE

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
g.bip <- graph_from_literal(actor1:actor2:actor3, movie1:movie2, actor1:actor2 - movie1, actor2:actor3 - movie2) V(g.bip)$type <- grepl("^movie", V(g.bip)$name) print_all(g.bip, v=T)IGRAPH f306940 UN-B 5 4 -- + attr: name (v/c), type (v/l) + vertex attributes: |nametype | [1] actor1 FALSE | [2] actor2 FALSE | [3] actor3 FALSE | [4] movie1TRUE | [5] movie2TRUE + edges from f306940 (vertex names): [1] actor1--movie1 actor2--movie1 actor2--movie2 actor3--movie2

图的投影
proj <- bipartite_projection(g.bip) print_all(proj[[1]]) IGRAPH 9a82b4d UNW- 3 2 -- + attr: name (v/c), weight (e/n) + edges from 9a82b4d (vertex names): [1] actor1--actor2 actor2--actor3print_all(proj[[2]]) IGRAPH 9a82b4d UNW- 2 1 -- + attr: name (v/c), weight (e/n) + edge from 9a82b4d (vertex names): [1] movie1--movie2

par(mfrow=c(1, 3), mai = c(0.2, 0.2, 0.2, 0.2)) plot(g.bip) plot(proj[[1]]) plot(proj[[2]])

网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据
文章图片
【网络数据统计分析笔记|网络数据统计分析笔记|| 操作网络数据】https://igraph.org/r/
存储在图的形式——邻接列表
https://visualgo.net/zh/graphds
https://gk.palem.in/iGraphExport.html
https://www.cnblogs.com/alan-blog-TsingHua/p/10924894.html

    推荐阅读