如何根据条件在R中使用igraph更改顶点形状?

3

我希望改变顶点形状,但不起作用:

我有一个如下的数据框:

Locus     X2     X3     Prophage
Vi_1236  Vi_456  5         yes
Vi_1254  Vi_263  6         no
Vi_1369  Vi_139  2         undef

我希望通过使用igraph获得一个图表,根据节点的介数中心性进行着色,当Prophage == "yes"时,我希望节点呈正方形,否则是圆形节点,未定义时为三角形节点。

因此,我进行了如下操作:

phage = graph.data.frame(innerJoinDf)
vertex = ifelse(phage$prophage == "yes","square","circle")
plot.igraph(phage, vertex.label = NA, vertex.color = betweenness(phage), vertex.shape = vertex)

我遇到了以下错误:

Error in .igraph.shapes[[shape[el[x, 1]]]] : 
  wrong arguments for subsetting an environment

你能帮助我吗?


你的数据组织方式中,“Prophage”是边属性而不是顶点属性。 - user20650
那么我该怎么做? - Théo Durand
假设您想使用 Prophage 将形状分配给 LocusX2 中给定的两个顶点,并且在这些顶点中,Prophage 在您的数据中是唯一的。一种方法是定义一个向量来保存 Prophage 属性,vertex <- setNames(rep(innerJoinDf$Prophage, 2), unlist(innerJoinDf[c("Locus", "X2")])),然后使用它来更新图形中的顶点形状属性,即在 V(g) 中,例如 V(phage)$shape = c( "circle", "square")[(vertex[V(phage)$name] == "yes") + 1L] - user20650
谢谢,它能工作了,但是“+1L”的意思是什么? - Théo Durand
例如,innerJoinDf$Prophage == "yes" 是一个逻辑向量。内部 TRUE == 1,FALSE == 0。因此,通过添加一个(1L 是整数 1),我们将逻辑向量转换为一个由一和二组成的向量(然后用于子集化 c("circle", "square") 向量,例如选择第一个或第二个元素)。 - user20650
@user20650 写成答案会更好。 - G5W
1个回答

2

innerJoinDf中组织数据的方式,将Prophage中的值解释为边缘属性。您可以通过查看igraph对象来了解这一点;其中顶点属性由v表示,边缘属性由e表示。(您可以使用vertex_attr(phage)edge_attr(phage)查看实际属性)。

library(igraph)

phage <- graph_from_data_frame(innerJoinDf)
phage
# IGRAPH d6af3b4 DN-- 6 3 -- 
# + attr: name (v/c), X3 (e/n), Prophage (e/c)
# + edges from d6af3b4 (vertex names):
# [1] Vi_1236->Vi_456 Vi_1254->Vi_263 Vi_1369->Vi_139

您的代码 vertex = ifelse(phage$prophage == "yes","square","circle") 无法正常工作,因为您不能直接使用 $ 符号访问属性(此外,Prophage 以大写字母 P 开头)。访问的一种方式是使用 V(graph)E(graph) 然后使用 $ 符号,例如 V(phage)$name

由于您想使用 Prophage 来为 LocusX2 中给出的两个顶点分配形状,因此假定在您的数据中 Prophage 对于这些顶点是唯一的。一种方法是定义一个向量来保存 Prophage 属性,然后使用它来更新图形中存储的顶点形状属性,该属性存储在 V(g) 中(当然,您也可以将 ifelse 的结果直接传递给 igraph 绘图函数,而不是显式地添加 shape 属性)。

vertex <- setNames(rep(innerJoinDf$Prophage, 2), unlist(innerJoinDf[c("Locus", "X2")])) 
vertex
# Vi_1236 Vi_1254 Vi_1369  Vi_456  Vi_263  Vi_139 
#   "yes"    "no" "undef"   "yes"    "no" "undef" 

# This seems a bit convoluted but is an attempt to match by vertex name rather than order
V(phage)$shape <- ifelse(vertex[V(phage)$name] == "yes", "square", "circle")
# or
# V(phage)$shape <- c( "circle", "square")[(vertex[V(phage)$name] == "yes") + 1L]
V(phage)$shape 
# [1] "square" "circle" "circle" "square" "circle" "circle"

数据

innerJoinDf=read.table(header=TRUE, text="
Locus     X2     X3     Prophage
Vi_1236  Vi_456  5         yes
Vi_1254  Vi_263  6         no
Vi_1369  Vi_139  2         undef")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接