百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

R 数据可视化——igraph 对象

connygpt 2024-11-18 10:41 11 浏览

igraph 对象

例如,我们有如下 igraph 对象

g <- graph(
  edges = c('A', 'B', 'B','D', 
            'C','D', 'D','E', 
            'E','G', 'F','G', 
            'G','H', 'H','I', 
            'I','J')
  )

查看对象

> g
IGRAPH 0e3645c DN-- 10 9 -- 
+ attr: name (v/c)
+ edges from 0e3645c (vertex names):
[1] A->B B->D C->D D->E E->G F->G G->H H->I I->J

在第一行中,16 进制数后面的字符分别代表:

  • DU 表示有向和无向
  • N 表示命名图,即节点有 name 属性

还有两个字符

  • W 表示加权图,即边存在 weight 属性
  • B 表示 bipartite (two-mode) graph,即节点存在 type 属性

后面的两个数值 (10 9) 表示节点和边的数量

第二行为节点和边的属性,其中括号中的字符分别表示:

  • g: graph
  • v: vertex
  • e: edge
  • n: numeric
  • c: character
  • l: logical
  • x: complex

例子中的 name 为节点的字符型属性

获取图的大小

# 获取图的顺序,即节点数
> gorder(g)
[1] 10
# 获取图的大小,即边的数量
> gsize(g)
[1] 9

提取子图

以传递节点 ID 的方式,获取指定节点及这些节点之间的边,构建子图

g2 <- induced_subgraph(g, 1:5)

以指定边 ID 的方式,获取包含指定边及边所涉及到的节点,构建子图

g3 <- subgraph.edges(g, 1:5)

1. 查询

1.1 邻接矩阵

最直接的表示图的方法是邻接矩阵,行列与节点对应,如果两个节点之间存在连接,则矩阵中对应位置的值为 1,否则为 0。对于加权图来说,值代表的是边的权重。

对于无向图来说,邻接矩阵总是对称的,而对于有向图来说并不一定是对称的。

使用 [] 可以返回对象的邻接矩阵,也可以使用 get.adjacency(g) 来获取

> g[]
10 x 10 sparse Matrix of class "dgCMatrix"
   [[ suppressing 10 column names ‘A’, ‘B’, ‘D’ ... ]]
                     
A . 1 . . . . . . . .
B . . 1 . . . . . . .
D . . . . 1 . . . . .
C . . 1 . . . . . . .
E . . . . . 1 . . . .
G . . . . . . . 1 . .
F . . . . . 1 . . . .
H . . . . . . . . 1 .
I . . . . . . . . . 1
J . . . . . . . . . .

返回的是一个稀疏矩阵

获取对应的边

> g['A', 'F']
[1] 0

0 表示不存在 AF 的边,我们可以将其设置为 1,意味着会添加这条边

> g['A', 'F'] <- 1
> g['A', 'F']
[1] 1

如果要删除一条边,可以将邻接矩阵对应位置的值设置为 0,例如

g['D', 'E'] <- 0

查询多条边会返回一个矩阵

> g[c('A', 'B', 'C'),c('A', 'B', 'C', 'D')]
3 x 4 sparse Matrix of class "dgCMatrix"
  A B C D
A . 1 . .
B . . . 1
C . . . 1

获取一个节点与其他所有节点之间的连接

> g['A',]
A B D C E G F H I J 
0 1 0 0 0 0 1 0 0 0 
> g[,'G']
A B D C E G F H I J 
0 0 0 0 1 0 1 0 0 0 

以数字索引的方式

> g[2,]
A B D C E G F H I J 
0 0 1 0 0 0 0 0 0 0 
> g[2,-1]
B D C E G F H I J 
0 1 0 0 0 0 0 0 0

条件查询

> degree(g)
A B D C E G F H I J 
2 2 2 1 1 3 2 2 2 1 
> g[degree(g) > 2, degree(g) < 3]
A B D C E F H I J 
0 0 0 0 0 0 1 0 0 

配对节点

> g[from = c('A', 'B', 'C'), to = c('C', 'D', 'E')]
[1] 0 1 0

将会查询的边为 A-CB-DC-E,需要保证 fromto 的长度一致

获取邻接节点

> neighbors(g, 'G')
+ 1/10 vertex, named, from e70593c:
[1] H

1.2 邻接表

邻接表是以表的形式来表示图的,只存储每个节点中与其相连的节点

> g[[]]
$A
+ 2/10 vertices, named, from e70593c:
[1] B F

