如何用 R 绘制交互式社会网络图?

article/2025/9/17 10:09:15

挖掘社会关系网络,助你洞若观火。

640?wx_fmt=jpeg

需求

最近有个学生问我,如何绘制交互式社会网络图(Interactive Social Network Graph)?

之所以一定要交互式,是因为他的应用场景,是演示给客户。

他解释说,如果客户有选项,可以根据需要来缩放图形、聚焦类别,甚至是可以拖拽图形元素,以不同视角来查看,那展示效果显然会更好。

我对学生这次把握客户需求的能力,还是比较赞赏的。确实,数据可视化的目的就是为了与人沟通。而人是需要控制感的。

在数据科学里,这个需求,属于网络可视化(Network Visualization)范畴。应用上,除了描绘社会网络外,这种可视化的对象还可以包括引文网络、贸易网络、信息(或疾病)传播网络等。甚至,网络可视化操作还能与时序数据结合,例如 Maximilian Noichl 绘制的这张古代哲学家的动态关系网络图。

640?wx_fmt=gif

网络可视化的工具,是非常多的。

然而,一旦涉及了交互式,选项就大幅减少了。特别是,他还要求免费易学格式开放、演示环境易于部署……

这条件,够苛刻了吧?

还好,我还真就帮他找到了。

虽然易学,可是由于他是文科生,我觉得还是给他写个教程,比较妥帖。

教程写完之后,我觉得你可能也会用得上,所以一并分享给你。

演示数据,我自然不能用他的。否则有泄露商业机密的风险。这里我采用的,是斯坦福大学开放课程《数据库基础》中的一个简单数据样例。我在国际班讲的英文数据库课程,一直用它作为练习数据。

这个演示数据的特点,就是简单。

有多简单?往下看。

数据

该数据刻画的,是某高中里4个年级部分学生之间的社交关系。

我们一共需要用到3张数据表格,分别是学生信息、朋友关系和“喜欢”关系。

先看学生信息表。我已经把它上传到了这个 github 链接,你可以点击查看。

640?wx_fmt=jpeg

表格包含3列,分别是学号、姓名和年级。

然后是朋友关系表。请点击这个链接查看。

640?wx_fmt=jpeg

除去表头,一共20行。包含两列,代表了关系两端的两个学生的学号。

注意“朋友”关系是一种双向(或者无向)关系。两个人都认可的,才算是朋友。我在人群中,一眼就能认出某影视巨星。可惜,人家不认识我,这显然就不算朋友关系。

再后面,是“喜欢”(likes)关系表。我放在了这个链接。

640?wx_fmt=jpeg

注意这里虽然也描述了关系的起点和终点,但是“喜欢”关系是一种有向关系。张三喜欢李四,李四可能并不喜欢张三。

好了,这就是我们需要用到的全部数据了。下面我们来看看运行环境。

环境

我们使用的,是 R 的集成开发环境(integrated development environment, IDE) RStudio 。

640?wx_fmt=jpeg

你可以在本机安装 R 以及 RStudio 。我已经把安装和设置步骤写在了《如何用 R 快速了解科研领域?》一文中。

配套的代码和数据,我放在了这个 github 仓库中。你可以下载使用。

