首页 > 代码库 > R语言:社会网络关系分析-进阶

R语言:社会网络关系分析-进阶

本文内容参考李明《R语言与网站分析》一书


下面使用R语言实现社会网络分析的各个基础概念
# (1) 点集合(Vertexs)和点的属性数据
# 使用V(g)可返回关系网络g中所有点的集合V,并通过length函数直接返回点数目n。代码如下:
V(g.undir)
## Vertex sequence:
## [1] 1 2 3 4 5 6 7
length(V(g.undir))
## [1] 7
# 在g.undir中记录了点名称属性数据V(g.undir)$label,这里也可以直接展示。代码如下:
V(g.undir)$label
## [1] "a" "e" "b" "c" "d" "f" "g"
# 注意,在点数据V(g.undir)中可任意添加属性数据。例如为个点添加分组标签menbership,并分别为每组内的点分配一种颜色(color)。代码如下:
member<-spinglass.community(g.undir)
V(g.undir)$membership<-member$membership;V(g.undir)$membership
## [1] 3 1 1 1 2 2 2
mem.col<-rainbow(length(unique(V(g.undir)$membership)),alpha=0.3)
V(g.undir)$color<-mem.col[V(g.undir)$membership];V(g.undir)$color
## [1] "#0000FF4C" "#FF00004C" "#FF00004C" "#FF00004C" "#00FF004C" "#00FF004C"
## [7] "#00FF004C"
plot(g.undir,edge.width=E(g.undir)$weight,vertex.color=V(g.undir)$color)
技术分享
# 其中,spinglass.community()是一种发现社群的函数,返回对象中的membership列数据是每个样本点的分类组号.


# (2)点筛选和删除
# 点数据V(g.undir)的读取方式类似于读取向量,而点的属性数据V(g.undir)$label本身就是一个向量。例如,可以使用V(g.undir)[1:2]和V(g.undir)$label[1:2]来读取前两个样本点的内容.
V(g.undir)[1:2]
## Vertex sequence:
## [1] 1 2
V(g.undir)$label[1:2]
## [1] "a" "e"
# 也可以通过which函数来筛选特定的点数据和点的属性数据。例如,读取第一组的点数据V(g.undir)以及点名称V(g.undir)$label.代码如下:
V(g.undir)[which(V(g.undir)$membership==1)]
## Vertex sequence:
## [1] 2 3 4
V(g.undir)$label[which(V(g.undir)$membership==1)]
## [1] "e" "b" "c"
# 上述的代码有可以简写成:
V(g.undir)[membership==1]
## Vertex sequence:
## [1] 2 3 4
V(g.undir)[membership==1]$label
## [1] "e" "b" "c"
# 使用减号(g-V(g0[i])形式)可以从关系网络g中删除部分点V(g)[i],它是add.vertices函数的反向操作。例如,删除关系网络g.undir中的孤立点(与任何其他店均没有关联),可使用如下代码:
g.undir<-g.undir-V(g.undir)[degree(g.undir)==0]
# 如果想删除第一组内的所有点数据,则使用如下代码:
g.undir<-g.undir-V(g.undir)[membership==1]

# (3) 相邻点集合
# 在igraphe包中可以使用neighbors函数来找出某一点的相邻点的序号向量。例如,在无向图g.undir中找到和点d相邻的点以及该点名称。代码如下:
g.undir<-init.graph(data)
plot(g.undir,edge.width=E(g.undir)$weight,main="无向图 g.undir",
     edge.label=E(g.undir)$weight)

技术分享
V(g.undir)[neighbors(g.undir,v=which(V(g.undir)$label=="d"))]
## Vertex sequence:
## [1] 4 6 7
V(g.undir)$label[neighbors(g.undir,v=which(V(g.undir)$label=="d"))]
## [1] "c" "f" "g"
# 对于有向图g.dir,可设置mode参数来制定neighbors的计算方式。
g.dir<-init.graph(data,dir=T)
plot(g.dir,edge.width=E(g.undir)$weight,main="有向图 g.undir",
     edge.label=E(g.undir)$weight)

技术分享

