有很多朋友表示在社会网络分析的第一步——生成邻接矩阵遇到了一些困难。因为社会网络分析的算法几乎都是基于矩阵的计算。所以把关系数据转换为邻接矩阵是一切分析的基础。关于邻接矩阵的定义,可以参看我的另一篇文章。闲话少说,进入正题。

获得关系数据的方式有很多,关系的内涵也是各种各样。比如文章的引用关系,医院间病人的转诊,股东对不同公司的持股等等。可以说关系数据无处不在。本文以最常见的朋友关系为例来介绍一种生成邻接矩阵的方式。文中会展示详细的代码,保证读者看完之后都能实操。

朋友关系最常用的还是问卷法,采取提名的方式,如下图:




R语言ANOV的Residuals指的是 r语言aov_一个aov网用邻接矩阵表示


图1

如图中所示,除了提名朋友的姓名之外,还可以设置一些题目对关系的属性进行评估。这些关系属性的数据可以在未来做一些更丰富的分析,为了不偏离主题,本文暂时不做介绍。

被试完成问卷之后我们就需要把数据录入。这里推荐一个比较好用的数据录入工具 EpiData,也是可以对语法进行编辑,可以设置数据格式(例如日期设置为yyyy/mm/dd)、取值范围、跳转条件等等,可以帮助我们规避很多录入错误。毕竟数据录入是一个没啥技术含量容易产生厌烦情绪的工作,而数据质量是科研工作的基础。语法写好之后,程序会自动识别输入的合法性,大大降低出错的概率。完成之后可以直接导出为excel等文件,非常方便。

扯远了,回到主题。一般数据格式都是每一个被试为一行,称为一个观测(observation),每一道题目为一列,称为变量(variable)。这里把英文给出来也是为了跟RStudio的界面对应上,方便读者前后联系。完成数据录入之后,图1部分的社会网络数据长这个样子:


R语言ANOV的Residuals指的是 r语言aov_一个aov网用邻接矩阵表示_02

图2


这里你会发现做了一个降维的处理。图1中原始的问卷是一个二维表格的形式,一个维度是朋友的名字,另一个维度是各种关系属性。降维的话一般就是两种,一种是按行降维,一种是按列降维。我们这里就是按行降维,D101-D108对应图1第一行的八个名字,D201-208对应图1第二行朋友的性别,以此类推。按行降维和按列降维都可以,方法也是一样的,相信你看懂了按行降维的方法,按列降维自然就会了。因为这里的问卷设置,被试并不需要填满8个名字。例如图2中红色方框所示,被试只填写的前三个名字,那么相应的,后面的题目也都是三个值。这个也可以用来判断录入是否有误。

数据录入完成之后就可以开始今天的正题了——生成邻接矩阵

这里为了照顾到更多的读者我会把基础的操作也写出来,大神请略过。

STEP 1:读入数据

我们需要把数据读入到R中去,如图3所示:我的数据是csv格式的,所以就用read.csv()函数。成功读入之后,在右上角的环境(environment)窗口中就会显示你所命名的对象,并显示其所包含的观测数和变量数。由于我这里展示的数据是分多个文件保存的,所以每一个文件都需要读取并命名。同样格式的数据也可以合并,这个可以根据具体的分析需要来选择,各有利弊。读入文件的时候要注意以下三点。第一文件名要用引号引起来并且带上后缀名。第二RStudio的工作路径和数据文件的存储路径一致时引号内只用写文件名,查看工作路径的函数为getwd(),此函数不用填写任何参数;或者在RStudio界面左下角控制台窗口的顶端查看。第三如果第二点不满足,有两种处理方式,一种是将当前工作路径设置为数据文件的保存路径,代码为setwd("D:/社会网络分析R语言实战之生成邻接矩阵"),引号内为数据文件实际的存储路径,这里要注意的是RStudio使用的是右上至左下斜杠,windows使用的则是左上至右下斜杠,使用时注意区分;另一种处理方式是在文件名前面加上路径。


R语言ANOV的Residuals指的是 r语言aov_一个aov网用邻接矩阵表示_03

图3

STEP 2:安装并加载所需程序包

我们需要安装并加载所需要的包(package),如图4所示。安装是一劳永逸的,如果你之前安装过,则无需再安装了。可以通过右下角package窗口的搜索栏进行搜索,所安装的包都会罗列在package窗口,如果能搜索到,证明已经安装过了。但是加载包则不一样,每次重新打开RStudio都需要重新加载。生成邻接矩阵需要的包就只有dylyr一个。代码及注释图中都有,我就不再赘述。


R语言ANOV的Residuals指的是 r语言aov_一个aov网用邻接矩阵表示_04

图4

STEP 3:生成邻接表

接下来我们需要把社会网络部分按照关系发出者(sender)一列关系接收者(receiver)一列的格式(我把它叫做邻接表)提取出来,如图5所示。第一个方框内的代码是提取网络部分的数据,数字表示第几列。被试,也就是关系发出者的姓名存在第4列;76-80对应图2中的D101-D105,84-88对应图2中的D201-D205,以此类推。这里并没有提取全部的八个好友,而是只提取了班内的好友。第二个方框内的代码是将五个对象(提名1-提名5)的列名统一,否则无法成功运行下一个方框内合并的代码。考虑到不是每个人都把五个名字写满了,最后一个方框内的代码删掉了那些没提名的情况。


R语言ANOV的Residuals指的是 r语言aov_数据_05

图5

STEP 4:生成邻接矩阵

有了邻接表我们就可以将其转换为邻接矩阵了,如图6所示。第56和57两行代码会在原来的对象“T1CLASS13”上增加一列新的变量,变量名为“Name_order”,内容是对名字排序之后的数字。对象“T1CLASS13”中存放被试姓名的那一列列名为“姓名”。因为后面的计算不能用姓名直接计算,而需要给每一个人编一个号。比如现在有50个人,那么就从1排到50。第60行做了一个命名,目的是简化63和64两行代码里的参数。63和64两行代码在对象“提名_all”上新增了两列变量,分别叫做“from_order”和“to_order”,变量内容为名字对应的编号。第65行增加了一列名为“tie”的变量,内容全为1。第66行则是把对象“提名_all”的第9到11列赋值给新的对象“提名_all.copy”。67行是删掉缺失值的行。68行是做了一个数据格式的转换,变成矩阵。69行则是创建了一个新的矩阵,名为adj,行数和列数都为班级人数,元素则都为0。70行是把对象“提名_all.copy”中第3列的值按照其1、2列的坐标赋值给对象“adj”。71行是将adj以txt文件输出,文件名为T1CLASS13friend.txt。


R语言ANOV的Residuals指的是 r语言aov_数据_06


最后,如果有写的不清楚的地方,敬请留言批评指正。关于社会网络分析有其他问题的也欢迎留言,共性问题我会在下一篇文章中详细解答。

码字不易,点个赞鼓励一下,才有动力继续输出呀!谢谢!