然而,此处为了你更快捷地上手,我直接为你准备了云端的运行环境。你只需要点击这个链接(http://t.cn/EJ5U8o6),就可以直接在浏览器里面开启一个 RStudio 。其中,已包含了我为你准备好的数据和代码。

640?wx_fmt=jpeg

双击右下方目录区域里面的 demo.Rmd,你就能看到对应的笔记本了。

640?wx_fmt=jpeg

怎么样?够方便吧?

其实,你自己也可以构建这样的云端环境。具体的方法,我已经在《如何用iPad运行Python代码?》一文中为你详细介绍了。如果你感兴趣,可以在学过本篇教程后,尝试练练手。

下面我们开始介绍代码了。请你根据我的介绍,逐步点击代码模块旁边的运行按钮,查看运行的结果。

640?wx_fmt=png

代码

首先,我们需要读入本教程中最重要的软件包,也就是 R 环境下的网络交互可视化工具—— visNetwork。

640?wx_fmt=jpeg

visNetwork 基于 Javascript 可视化工具库 vis.js 开发,为 R 用户提供了简单易用的界面,而且功能也很强大。

640?wx_fmt=jpeg

我们使用 library 命令来读入它。

library('visNetwork')

下面我们来读入数据。

首先,我们观察“朋友”关系。读入学生信息表和朋友关系表。

nodes <- read.csv("data/Highschooler.csv", header=T, as.is=T)
friends <- read.csv("data/Friend.csv", header=T, as.is=T)

注意这里的参数:

  • header=T 是指我们读入的数据里包含了表头,需要让 R 注意,不要把表头也当成了数据来处理;

  • as.is=T 是指读入的字符串数据,不要默认按照因子来转换。这其实是一种技巧。因为如果大量数据默认做转换,可能会导致读取效率很低。当然,对于我们的例子来说,因为数据量很小,实际上效率差别不大。但是好习惯还是需要养成的。

下面我们要在节点上生成一些属性。我们希望把鼠标挪到某个节点上的时候,显示该学生属于“某年级”;而生成图像的时候,直接在节点旁边标明学生的姓名。

因此,我们就需要分别对 nodes$titlenodes$label 赋值。

之后,用 visNetwork 可视化我们的节点和关系连线。

nodes$title <- paste0("grade", nodes$grade)
nodes$label <- nodes$name
visNetwork(nodes, friends)

结果如下图所示:

640?wx_fmt=jpeg

注意,这可不是一张静态图,你把鼠标悬浮到 Alexis 人名上试试看。

640?wx_fmt=jpeg

年级属性就出现了。

你还可以拖动任意一个学生节点,感受一下什么叫做“牵一发而动全身”。

640?wx_fmt=gif

有趣吧?

但是现在所有的节点,都是一样的颜色。我们希望依据不同的年级,重新绘制节点颜色,这样看得会更清晰。

我们依据年级属性(nodes$grade),来定义节点的背景颜色(nodes$color.background)。

然后再次调用 visNetwork,进行绘制。

nodes$color.background <- c("orange""pink""yellow""blue")[nodes$grade]
visNetwork(nodes, friends)

结果是……

640?wx_fmt=jpeg

不对呀,说好的颜色变化呢?

别着急。

如果让 R 根据不同属性来区分颜色,我们首先需要保证该属性类型是因子(factor)。可是我们读取的时候,为了效率,没让 R 自动转换。

怎么办?

手动来做吧。

nodes$grade <- as.factor(nodes$grade)
nodes$color.background <- c("orange""pink""yellow""blue")[nodes$grade]
visNetwork(nodes, friends)

这次,我们再看看结果:

640?wx_fmt=jpeg

嗯,感觉好极了。

这里节点很少,全部同时显示,也能看得清晰。但是假设我们需要处理一所真正学校中的朋友关系,可以想象那会有成百上千个节点。如果我们希望聚焦,那就得给用户更多的交互功能。

这里我给你介绍其中一个选项,就是利用 selectedBy ,指定我们让用户在哪一个属性上进行分组选择。

你需要把它放在 visOptions 中。

visNetwork(nodes, friends) %>%
  visOptions(selectedBy = "grade")

运行效果是这样的:

640?wx_fmt=jpeg

看起来,跟刚刚区别不大,只是多了一个下拉框而已。

我们尝试选择一下:

640?wx_fmt=gif

交互选项,让当前分组保持高亮,其他分组变灰暗,于是我们的注意力就可以集中。

尝试着玩儿一下,看看你能否发现什么有趣的关系模式?

我发现了一个。

640?wx_fmt=jpeg

大部分情况下,同一个年级的学生间,总会可以关联起来。但是,11年级的 Austin ,跟本年级的其他3名同学,没有任何直接联系。反而,跟其他年级的学生,保持了朋友关系。

如果你是他的班主任,要不要关注一下?

下面,我们来看看另外一种关系——“喜欢”(likes)。

还是读入 csv 文件,到 likes 数据框里面。参数跟刚才一样。

likes <- read.csv("data/Likes.csv", header=T, as.is=T)

先来绘制看看。

visNetwork(nodes, likes)
640?wx_fmt=jpeg

我们一下子就发现了,这次的整体图形,不再是全连通的。出现了孤立节点。

这些人,既没有“喜欢”别人,也没有“被喜欢”。你自己找找看,都包括哪几个学生?

注意这个图形,是有问题的。

前面提到过,“喜欢”关系是一种有向关系。因此关系的方向很重要。但是目前这张图里面,方向是缺失的。

没关系,只需要给 likes 加入一个属性 arrow 就好。

likes$arrows <- "to"
visNetwork(nodes, likes)
640?wx_fmt=jpeg

这次就对了。

下面我们来玩儿一个更有趣的——把两个关系合并,一起观察。

我们需要记录一下,关系来自于哪张关系表格。所以分别把表名称作为属性,填到 relation 字段中。

friends$relation <- c("friend")
likes$relation <- c("likes")

看看这时候的 friends 朋友关系表。

friends
640?wx_fmt=jpeg

好了,下面我们需要合并两张表格。我们需要用到 tidyverse 软件包中的按行合并(bind_rows)功能。所以,需要首先载入tidyverse 软件包。

library(tidyverse)

然后,把原先的两张关系表,合并成一张,起名叫做 links

links <- bind_rows(friends, likes)
links

再次绘制,注意这次,关系位置上,我们放的是合并的 links

visNetwork(nodes, links)
640?wx_fmt=jpeg

两种关系,确实都绘制好了。可问题是,关系展示的颜色是一样的蓝色,看着不是很清晰。

仿照刚才对节点的颜色赋值,我们把关系连接的颜色也设置一下。

links$color <- c("green""red")[links$relation]
visNetwork(nodes, links)
640?wx_fmt=jpeg

呃……好像没有变化嘛。

聪明的你,一定可以举一反三,发现还是由于“关系”(links$relation)属性不是“因子”导致的。

我们把 relation 属性转换成因子类型。

links$relation <- as.factor(links$relation)
links$color <- c("green""red")[links$relation]
visNetwork(nodes, links)
640?wx_fmt=jpeg

太棒了!

下面,我们还是以年级作为交互选项,加入进来。

links$relation <- as.factor(links$relation)
links$color <- c("green""red")[links$relation]
visNetwork(nodes, links) %>%
  visOptions(selectedBy = "grade")
640?wx_fmt=jpeg

我们选择一下年级,拖动节点看看:

640?wx_fmt=gif

以上,是样例代码中,出现的内容解释。

小结

通过本文的学习,相信你已经掌握如何把社会网络的表格数据,用交互可视化的方法展现出来。

对于不同的元素,你也已经学会了基本的展现方式。

但请你一定不要止步于此。

首先,你需要继续查看文档。里面还有很多选项参数,此处我们没有涉及。例如说,这里我们只绘制了“关系”(边),但是却没有在其上进行任何文字标记。

640?wx_fmt=jpeg

如果你需要生成非常严肃的数据可视化作品,这些内容很可能用得上。请你点击这个链接,查看完整的文档。从中选择自己感兴趣的部分深入研读。

另外,这个工具,也绝不仅仅可以帮助你绘制社会网络图。只要是适合用网络图展现的内容,它都可以发挥作用。

希望你充分发挥自己举一反三的能力,把这项新技能用好。

祝学习愉快!

延伸阅读

你可能也会对以下话题感兴趣。点击链接就可以查看。

  • 如何用 R 绘制动态统计图?

  • 如何用4行 R 语句,快速探索你的数据集?

  • 如何用R分析CNKI文献关键词词频?

  • 如何用Python和R对故事情节做情绪分析?

  • 《文科生数据科学上手指南》分享

在为学生找寻这款工具的时候,我还发现了不少其他的优质工具和教程资源。近期会发布在知识星球中。如果你订阅了,欢迎经常来看看,并且积极参与到我们的社区讨论中来。

如果你对社会网络分析感兴趣,推荐这本书给你。

喜欢请点赞和打赏。还可以微信关注和置顶我的公众号“玉树芝兰”(nkwangshuyi)。

如果你对 Python 与数据科学感兴趣,不妨阅读我的系列教程索引贴《如何高效入门数据科学?》,里面还有更多的有趣问题及解法。

由于微信公众号外部链接的限制,文中的部分链接可能无法正确打开。如有需要,请点击文末的“阅读原文”按钮,访问可以正常显示外链的版本。

知识星球入口在这里:

640?wx_fmt=png



http://chatgpt.dhexx.cn/article/AdvyhjpA.shtml

相关文章

R语言如何绘制相互作用网络图(27)

1.什么是相互作用网络图&#xff1f; 生物网络是复杂网络&#xff0c;也是以系统科学的思想研究生命科学的桥梁。网络中的节点可以是蛋白质&#xff0c;基因&#xff0c;RNA或DNA等&#xff0c;网络的边对应节点之间的物理、生化或功能上的相互作用。生物分子之间的相互作用并…

R语言网络分析2:graph函数和应用

产生网络 自定义 BioC 中用得最多的网络类型可能是 graphNEL 类。使用 graphNEL 类的同名函数可以产生自定义网络&#xff1a; library(graph)str(graphNEL) #> function (nodes character(), edgeL list(), edgemode "undirected") nds <- letters[1:3]…

在R语言中轻松创建关联网络

数据 ## Ozone Solar.R Wind Temp Month Day ## 1 41 190 7.4 67 5 1 ## 2 36 118 8.0 72 5 2 ## 3 12 149 12.6 74 5 3 ## 4 18 313 11.5 62 5 4 ## 5 NA NA 14.3 56 5 5 ## 6 28 …

(转载)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。 堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

关于内核堆溢出漏洞的分析

一、漏洞背景 CVE-2021-22555是一个存在了15年之久的内核堆溢出漏洞&#xff0c;它位于内核的Netfilter组件中&#xff0c;这个组件可以被用来实现防火墙、NAT等功能。 该漏洞在2006年由commit 9fa492cdc160cd27ce1046cb36f47d3b2b1efa21引入&#xff0c;并在2021年由commit …

Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞

漏洞名称&#xff1a;Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞CNNVD编号&#xff1a;CNNVD-201311-423发布时间&#xff1a;2013-11-29更新时间&#xff1a;2013-11-29危害等级&#xff1a;中危 漏洞类型&#xff1a;缓冲区溢出威胁类型&#xff1a;本地CVE编号…

hackthebox-buff(gym渗透 端口转发 cloudme 缓冲区溢出 )

1、扫描 masscan快速全局扫&#xff0c;nmap具体扫。7680不知道&#xff0c;8080是web进去搜集信息。 C:\root> masscan -p1-65535,U:1-65535 10.10.10.198 --rate1000 -e tun0Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2021-01-17 09:36:41 GMT-- forced optio…

20181018栈溢出

所有内容参考书籍《0day安全&#xff1a;软件漏洞分析技术&#xff08;第二版&#xff09;》 缓冲区溢出 简单来说&#xff0c;缓冲区艺术就是在大缓冲区中的数据向小缓冲区复制的过程中&#xff0c;由于没注意小缓冲区的边界&#xff0c;“撑爆”了较小的缓冲区&#xff0c;…

再谈关于缓冲器溢出

废话少说(说一句废话,这是入门级的) C/C的代码: // buffer overflow code by ctorenshenguo.com #include <windows.h>#include <stdio.h>void fnHack() //the host never expect to run this{ printf("Your computer has been hacked!\n"); //ex…

Go内存溢出与内存泄露

https://www.cnblogs.com/sunsky303/p/11077030.html 一、内存泄露与内存溢出的区别 内存溢出(out of memory&#xff0c;简称OOM) 内存溢出是指程序在申请内存时&#xff0c;没有足够的内存空间供其使用&#xff0c;简单点说就是你要求分配的内存超出了系统能给你的&#…

(原创)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型。…

攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow) [zt]

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。 堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

