
作者Luther 弓
网络图在社交关系分析中最常见,直观明了,很受欢迎。但在产品分析中,网络图同样有很多应用场景,比如分析各个功能模块或打点之间的关系,用户在各个功能上的行为分布等。它与路径图的区别在于,行为路径是单向的,是一个动态的流;而网络图主要描述的是静态关系或分布,虽然也可以有方向,但只是描述两个点之间的相向关系。
R语言有两个包可以实现网络图,一是networkD3,二是igraph。个人认为后者更容易上手,效果较好,也更灵活。igaph是一个项目,目标是建立一条简单,易用的网络分析工具,有 R, python, C/C++ 等语言的具体实现。
1、数据准备
网络图最基本的两个元素是节点/顶点(vertice) 和 边(edge),如下图。圆圈就是节点,节点之间的连线就是边。节点可以是包括人在内的任何实体,而边则是关系,这种关系也可以是任何互动,比如对话、拜访、资金往来、用户跳转等。边是可以有方向的,比如张三主动和李四攀谈,那方向就是张三到李四。

所以数据应是下面这样的:
首先是两个数据文件,边数据和点数据。当然,点数据不是必须的,如果作图不涉及点的属性,这个就没必要。

边数据的结构如下:一共三列,from(来源列,当然也可以取其他名称)、to(去向列)、fre(频次)。频次可以没有,因为我这里把相同的边去重了,所以加了频次。如果不去重,程序也可以计算频次。不过我建议还是去重加频次,这样看着清晰些。另外,fre列数据也可以换成权重数据,比如某个边对你很重要,这样后面作图时可以根据权重把相应的做边加粗处理。

点数据比较灵活,除了第一列是点本身外,可以放很多属性数据,如分组、性别年龄等。另外,点也可以是中文,如下图示例。

在这里,我用的是用户APP打点行为数据作为案例演示。数据中的点即每个打点,边即用户在打点之间的跳转,fre即跳转的次数,leixing即每个点所属的功能模块。下面是具体的实现方式
2、网络图的R语言实现及代码说明
library(igraph)
#1)导入边数据和节点数据
edges <- read.table('C:\\Users\\lenovo\\Desktop\\edges.csv', header=T, sep=',') #导入边数据,里面可以包含每个边的频次数据或权重
vertices <- read.table('C:\\Users\\lenovo\\Desktop\\vertices.csv', header=T, sep=',') #导入节点数据,可以包含属性数据,如分类
#2)导入数据后,要转化成图数据才能用R作图,不同数据格式用不同方式
#graph_from_literal 通过文字创建,graph_from_edgelist通过边列表(矩阵)创建,graph_from_adj_list通过邻接列表(矩阵)创建
#graph_from_adjacency_matrix 通过邻接矩阵(所有点的纵横矩阵)创建,graph_from_incidence_matrix通过关联矩阵(两组内部独立点的矩阵)创建
#graph_from_data_frame通过数据框创建,详细介绍可参见《igraph manual》http://igraph.org/r/doc/igraph.pdf
#这里数据格式是数据框,所以用graph_from_data_frame
graph <- graph_from_data_frame(edges, directed = TRUE, vertices=vertices) #directed = TRUE表示有方向,如果不需要点数据,可以设置vertices=NULL
#3)转换完成后,有两种生成方式,一是直接plot,参数放里面;二是通过修改图的方式设置参数,然后plot
#生成方式1:
plot(graph,
layout=layout.fruchterman.reingold, #layout.fruchterman.reingold表示弹簧式发散的布局,
#其他还有环形布局layout.circle,分层布局layout.reingold.tilford,中心向外发散layout.reingold.tilford(graph,circular=T) ,核心布局layout_as_star,大型网络可视化layout_with_drl
vertex.size=15, #节点大小
vertex.shape='circle', #节点不带边框none,,圆形边框circle,方块形rectangle
vertex.color="yellow",#设置颜色,其他如red,blue,cyan,yellow等
vertex.label=NULL, #NULL表示不设置,为默认状态,即默认显示数据中点的名称,可以是中文。如果是NA则表示不显示任何点信息
vertex.label.cex=0.8, #节点字体大小
vertex.label.color='black', #节点字体颜色,red
vertex.label.dist=0.4, #标签和节点位置错开
edge.arrow.size=0.3,#连线的箭头的大小,若为0即为无向图,当然有些数据格式不支持有向图
edge.width = 0.5, #连接线宽度
edge.label=NA, #不显示连接线标签,默认为频次
edge.color="black") #连线颜色
#生成方式2:
set.seed(50) #生成随机数,这样图的布局就会可重复,而不是每次生成的时候都变
l<-layout.fruchterman.reingold(graph) #设置图的布局方式为弹簧式发散的布局
#具体修改过程
V(graph)$size <- degree(graph)*2+5 #节点大小与点中心度成正比,中心度即与该点相连的点的总数
colrs <- c("gray50", "tomato", "orange", "red", "yellow")
V(graph)$color <- colrs[V(graph)$leixing] #根据类型设置颜色,按照类型分组
V(graph)$label.color <- 'black' #设置节点标记的颜色
E(graph)$width <- E(graph)$fre #根据频次列设置边宽度
E(graph)$label <- E(graph)$fre #根据频次列设置边标签
E(graph)$arrow.size=0.3 #设置箭头大小
#生成图
plot(graph, layout=l)
注意:方式2比方式1更加灵活,尤其是在设置不同分类节点颜色的时候
3、生成结果
方式1生成结果:

方式2生成结果:
不同颜色代表打点所属功能模块

恭喜你,又看完一篇文章,扫码领个红包吧!