1

I have a matrix from which I construct a network graph with igraph. I want to store the information of different types of vertices as an attribute, which I can deduce from its names. I tried a couple of combinations

mymat = matrix(c(1,0),6,5)
colnames(mymat) <- c("tim", "tom","jane","tarzan", "maria")
rownames(mymat) <- c("tim", "tom","jane","tarzan", "maria", "megan")
M <- graph_from_incidence_matrix(mymat)

V(M)$gender <- ifelse(V(M) == startsWith(as.character(V(M)),"t"), "male","female")
V(M)$gender

[1] "female" "female" "female" "female" "female" "female" "female" "female" "female" "female" "female"

I started but forgot to call for the name of the attribute.

V(M)
V(M)$name

V(M)$gender <- ifelse(V(M)$name == startsWith(as.character(V(M)$name),"t"), "male","female")

Nothing there, too. By accident I called this:

V(M)$gender <- ifelse(V(M) == startsWith(as.character(V(M)$name),"t"), "male","female")
V(M)$gender
 [1] "male"   "female" "female" "female" "female" "female" "female" "female" "female" "female" "female"

But why not the others, I thought? Seems as it looks only at the first one?

V(M)$gender <- ifelse(V(M) == startsWith(as.character(V(M)$name),"to"), "male","female")
V(M)$gender

Again, nothing.

  1. Is something wrong with how I use ifelse? Do I need to write a function?

  2. Is there something wrong with how I call on the attributes' name?

  3. off-topic: Why does graph_from_incidence_matrix or igraph in general create a "type"-attribute and on which grounds is "false" and "true" assigned here. You may see it here by

    get.vertex.attribute(M)

slinel
  • 61
  • 7

1 Answers1

0

I'm not an expert with igraph, but I'd like to try answering to the best of my ability. If someone sees this answer and notices something that is incorrect, please do comment so I can fix!

First, it sounds like you wish to identify which vertices start with the letter "t" and assign a gender value. Based on V(M) you have 11 vertices in your graph:

V(M)

+ 11/11 vertices, named, from f5ca776:
 [1] tim    tom    jane   tarzan maria  megan  tim    tom    jane   tarzan maria 

Some with repeating names.

To first check if the name starts with "t", your code is partially correct here:

startsWith(V(M)$name, "t")
# alternative: startsWith(attr(V(M), "names"), "t")

[1]  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE

This gives you a logical vector where the names attribute starts with "t". And this looks correct.

So, for your ifelse statement, you already have the logical value needed to determine gender. You don't need to compare this with V(M).

M <- set_vertex_attr(M, 
                     "gender", 
                     value = ifelse(startsWith(V(M)$name, "t"), "male", "female"))
M

IGRAPH f5ca776 UN-B 11 15 -- 
+ attr: type (v/l), name (v/c), gender (v/c)
+ edges from f5ca776 (vertex names):
 [1] tim  --tim    tim  --tom    tim  --jane   tim  --tarzan tim  --maria  jane --tim    jane --tom    jane --jane  
 [9] jane --tarzan jane --maria  maria--tim    maria--tom    maria--jane   maria--tarzan maria--maria 

You now have the attribute created for gender:

V(M)$gender

[1] "male"   "male"   "female" "male"   "female" "female" "male"   "male"   "female" "male"   "female"

Now, you noticed there's the type attribute created. Your graph was determined to be bipartite:

is_bipartite(M)

[1] TRUE

To visualize, you could do the following:

plot(M, layout = layout_as_bipartite(M))

Or fix up this way based on type:

V(M)[type]$color <- 'green'
V(M)[!type]$color <- 'yellow'

V(M)$x <- c(rep(1, 6), rep(2, 5))
V(M)$y <- c(seq(1, 5, length.out = 6), seq(1, 5, length.out = 5))

V(M)$label.cex <- .5
V(M)$size <- 30

plot(M)

Based on TRUE/FALSE values, we colored by green and yellow and separated spatially.

bipartite plot

Ben
  • 28,684
  • 5
  • 23
  • 45