Igraph入门指南 3

4、图转换到其他R数据结构

图是对实体关系的表达,在igraph中,图可以转换为三种数据结构。

4-1 图转邻接矩阵:as_adjacency_matrix | as_adj,结果是矩阵

邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵,但本函数使用无向图,有向图忽略边的方向,矩阵可以是上三角、下三角或一般矩阵,这通过参数type设置;

百度百科:

邻接矩阵(Adjacency Matrix)是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn}。G的邻接矩阵是一个具有下列性质的n阶方阵:

①对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零(在此仅讨论无向简单图),副对角线不一定为0,有向图则不一定如此。

②在无向图中,任一顶点i的度为第i列(或第i行)所有非零元素的个数,在有向图中顶点i的出度为第i行所有非零元素的个数,而入度为第i列所有非零元素的个数。

③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。

> g <- sample_gnp(10, 2 / 10)
> as_adjacency_matrix(g)
10 x 10 sparse Matrix of class "dgCMatrix"

 [1,] . . . . . . 1 . . .
 [2,] . . . . 1 1 . . . .
 [3,] . . . 1 . . . 1 . .
 [4,] . . 1 . . . . . . .
 [5,] . 1 . . . . . 1 1 .
 [6,] . 1 . . . . . . . .
 [7,] 1 . . . . . . . . 1
 [8,] . . 1 . 1 . . . . .
 [9,] . . . . 1 . . . . .
[10,] . . . . . . 1 . . .

可见,邻接矩阵用行位置和列位置来匹配边的起始顶点和终止顶点,如果两个顶点间存在一条边,就在交接处填入数字1。如果想找一条边起点,需要看该表在矩阵中的行号,终点需要看列号。

MIT 的Gilbert Strang教授在线性代数视频中,也用矩阵表示图,但他在起始顶点的位置填-1,在终点位置填1,他的表示法和igraph不同,矩阵所有元素之和是0,似乎有特殊的数学意义。

邻接矩阵,igraph默认填入数字1,如果想将边的属性值(比如边的权值)填入,可以通过设置参数attr = "weight实现:

> E(g)$weight <- 2
> as_adjacency_matrix(g, attr = "weight")
10 x 10 sparse Matrix of class "dgCMatrix"
  [[ suppressing 10 column names ‘a’, ‘b’, ‘c’ ... ]]

a . . . . . . 2 . . .
b . . . . 2 2 . . . .
c . . . 2 . . . 2 . .
d . . 2 . . . . . . .
e . 2 . . . . . 2 2 .
f . 2 . . . . . . . .
g 2 . . . . . . . . 2
h . . 2 . 2 . . . . .
i . . . . 2 . . . . .
j . . . . . . 2 . . .

igraph默认用顶点的ID号对应邻接矩阵的行号和列号,但如果设置了顶点的name属性,igraph会自动用顶点名替换邻接矩阵的行号

> V(g)$name <- letters[1:vcount(g)]
> as_adjacency_matrix(g)
10 x 10 sparse Matrix of class "dgCMatrix"
  [[ suppressing 10 column names ‘a’, ‘b’, ‘c’ ... ]]

a . . . . . . 1 . . .
b . . . . 1 1 . . . .
c . . . 1 . . . 1 . .
d . . 1 . . . . . . .
e . 1 . . . . . 1 1 .
f . 1 . . . . . . . .
g 1 . . . . . . . . 1
h . . 1 . 1 . . . . .
i . . . . 1 . . . . .
j . . . . . . 1 . . .
4-2 专用函数:二部邻接矩阵as_biadjacency_matrix

据百度百科:二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(U,V),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in U,j in V),则称图G为一个二分图。
在这里插入图片描述

g <- make_bipartite_graph(c(0, 1, 0, 1, 0, 0), c(1, 2, 2, 3, 3, 4))
as_biadjacency_matrix(g)
  2 4
1 1 0
3 1 1
5 0 0
6 0 0
plot(g,layout=-layout_as_bipartite(g))

在这里插入图片描述

4-3 图转邻接表:as_adj_list | as_adj_edge_list,结果是列表

igraph的as_adj_list和网页一些邻接列表的介绍不同,网上很多文章形容邻接列表是“对图的每个顶点都创建一个单链表,每个单链表都存储与该顶点直接相连的顶点。”

igraph不是这样,它用list数据结构,先列出一个顶点,随后列出这个顶点的邻接顶点

> g <- make_ring(10)
> as_adj_list(g)
[[1]]
+ 2/10 vertices, from 74ab1d3:
[1]  2 10

[[2]]
+ 2/10 vertices, from 74ab1d3:
[1] 1 3