$B
+ 1/10 vertex, named, from e70593c:
[1] D
...
$I
+ 1/10 vertex, named, from e70593c:
[1] J

$J
+ 0/10 vertices, named, from e70593c:

获取节点的邻接节点

> g[[c('A', 'B')]]
$A
+ 2/10 vertices, named, from e70593c:
[1] B F

$B
+ 1/10 vertex, named, from e70593c:
[1] D

不同方向的邻接节点

> g[['G', ]]
$G
+ 1/10 vertex, named, from e70593c:
[1] H

> g[[, 'G']]
$G
+ 2/10 vertices, named, from e70593c:
[1] E F

显示边

> g[['A', edges = TRUE]]
$A
+ 2/9 edges from e70593c (vertex names):
[1] A->B A->F

获取两个节点集合之间的边

> g[[c('A', 'B', 'C'),c('C', 'D', 'E', 'F'), edges = TRUE]]
[[1]]
+ 1/9 edge from e70593c (vertex names):
[1] A->F

[[2]]
+ 1/9 edge from e70593c (vertex names):
[1] B->D

[[3]]
+ 1/9 edge from e70593c (vertex names):
[1] C->D

2. 节点和边

使用 E()V() 函数,可以获取 igraph 对象的边和节点。例如

> E(g)
+ 9/9 edges from 063a143 (vertex names):
[1] A->B B->D C->D D->E E->G F->G G->H H->I I->J
> V(g)
+ 10/10 vertices, named, from 063a143:
 [1] A B D C E G F H I J

V() 的返回值是根据结点的 ID 进行了排序。由于我们的节点是字符型的,会根据节点添加的顺序自动为节点设置 ID,第一个节点的 ID1

可以使用两个节点名称之间添加一个竖线组成的字符串来引用连接两个节点的边,如果是无向图,则两个节点的顺序不影响边的引用

使用 ends() 可以获取边的矩阵表示

> g %>% ends('A|B')
     [,1] [,2]
[1,] "A"  "B"
>
> g %>% ends(E(g))
      [,1] [,2]
 [1,] "A"  "B" 
 [2,] "B"  "D" 
 [3,] "C"  "D" 
 [4,] "D"  "E" 
 [5,] "E"  "G" 
 [6,] "F"  "G" 
 [7,] "G"  "H" 
 [8,] "H"  "I" 
 [9,] "I"  "J" 

对于有向图,head_oftail_of 可以获取边的头尾两个端点,有箭头的一端为头

> g %>% tail_of('A|B')
+ 1/10 vertex, named, from 063a143:
[1] A
> g %>% head_of('A|B')
+ 1/10 vertex, named, from 063a143:
[1] B

使用 neighbors 来获取节点的邻接节点

> g %>% neighbors('D', mode = "in")
+ 2/10 vertices, named, from 063a143:
[1] B C
> g %>% neighbors('D', mode = "out")
+ 1/10 vertex, named, from 063a143:
[1] E

对于无向图,两种模式的邻接节点是一样的

计算边和节点的数量

> ecount(g)
[1] 9
> vcount(g)
[1] 10

2.1 序列操作

节点序列操作

> V(g)[1:4]
+ 4/10 vertices, named, from 1ee19c4:
[1] A B D C
> V(g)[1:3, 5:7]
+ 6/10 vertices, named, from 1ee19c4:
[1] A B D E G F
> V(g)[c('A', 'C', 'D', 'G')]
+ 4/10 vertices, named, from 1ee19c4:
[1] A C D G

根据邻接节点索引

> V(g)[nei('D')]
+ 3/10 vertices, named, from 1ee19c4:
[1] B C E
> V(g)[innei('D')]
+ 2/10 vertices, named, from 1ee19c4:
[1] B C
> V(g)[outnei('D')]
+ 1/10 vertex, named, from 1ee19c4:
[1] E

查询条件

> V(g)[degree(g) > 2]
+ 2/10 vertices, named, from 1ee19c4:
[1] D G

反转、去重和集合操作

> rev(V(g))
+ 10/10 vertices, named, from 1ee19c4:
 [1] J I H F G E C D B A
> unique(V(g)['A', 'A'])
+ 1/10 vertex, named, from 1ee19c4:
[1] A
> union(V(g)[1:3], V(g)[6:8])
+ 6/10 vertices, named, from 1ee19c4:
[1] A B D G F H
> intersection(V(g)[1:5], V(g)[4:8])
+ 2/10 vertices, named, from 1ee19c4:
[1] C E
> difference(V(g), V(g)[1:5])
+ 5/10 vertices, named, from 1ee19c4:
[1] G F H I J

