sand包
数据集收集到一个名为sand的独立R包中用于“网络数据统计分析。
#1
#install.packages("sand")
library(sand)
#install_sand_packages()
#?sand
创建网络图
无向图和有向图
在igraph中有一个用于图形的“igraph”类。在本节中,我们将看到在R中创建igraph类对象的多种方法,以及提取和总结该对象中的信息的各种方法。
无向图
#2.1.1
library(igraph)
g <- graph.formula(1-2, 1-3, 2-3, 2-4, 3-5, 4-5, 4-6,4-7, 5-6, 6-7)
V(g) #显示图的顶点(vertexs)信息
E(g) #显示边(edges)信息
g
#str(g)
get.adjacency(g) # 获得邻接矩阵
#可视化
plot(g)
有向图
#图中的有向边。公式用正负约定表示。
#2.1.2
dg <- graph.formula(1+-2, 1-+3, 2++3)
plot(dg)
dg2 <- graph.formula(Sam-+Mary, Sam-+Tom, Mary++Tom)
dg2
plot(dg2)
# 改节点名
V(dg)$name <- c("Sam", "Mary", "Tom")
plot(dg)
修改操作图(Operations on Graphs)
我们能够加载到R中的图形可能不是我们最终想要的图形。可能需要对图进行各种操作,包括提取图的一部分、删除顶点、添加边,甚至组合多个图。
图的“部分”概念是通过子图的概念获得的。例如,考虑由前5个顶点导出的g的子图
#2.1.3
#获取节点1-5
#直接获得
h1 <- induced.subgraph(g, 1:5)
#h1
h1
#方法2,通过‘减法’
h2 <- g - vertices(c(6,7))
#h2
h2
#类似地,g可以从h中恢复,首先把这两个顶点加回去。
#然后再加适当的边。
h3 <- h2 + vertices(c(6,7))
#h3
h3
h4 <- h3 + edges(c(4,6),c(4,7),c(5,6),c(6,7))
#h4
h4
最后,集论的基本概念并集、不相交并集、交集、差集、补集都以自然的方式扩展到图上。例如,两个图的并集,例如H5和H6,是一个图G,其中顶点和边被包含在且仅当它们被包含在H5或H6的至少一个中。例如,我们的图g可以通过上面定义的(诱导的)子图h和第二个适当定义的子图的合并来创建。
#2.1.4
h5 <- h3
h6 <- graph.formula(4-6, 4-7, 5-6, 6-7)
h7 <- graph.union(h5,h6)
h7
装饰网络图
顶点、边和图形属性
#2.1.5
V(dg)$name
#Their gender is added to dg as
V(dg)$gender <- c("M","F","M")
dg
# Their color is added to dg as
V(g)$color <- "red"
# 判断是否为加权图
is.weighted(g)
#加权
wg <- g
E(wg)$weight <- runif(ecount(wg))
#?runif #runif产生ecount(wg)个随机数(0-1)。
#?ecount # 边的数量
E(wg)$weight
wg
is.weighted(wg)
# 整个图的名字
g
g$name <- "Graph-1"
g
使用数据框
就像通常不会手动输入任何网络图一样,而是偏好在文件中处理,因此属性也倾向于被类似地编码。
例子: 针对 Lazega 的数据集:v.attr.lazega 包含顶点信息,elist.lazega 包含边信息。
#2.2
library(sand)
g.lazega <- graph.data.frame(elist.lazega,directed="FALSE",
vertices=v.attr.lazega)
g.lazega$name
g.lazega$name <- "Lazega Lawyers"
g.lazega$name
# 我们关于这些的全套网络信息
g.lazega
vcount(g.lazega)
ecount(g.lazega)
list.vertex.attributes(g.lazega)#列出顶点属性的名称
g.lazega$Seniority
is.weighted(g.lazega)
#str(g.lazega)
plot(g.lazega)
讨论图
简单图,加权图,连通图,弱连通图,强连通图,顶点度(出度,入度)等一系列的概念。
在进行典型的网络分析时,检查网络图是否简单是一件不太重要但却很重要的初步步骤,因为许多模型和方法都假定输入图是简单的,或者如果输入图不是简单的,则会有不同的行为
简单图
#2.3.1 判断是否为简单图
g
plot(g) #发现之前改的color属性作用了!
is.simple(g)
#复制顶点2和3之间的边,会得到一个复杂图
#在相同的顶点对之间有多条边
mg <- g + edge(2,3)
mg
is.simple(mg)
加权矩阵
请注意,将一个多图转换成一个加权图是很简单的,而且在实践中也并不少见,其中每个结果适当的边都配备了一个权值,该权值等于原始多图中该边的多重性。
#2.3.2
E(mg)$weight <- 2 #每条边的权重都为2
E(mg)$weight #重复边也算在内
plot(mg)
is.simple(mg)
wg2 <- simplify(mg)
E(wg2)$weight
#因为2,3边有两条边,因为是简单图故权重变为了4!
is.simple(wg2)
#查看某节点邻居
neighbors(g, 5)
#顶点的度
degree(g)
degree(g,2)
#对于有向图
dg
degree(dg, mode="in")
degree(dg, mode="out")
degree(dg)
连通性
连通:如果存在一条从顶点u到v的路径,则称u和v是连通的。
连通图:图中任意两个顶点都是连通的,称为连通图;否则为非连通图。
连通分量:无向图中的极大连通子图。
有向图中分为强弱连通。
#连通性
plot(g)
is.connected(g)
#因此它只包含一个分量
clusters(g)
#?clusters #计算图的最大(弱或强)连通分量
g2 = graph.formula(1-2, 3-5, 4-3, 6-7)
plot(g2)
is.connected(g2)
clusters(g2) #no为连通分量个数
#membership为节点所在的连通分量;csize为连通分量节点数
#有向图的强弱连性
plot(dg)
is.connected(dg, mode="weak")
is.connected(dg, mode="strong")
clusters(dg)
dg2 = graph.formula(sam+-mary,mary+-tom)
plot(dg2)
is.connected(dg2, mode="weak")
is.connected(dg2, mode="strong")
clusters(dg2, mode="strong") #默认mode为weak
图的直径
图中(两节点最短路径的)最长距离的值称为图的直径
plot(g)
diameter(g, weights=NA)
plot(dg)
diameter(dg, weights=NA)
plot(mg)
E(mg)$weight
diameter(mg, weights=NA)
diameter(mg)
特殊类型的图
图形有各种各样的“形状和大小”,但是在实践中经常遇到一些图族。我们以图2.2中所示的四个这样的族为例来说明这一概念。
完全图
图中任意两个节点都相连
正则图
图中每个节点都有相同的度k,则称图为k-正则图。
树
不含环路的连通图称为树。在数中,度为1的节点称为树叶。
k-星图
是树的一个特例,它只由一个根和k个叶组成。
森林
当无向图的所有连通子图均为树时,这种图称为森林。
零图
图中只有节点没有边
g.full <- graph.full(7)
g.ring <- graph.ring(7)
g.tree <- graph.tree(7, children=2, mode="undirected")
g.star <- graph.star(7, mode="undirected")
par(mfrow=c(2, 2))
plot(g.full)
plot(g.ring)
plot(g.tree)
plot(g.star)
树概念的一个重要概括是有向无环图(DAG)。顾名思义,DAG是一个有向图,它没有有向循环。然而,与有向树不同的是,它的底层图不一定是树,因为用无向边替换弧可能会留下一个包含循环的图。例如,我们的图dg是定向的,而不是DAG。
#2.37
plot(dg)
is.dag(dg)
二部图是这样的图G = (V,E)使得顶点集V可以被分割成两个不相交的集合。
例如,他们在研究演员和电影之间的关系时很受欢迎,演员和电影分别扮演成员和组织的角色。
g.bip <- graph.formula(actor1:actor2:actor3,movie1:movie2,
actor1:actor2 - movie1,actor2:actor3 - movie2)
V(g.bip)$type <- grepl("^movie", V(g.bip)$name)
#在字符向量的每个元素中搜索与参数模式匹配的参数:
g.bip
#节点属性
V(g.bip)$name
V(g.bip)$type
E(g.bip)
plot(g.bip)
#将二部图投影到两个单模网络中
proj <- bipartite.projection(g.bip)
proj
proj[[1]]
proj[[2]]
#
#gg.big = make_bipartite_graph(V(g.bip)$type,E(g.bip))
g1 <- make_bipartite_graph( rep(0:1,length=10),c(1:10))
g2 <- make_bipartite_graph(
rep(0:1,length=10),c(c(1,4),c(2,3))
) #相连点必须在不同分类里,此处为一个0,一个1
print(g1, v=TRUE)
par(mfrow=c(1,2))
plot(g1)
plot(g2)
补充
外部读取数据(补充, 实际比较常用的方式)
## 导入边数据,里面可以包含每个边的频次数据或权重
#edges <- read.table('edge.csv', header=T, sep=',')
## 导入节点数据,可以包含属性数据,如分类
#vertices <- read.table('vertices.csv', header=T, sep=',')
#data <- graph.data.frame(edges,directed="FALSE",vertices=vertices)
#read.graph('edge.csv')