[[3]]
+ 2/10 vertices, from 74ab1d3:
[1] 2 4

[[4]]
+ 2/10 vertices, from 74ab1d3:
[1] 3 5

igraph默认用顶点ID显示,但如果图的顶点设置了name属性,则用Name,但label属性不行

> g <- make_ring(10) %>% set_vertex_attr('name',value = letters[1:10])
> as_adj_list(g)
$a
+ 2/10 vertices, named, from 600b734:
[1] b j

$b
+ 2/10 vertices, named, from 600b734:
[1] a c

$c
+ 2/10 vertices, named, from 600b734:
[1] b d

> g <- make_ring(10) %>% set_vertex_attr('label',value = letters[1:10])
> as_adj_list(g)
[[1]]
+ 2/10 vertices, from a6a7d0d:
[1]  2 10

[[2]]
+ 2/10 vertices, from a6a7d0d:
[1] 1 3

[[3]]
+ 2/10 vertices, from a6a7d0d:
[1] 2 4

如果想将结果用边的方式展示,可以用as_adj_edge_list函数,用法相同,只是显示形式不同:

> as_adj_edge_list(g)
[[1]]
+ 2/10 edges from a6a7d0d:
[1] 1-- 2 1--10

[[2]]
+ 2/10 edges from a6a7d0d:
[1] 1--2 2--3

[[3]]
+ 2/10 edges from a6a7d0d:
[1] 2--3 3--4

因为函数返回的结果是列表,可以向普通列表一样检索它:

> as_adj_edge_list(g)[1:3]
[[1]]
+ 2/10 edges from a6a7d0d:
[1] 1-- 2 1--10

[[2]]
+ 2/10 edges from a6a7d0d:
[1] 1--2 2--3

[[3]]
+ 2/10 edges from a6a7d0d:
[1] 2--3 3--4

> as_adj_edge_list(g)[[1]]
+ 2/10 edges from a6a7d0d:
[1] 1-- 2 1--10
4-4 图转边列表:as_edgelist函数,结果是矩阵或数组

边列表类似于电子表格的结构,igraph把边列表看作图的标准表示。as_edgelist用每行用起止两个顶点来表示存在一条边外,并不显示图的其他属性(顶点的name属性除外,如果顶点设置的name属性,则用name属性取代顶点 ID)

> g <- sample_gnp(10, 2 / 10)
> as_edgelist(g)
     [,1] [,2]
[1,]    3    4
[2,]    2    5
[3,]    2    6
[4,]    1    7

> V(g)$name <- LETTERS[seq_len(gorder(g))]
> as_edgelist(g)
     [,1] [,2]
[1,] "C"  "D" 
[2,] "B"  "E" 
[3,] "B"  "F" 
[4,] "A"  "G" 

> g <- sample_gnp(10, 2 / 10)
> V(g)$label <- letters[seq_len(gorder(g))]
> as_edgelist(g)
      [,1] [,2]
 [1,]    1    3
 [2,]    1    4
 [3,]    1    5
 [4,]    2    5

5、图转换为其他数据格式

5-1 与Pajek互通的.net

Pajek是开源的大型复杂网络分析工具,是用于研究目前所存在的各种复杂非线性网络的有力工具,用于带上千乃至数百万个结点大型网络的分析和可视化操作。

igraph可以直接输出Pajek支持的.net文件格式