获取边涉及的结点

> V(g)[inc('A|B'), inc('D|E')]
+ 4/10 vertices, named, from 1ee19c4:
[1] A B D E

边序列操作与节点类似

> E(g)[1:4]
+ 4/9 edges from 1ee19c4 (vertex names):
[1] A->B B->D C->D D->E
> E(g)[c('A|B', 'G|H', 'H|I')]
+ 3/9 edges from 1ee19c4 (vertex names):
[1] A->B G->H H->I

获取涉及到节点的边

> E(g)[inc('D')]
+ 3/9 edges from 1ee19c4 (vertex names):
[1] B->D C->D D->E
> E(g)[from('D')]
+ 1/9 edge from 1ee19c4 (vertex names):
[1] D->E
> E(g)[to('D')]
+ 2/9 edges from 1ee19c4 (vertex names):
[1] B->D C->D

条件索引

> E(g)[seq_len(gsize(g)) %% 2]
+ 5/9 edges from 1ee19c4 (vertex names):
[1] A->B A->B A->B A->B A->B

获取两个节点集合之间存在的边

# 不管方向
> E(g)[V(g)['D'] %--% V(g)['B', 'C', 'E']]
+ 3/9 edges from 1ee19c4 (vertex names):
[1] B->D C->D D->E
# 左到右
> E(g)[V(g)['D'] %->% V(g)['B', 'C', 'E']]
+ 1/9 edge from 1ee19c4 (vertex names):
[1] D->E
# 右到左
> E(g)[V(g)['D'] %<-% V(g)['B', 'C', 'E']]
+ 2/9 edges from 1ee19c4 (vertex names):
[1] B->D C->D

集合操作、去重和反转和节点操作一样

注意:我们在中括号中使用的简写函数只能在对应条件下使用,无法单独使用

> nei(g, 'A')
Error in nei(g, "A") : 没有"nei"这个函数
> from('A')
Error in from("A") : 没有"from"这个函数

3. 元数据属性

我们可以将节点和边的元数据(附加信息)作为属性值的方式添加到节点和边的属性中

使用 $ 可以获取和设置属性,例如,获取节点的 name 属性

> V(g)$name
 [1] "A" "B" "D" "C" "E" "G" "F" "H" "I" "J"

为节点新建一个名为 class 的属性

> V(g)$class <- rep(c("I", "II"), each = 5)
> neighbors(g, 'G', mode = "all")$class
[1] "I"  "II" "II"

为边设置属性值

> E(g)$type <- rep(c('activation', 'repression', 'inhibition'), each = 3)
> E(g)$weight <- sample(3:6, 9, replace = TRUE)

也可以使用 set_edge_attrset_vertex_attr 函数来设置,效果是一样的

获取所有节点和边的属性

> edge_attr(g)
$type
[1] "activation" "activation" "activation" "repression" "repression" "repression" "inhibition" "inhibition"
[9] "inhibition"

$weight
[1] 3 4 3 3 6 4 3 5 6

> vertex_attr(g)
$name
 [1] "A" "B" "D" "C" "E" "G" "F" "H" "I" "J"

$class
 [1] "I"  "I"  "I"  "I"  "I"  "II" "II" "II" "II" "II"

可以使用 delete_edge_attrdelete_vertex_attr 删除属性

获取图属性

> g$name
[1] "demo"
> graph_attr(g)
$name
[1] "demo"

> graph_attr_names(g)
[1] "name"
> graph_attr(g, 'name')
[1] "demo"

设置图的属性

g$name <- "demo"
# or
g <- set_graph_attr(g, 'name', 'demo')

删除图属性

> g <- set_graph_attr(g, 'some', 'something')
> graph_attr(g)
$name
[1] "demo"

$some
[1] "something"

> g <- delete_graph_attr(g, 'some')
> graph_attr(g)
$name
[1] "demo"

上面的属性设置都是在已经构建完图之后,我们也可以在构建图的时候添加属性。例如

g <- make_empty_graph(n = 5) %>%
  add_edges(c(1,2, 2,3, 3,4, 4,5)) %>%
  set_edge_attr("color", value = "red") %>%
  add_edges(c(5,1), color = "green") %>%
  set_vertex_attr("color", value = "orange") %>%
  add_vertices(3, color = "red") %>%
  add_vertices(2, color = "green")
plot(g)

在这里,我们使用 add_edgesadd_vertices 函数来添加边和节点,对应的,可以使用 delete_edgesdelete_vertices 来删除边和节点