# 找出点d的相邻出点(点d为线的发起端:edges(d,f)和edges(d,g)),代码如下:
V(g.dir)$label[neighbors(g.dir,v=which(V(g.dir)$label=="d"),mode="out")]
## [1] "f" "g"
# 找出点d的相邻入点(点d为线的接收端:edges(c,d)和edges(f,d)),代码如下:
V(g.dir)$label[neighbors(g.dir,v=which(V(g.dir)$label=="d"),mode="in")]
## [1] "c" "f"
# 找出点d的相邻出点和相邻入点总和(点d为线的发起端或接收端:edges(d,f),edges(d,g),edges(c,d)和edges(f,d)),代码如下:
V(g.dir)$label[neighbors(g.dir,v=which(V(g.dir)$label=="d"),mode="total")]
## [1] "c" "f" "f" "g"
# (4) 点的度数。
# 1) 无向图的点度数。在无向图中,点的度数等于该点的相邻点数。例如,无向图g.undir中点d的度数为:
length(neighbors(g.undir,v=which(V(g.undir)$label=="d")))
## [1] 3
# 在igraph包中也可以直接使用degree函数来计算。
#### 设置参数v方式####
degree(g.undir,v=which(V(g.undir)$label=="d"))
## [1] 3
#### 向量方式####
degree(g.undir)[which(V(g.undir)$label=="d")]
## [1] 3
# 其中dgree(g.undir)以向量形式直接返回关系网络g.undir内所有点的度数.
degree(g.undir)
## [1] 2 3 2 4 3 1 1
# 2) 有向图的点度数。对于有向图g.dir,也可以设置mode参数来指定degree函数的计算方式。以下代码分别计算点d的出度,入度和综合度数。
### 设置参数v方式###
degree(g.dir,v=which(V(g.dir)$label=="d"),mode="out")
## [1] 2
degree(g.dir,v=which(V(g.dir)$label=="d"),mode="in")
## [1] 2
degree(g.dir,v=which(V(g.dir)$label=="d"),mode="total")
## [1] 4
#### 向量方式###
degree(g.dir,mode="out")[which(V(g.dir)$label=="d")]
## [1] 2
degree(g.dir,mode="in")[which(V(g.dir)$label=="d")]
## [1] 2
degree(g.dir,mode="total")[which(V(g.dir)$label=="d")]
## [1] 4
# (5) 线集合和线的属性数据
# 使用E(g)可返回关系网络g中所有线的集合E(edges),并通过length函数直接返回线数目m。
# 无向图g.undir
E(g.undir);length(E(g.undir))
## Edge sequence:
##           
## [1] 2 -- 1
## [2] 4 -- 1
## [3] 3 -- 2
## [4] 4 -- 2
## [5] 4 -- 3
## [6] 5 -- 4
## [7] 6 -- 5
## [8] 7 -- 5
## [1] 8
# 有向图g.dir
E(g.dir);length(E(g.dir))
## Edge sequence:
##           
## [1] 1 -> 2
## [2] 1 -> 4
## [3] 2 -> 4
## [4] 3 -> 2
## [5] 3 -> 4
## [6] 4 -> 5
## [7] 5 -> 6
## [8] 5 -> 7
## [9] 6 -> 5
## [1] 9
# (6) 线的筛选和删除
# 线的筛选和删除操作与点数据类似。例如,读取无向图g.undir中线权重大于1的线,代码如下:
E(g.undir)[weight>1]
## Edge sequence:
##           
## [7] 6 -- 5
## [8] 7 -- 5
# 也可以使用减号(g-E(g)[i]形式)从关系网络g中删除部分线E(g)[i]的功能,它是add.edges函数的反操作。下面的代码从无向图g.undir中删除线权重大于1的线。
g.undir<-g.undir-E(g.undir)[weight>1]
plot(g.undir)
技术分享
# (7) 两点间的最短路径和距离
# 使用igraph包中的get.shortest.paths函数可读取两点间的最短路径。
g.undir<-init.graph(data)
get.shortest.paths(g.undir,from=V(g.undir)[label=="a"])
## $vpath
## $vpath[[1]]
## numeric(0)
## 
## $vpath[[2]]
## [1] 1 2
## 
## $vpath[[3]]
## [1] 1 4 3
## 
## $vpath[[4]]
## [1] 1 4
## 
## $vpath[[5]]
## [1] 1 4 5
## 
## $vpath[[6]]
## [1] 1 4 5 6
## 
## $vpath[[7]]
## [1] 1 4 5 7
## 
## 
## $epath
## NULL
## 
## $predecessors
## NULL
## 
## $inbound_edges
## NULL
get.shortest.paths(g.undir,from=V(g.undir)[label=="a"],to=V(g.undir)[label=="b"])
## $vpath
## $vpath[[1]]
## [1] 1 4 3
## 
## 
## $epath
## NULL
## 
## $predecessors
## NULL
## 
## $inbound_edges
## NULL
# 对于有向图,可以设置计算方式,其取值可为"in","out","all"。
# 另外,使用igraph包中的shortest.paths函数可以读取两点间的距离(即最短路径的长度)。
shortest.paths(g.undir)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,]    0    1    2    1    2    4    4
## [2,]    1    0    1    1    2    4    4
## [3,]    2    1    0    1    2    4    4
## [4,]    1    1    1    0    1    3    3
## [5,]    2    2    2    1    0    2    2
## [6,]    4    4    4    3    2    0    4
## [7,]    4    4    4    3    2    4    0
shortest.paths(g.undir,v=V(g.undir)[label=="a"]) # 参数v是路径的起点
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,]    0    1    2    1    2    4    4
shortest.paths(g.undir,v=V(g.undir)[label=="a"],to=V(g.undir)[label=="b"])
##      [,1]
## [1,]    2
# 如果想把无向图g.undir中点c到点g之间的最短路径绘制为红线并加粗,且路径所经过的相关点设置为绿色。代码如下:
pa<-get.shortest.paths(g.undir,from=which(V(g.undir)$label=="c"),
                       to=which(V(g.undir)$label=="g"))[[1]][[1]]