write_graph(g,'g.net',format = 'pajek')`

*Vertices 10
*Edges
1 3
1 4
1 5
2 5
5 7

输出的结果采用的是边列表的结构,但没有顶点名信息。

目前,我在igraph函数中没有找到解决生成的.net 文件中没有顶点名的问题,便自己写了一个函数data.frame(v=paste(1:gorder(g),V(g)$name))手动复制的.net 文件中

附录:pajek读入.net 中文乱码解决办法

使用pajek官网推荐的BabelPad软件(下载地址:BabelStone : BabelPad (Unicode Text Editor for Windows))

运行该软件,打开.net文件,文件–>另存,Engcoding下拉菜单中选择 ”GB18030"即可。
在这里插入图片描述

5-2 与graph包互通的graphNel:as_graphnel
g <- make_ring(10)
V(g)$name <- letters[1:10]
GNEL <- as_graphnel(g)
g2 <- graph_from_graphnel(GNEL)
5-3 与电子表格互通的data.frame:as_data_frame 简版

把电子表格转换为图将放在图的创建部分,本节只谈把图转换为data.farme

转换时可通过设置what参数,决定转换顶点、边、还是两者都转换

本命令只输出构成表的两个顶点的ID或name,不显示边或顶点的其他属性,如需显示其他属性,用5-4的命令。

> igraph::as_data_frame(g,what = 'vertices')
  name
a    a
    b
c    c
d    d

> igraph::as_data_frame(g,what = 'edges')
  from to
1    b  c
2    a  d
3    d  e
4    a  f

> igraph::as_data_frame(g,what = 'both')
$vertices
  name
a    a
b    b
c    c
d    d

$edges
  from to
1    b  c
2    a  d
3    d  e
4    a  f

注意,R语言中多个包都有as_data_frame函数,比如tibble包、dplyr包、igraph包,所以如果执行上面示例提示错误的话,请在函数前面家包名igraph::as_data_frame()

5-4 与电子表格互通的data.frame:as_long_data_frame 显示属性版

as_long_data_frame包含关于图的顶点和边的所有元数据。它为每条边包含一行,关于该边及其关联顶点的所有元数据都包含在该行中。包含偶发顶点元数据的列的名称以from_和to_为前缀。前两列始终命名为from和to,它们包含入射顶点的数字id。这些行按数字顶点ID的顺序列出。

> g <- make_(ring(10),
+   with_vertex_(name= letters[1:10],color='green'), 
+   with_edge_(weight=1:10,color='red'))

> as_long_data_frame(g)
   from to weight color from_name from_color to_name to_color
1     1  2      1   red         a      green       b    green
2     2  3      2   red         b      green       c    green
3     3  4      3   red         c      green       d    green
4     4  5      4   red         d      green       e    green

5-5 转换为普通向量:as_ids

本函数将顶点序列或边序列转换为普通向量。

如果图的顶点没有设置name属性,则返回数字向量,如果顶点设置了name属性,则返回字符向量。

对边序列的操作有所不同,如果顶点没有name属性,直接返回边ID序列,比如有7条边,直接返回“1 2 3 4 5 6 7”。但如果顶点设置了name属性,则用a|b的格式显示每条边构成的序列:

> g <- sample_gnp(10, 2 / 10)
> as_ids(V(g))
 [1]  1  2  3  4  5  6  7  8  9 10
> V(g)$name <- letters[1:10]
> as_ids(V(g))
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
> g <- sample_gnp(10, 2 / 10)
> as_ids(E(g))
[1] 1 2 3 4 5 6 7
> V(g)$name <- letters[1:10]
> as_ids(E(g))
[1] "b|c" "d|g" "e|g" "c|h" "d|h" "e|i" "a|j"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/440792.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

老司机都懂的!【打赏】完美运营的最新视频打赏系统

完美运营的最新视频打赏系统优于市面上95%的打赏系统&#xff0c;与其他打赏系统相比&#xff0c;功能更加强大&#xff0c;完美运营且无bug。支付会调、短链接生成、代理后台、价格设置和试看功能等均没有问题。 以上为原简介&#xff0c;经测试验证。成功搭建并可以正常进入…

Linux学习之线程

目录 线程概念 1.什么是线程&#xff1f; 2.线程的优缺点 3.线程异常 4.线程用途 线程操作 1.如何给线程传参 2.线程终止 3.获取返回值 4.分离状态 5.退出线程 线程的用户级地址空间&#xff1a; 线程的局部存储 线程的同步与互斥 互斥量mutex 数据不一致的主要过…

Sora的核心技术预测

在ChatGPT火爆全网的一年后&#xff0c;OpenAI公司又一次大显身手&#xff1a;推出了全新的文生视频大模型Sora。直接输入文字提示词&#xff0c;即可直接生成长达60秒的视频。 “现实真的要不存在了。” 马斯克直接大呼&#xff1a;人类彻底完蛋了&#xff01; 马斯克为什么…

CDN(内容分发网络):加速网站加载与优化用户体验

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【NR技术】 3GPP支持无人机的关键技术以及场景

1 背景 人们对使用蜂窝连接来支持无人机系统(UAS)的兴趣浓厚&#xff0c;3GPP生态系统为UAS的运行提供了极好的好处。无处不在的覆盖范围、高可靠性和QoS、强大的安全性和无缝移动性是支持UAS指挥和控制功能的关键因素。与此同时&#xff0c;监管机构正在调查安全和性能标准以及…

WinSCP下载安装并结合内网穿透实现固定公网TCP地址访问本地服务器

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…

二叉树入门

这篇博客通过手动创建的一个简单二叉树&#xff0c;实现二叉树遍历&#xff0c;返回节点&#xff0c;叶子个数&#xff0c;查找结点等相关操作。 1. 二叉树的概念 二叉树不为空时&#xff0c;由根节点&#xff0c;左/右子树组成&#xff0c;逻辑结构如下&#xff0c;当二叉树…

上班族真香副业:工资4500,靠steam游戏搬砖项目月入过w

steam游戏搬砖项目已经存在好多年了&#xff0c;这个项目比较冷门且能持续稳定盈利&#xff0c;是一个非常不错的项目。即使你没玩过steam游戏也没关系&#xff0c;这个steam游戏搬砖项目既不需要你会玩游戏&#xff0c;也不需要你懂英语。 steam游戏搬砖项目的盈利点在汇率差和…

Lwip之TCP服务端示例记录(1对多)

前言 实现多个客户端同时连接初步代码结构已经实现完成(通过轮训的方式) // // Created by shchl on 2024/3/8. // #if 1#include <string.h> #include "lwip/api.h" #include "FreeRTOS.h" #include "task.h" #include "usart.h&…

寻找数组的中心索引

给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为 0 &#xff0c;因为在下标的左侧不存在元素。这一点…

斐讯N1 刷coreelec 笔记

1.下载恩山的镜像 下载好后不需要刷优盘 这个很方便&#xff0c;可以勾选擦除flash &#xff08;如果第一次装&#xff09; 升级可以不用勾选 详细使用参考恩山大佬的描述 2.下载插件 想装openwrt 发现镜像里面 coreelec-addons 挂了&#xff0c;研究了好长时间可以 去githu…

一文扫荡,12个可视化图表js库,收藏备用。

hello&#xff0c;我是贝格前端工场&#xff0c;可视化图表在web前端开发中经常碰到&#xff0c;是不是很疑惑这些炫酷的图表是怎么实现的&#xff0c;其实是通过js库开发的&#xff0c;本文带来12个javascript库的介绍&#xff0c;欢迎关注我&#xff0c;阅读精彩内容。 一、什…

2024 RubyMine 激活,分享几个RubyMine 激活的方案

文章目录 RubyMine 公司简介我这边使用RubyMine 的理由RubyMine 2023.3 最新变化AI Assistant 正式版对 AI 生成名称建议的支持改进了 Ruby 上下文单元测试生成 RailsRails 应用程序和引擎的自定义路径Rails 路径的自动导入对存储在默认位置之外的模型、控制器和邮件器的代码洞…

Express学习(三)

Express中间件 中间件的概念 什么是中间件 中间件&#xff0c;特指业务流程的中间处理环节。Express中间件的调用流程 当一个请求到达Express的服务器之后&#xff0c;可以连续调用多个中间件&#xff0c;从而对这次请求进行预处理。类似于下图所示 Express中间件的格式 Expr…

C++进阶之路---继承(二)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、继承与友元 友元关系不能继承&#xff0c;也就是说基类友元不能访问子类私有和保护成员。 class Student; class Per…

[C语言]——分支和循环(4)

目录 一.随机数生成 1.rand 2.srand 3.time 4.设置随机数的范围 猜数字游戏实现 写⼀个猜数字游戏 游戏要求&#xff1a; &#xff08;1&#xff09;电脑自动生成1~100的随机数 &#xff08;2&#xff09;玩家猜数字&#xff0c;猜数字的过程中&#xff0c;根据猜测数据的⼤…

【LaTeX】行内代码块、行间代码块的插入以及高亮(懒人版)

文章目录 思路和优点基本框架行内代码行间代码pythoncpp 所支持的语言所支持的代码风格 思路和优点 思路是listingsminted包&#xff0c; 一个负责插入代码一个负责高亮代码 这种方法显著的优点在于&#xff1a;完全不需要自定义代码风格 使用其他方法时&#xff0c;你定义好…

嵌入式学习36-TCP要点及http协议

TCP发送文件的粘包问题 1. 例&#xff1a; 发端 1.flv-------->收端 1.flv csfga 2.解决 1. sleep&#xff08;1&#xff09; 延时发送 2.自…

httprunner用例结构(前后置)

说明&#xff1a;httprunner 结合 pytest 的前后置方式 1. 用例级别前后置 1.1. setup teardown class TestCaseRefTestcase(HttpRunner):# 用例级别前后置def setup(self):logger.warning("------用例级别前置")def teardown(self):logger.warning("------用…

用一个 Python 脚本实现依次运行其他多个带 argparse 命令行参数的 .py 文件

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 问题描述&#xff1a;在 Windows 环境中&#xff0c;您希望通过一个 Python 脚本来实现特定的自动化任务&#xff0c;该任务需要依次运行其他多个带 argparse 命令行参数的 .py 文件。您希望找到一种简…