有几个特殊的属性:



相关推荐

自学Python,写一个挨打的游戏代码来初识While循环

自学Python的第11天。旋转~跳跃~,我~闭着眼!学完循环,沐浴着while的光芒,闲来无事和同事一起扯皮,我说:“编程语言好神奇,一个小小的循环,竟然在生活中也可以找到原理和例子”,同事也...

常用的 Python 工具与资源,你知道几个?

最近几年你会发现,越来越多的人开始学习Python,工欲善其事必先利其器,今天纬软小编就跟大家分享一些常用的Python工具与资源,记得收藏哦!不然下次就找不到我了。1、PycharmPychar...

一张思维导图概括Python的基本语法, 一周的学习成果都在里面了

一周总结不知不觉已经自学Python一周的时间了,这一周,从认识Python到安装Python,再到基本语法和基本数据类型,对于小白的我来说无比艰辛的,充满坎坷。最主要的是每天学习时间有限。只...

三日速成python?打工人,小心钱包,别当韭菜

随着人工智能的热度越来越高,许多非计算机专业的同学们也都纷纷投入到学习编程的道路上来。而Python,作为一种相对比较容易上手的语言,也越来越受欢迎。网络上各类网课层出不穷,各式广告令人眼花缭乱。某些...

Python自动化软件测试怎么学?路线和方法都在这里了

Python自动化测试是指使用Python编程语言和相关工具,对软件系统进行自动化测试的过程。学习Python自动化测试需要掌握以下技术:Python编程语言:学习Python自动化测试需要先掌握Py...

Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能

这篇文章不谈江流所专研的营销与运营,而聊一聊技能学习之路,聊一聊Python这门最简单的编程语言该如何学习,我完成的第一个Python项目,将任意公众号的所有历史文章导出成PDF电子书。或许我这个Py...

【黑客必会】python学习计划

阅读Python文档从Python官方网站上下载并阅读Python最新版本的文档(中文版),这是学习Python的最好方式。对于每个新概念和想法,请尝试运行一些代码片段,并检查生成的输出。这将帮助您更...

公布了!2025CDA考试安排

CDA数据分析师报考流程数据分析师是指在不同行业中专门从事行业数据搜集、整理、分析依据数据作出行业研究评估的专业人员CDA证书分为1-3级,中英文双证就业面广,含金量高!!?报考条件:满18...

一文搞懂全排列、组合、子集问题(经典回溯递归)

原创公众号:【bigsai】头条号:程序员bigsai前言Hello,大家好,我是bigsai,longtimenosee!在刷题和面试过程中,我们经常遇到一些排列组合类的问题,而全排列、组合...

「西法带你学算法」一次搞定前缀和

我花了几天时间,从力扣中精选了五道相同思想的题目,来帮助大家解套,如果觉得文章对你有用,记得点赞分享,让我看到你的认可,有动力继续做下去。467.环绕字符串中唯一的子字符串[1](中等)795.区...

平均数的5种方法,你用过几种方法?

平均数,看似很简单的东西,其实里面包含着很多学问。今天,分享5种经常会用到的平均数方法。1.算术平均法用到最多的莫过于算术平均法,考试平均分、平均工资等等,都是用到这个。=AVERAGE(B2:B11...

【干货收藏】如何最简单、通俗地理解决策树分类算法?

决策树(Decisiontree)是基于已知各种情况(特征取值)的基础上,通过构建树型决策结构来进行分析的一种方式,是常用的有监督的分类算法。决策树算法是机器学习中的一种经典算法,它通过一系列的规则...

面试必备:回溯算法详解

我们刷leetcode的时候,经常会遇到回溯算法类型题目。回溯算法是五大基本算法之一,一般大厂也喜欢问。今天跟大家一起来学习回溯算法的套路,文章如果有不正确的地方,欢迎大家指出哈,感谢感谢~什么是回溯...

「机器学习」决策树——ID3、C4.5、CART(非常详细)

决策树是一个非常常见并且优秀的机器学习算法,它易于理解、可解释性强,其可作为分类算法,也可用于回归模型。本文将分三篇介绍决策树,第一篇介绍基本树(包括ID3、C4.5、CART),第二篇介绍Ran...

大话AI算法: 决策树

所谓的决策树算法,通俗的说就是建立一个树形的结构,通过这个结构去一层一层的筛选判断问题是否好坏的算法。比如判断一个西瓜是否好瓜,有20条西瓜的样本提供给你,让你根据这20条(通过机器学习)建立起...