E(g.undir)$color<-"black";
E(g.undir,path=pa)$color<-"red"
E(g.undir,path=pa)$width<-3
E(g.undir)[pa]$color<-"green"
plot(g.undir)
技术分享
# 代码E(g.undir,path=pa)用于截取经过pa各个点的相关线(通过设置E函数的path参数实现),结果如下:
pa
## [1] 4 5 7
E(g.undir,path=pa)
## Edge sequence:
##           
## [6] 5 -- 4
## [8] 7 -- 5
# (8) 关系网络的筛选
# 使用induced.subgraph函数可以通过点筛选出关系网络。例如,要筛选出无向图g.undir中点f,d,g,c的图。可以采用如下代码:
g.unidr<-init.graph(data)
tmp.v<-c(which(V(g.undir)$label==c("c")),which(V(g.undir)$label==c("d")),
         which(V(g.undir)$label==c("g")),which(V(g.undir)$label==c("f")))
g.undir.1<-induced.subgraph(g.undir,V(g.undir)[tmp.v])
# 也可以用 g.undir.1<-induced.subgraph(g.undir,V(g.undir)[tmp.v])
# 使用subgraph.edges函数通过连续筛选得到关系网络。例如,从无向图g.undir中筛选出连接点c和g之间的联系:
pa<-get.shortest.paths(g.undir,from=which(V(g.undir)$label=="c"),
                       to=which(V(g.undir)$label=="g"))[[1]][[1]]
g.undir.2<-subgraph.edges(g.undir,E(g.undir,path=pa))
# 或者筛选出线权重大于1的线(点d,f,g之间的连线):
g.undir.3<-subgraph.edges(g.undir,which(E(g.undir)$weight>1))
# 最后使用如下语句展示筛选后的网络图。
par(mfrow=c(2,2))
plot(g.undir,edge.width=E(g.undir)$weight,main="g.undir的关系网络图")
plot(g.undir.1,edge.width=E(g.undir.1)$weight,main="g.undir中筛选出f,d,g,c")
plot(g.undir.2,edge.width=E(g.undir.2)$weight,main="g.undir中筛选点c和g之间的连线")
plot(g.undir.3,edge.width=E(g.undir.3)$weight,main="g.undir中筛选线权重大于1的连线")
par(mfrow=c(1,1))

技术分享

R语言:社会网络关系分析-进阶