linux 远程溢出,Linux Kernel蓝牙CAPI报文远程溢出漏洞

Linux Kernel是开放源码操作系统Linux所使用的内核。 Linux Kernel对入站CAPI消息没有执行正确的处理&#xff0c;远程攻击者可能利用此漏洞在服务器上执行任意指令。 Linux Kernel代码的net/bluetooth/cmtp/capi.c文件中没有正确地处理入站的CAPI消息。如果用户发送了特制的CA…

linux远程溢出,linux-ftpd-ssl 远程溢出漏洞

linux-ftpd-ssl 远程溢出漏洞 2005-11-15 eNet&Ciweek 详细描述&#xff1a; linux-ftpd-ssl是一款支持加密的FTP server。 linux-ftpd-ssl软件包中存在远程溢出漏洞&#xff0c;恶意服务器可能利用此漏洞在主机上执行任意指令。 恶意服务器生成的超长响应命令可能会覆盖栈…

html溢出攻击,溢出(漏洞)攻击的实现及防御

前言 媒体上关于系统漏洞的话题一直不断&#xff0c;在我所接触的用一些朋友和用户中虽然也知道打系统补丁很重要&#xff0c;但却又一直不以为然总以为网络上的危险离自己很远&#xff0c;大部份人都认为进行一次远程攻击很困难甚至认为只要安装了防病毒软件就一切大吉&#x…

缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

永恒之蓝漏洞复现(Windows server 2008系列缓冲区溢出漏洞)

漏洞信息 漏洞名称&#xff1a;Windows server 2008系列缓冲区溢出漏洞 CVEID&#xff1a;2017-0144 漏洞类型&#xff1a;输入验证错误 威胁类型&#xff1a;远程 发布时间&#xff1a;2017-03-14 危害等级&#xff1a;高危 漏洞简介 Microsoft服务器消息块1.0&#xff08;…

攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

缓冲区溢出实例(一)--Windows

一、基本概念 缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获取服务器控制权限等。 在Windows XP或2k3 server中的SLMail 5.5.0 Mail Server…

linux服务器接收缓冲区拥堵,Linux Kernel IP虚拟服务器栈缓冲区溢出漏洞

发布日期&#xff1a;2013-11-15 更新日期&#xff1a;2013-11-18 受影响系统&#xff1a; Linux kernel < 3.2.13 描述&#xff1a; -------------------------------------------------------------------------------- BUGTRAQ ID: 63744 CVE(CAN) ID: CVE-2013-4588 Li…