Home > OS >  How to change vertex.shape in R with igraph according to condition
How to change vertex.shape in R with igraph according to condition

Time:10-19

I am trying to change vertex.shape but it doesn't work :

I have a dataframe like :

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

And I want to get a graph with igraph on which I can color the nodes according to their centrality of betweeness and when Prophage == "yes" i want a square node , when its no a circle node and when its undef a triangle node.

So, I did :

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)

And I get the following error:

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

Could you please help me?

CodePudding user response:

The way your data are organised in innerJoinDf the values in the Prophage are interpreted as edge attributes. You can see this by looking at your igraph object; where the vertex attributes are indicated by the v and the edge by the e. (You can see the actual attributes using vertex_attr(phage) and 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

Your code vertex = ifelse(phage$prophage == "yes","square","circle") did not work as you cannot access the attributes directly using the $ notation (additionaly Prophage starts with an uppercase P). One of the ways to access is using V(graph) and E(graph) and then the $ notation e.g. V(phage)$name.

As you want to use Prophage to assign the shape to both vertices given in Locus and X2 this then assumes that Prophage is unique in your data for these vertices. One way to do this is to define a vector that holds the Prophage attribute and then use this to update the vertex shape attribute of your graph, which is stored in V(g) (you could of course just pass the results from the ifelse to the igraph plot function instead of explicitely adding the shape attribute).

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"

Data

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")
  • Related