1

I am using the package igraph in Rto be able to plot a network. However, once I pass the command vertex.size in the graph function, it does 2 things. 1) it removes a few of the edges and directed arrows from the network and 2) it gives me an error:

In layout[, 2] + label.dist * sin(-label.degree) * (vertex.size + : longer object length is not a multiple of shorter object length

Here is some reproducible data that shows the errors:

Setting up the data

stack.edges <- data.frame(from = c("XTD-PRI", "XTD-PRI", "EVS-16", "EVS-16", "EVS-16", "J-4", "J-4", "Sigma", "Sigma", "T-1"), 
                to = c("XTD-PRI", "E-6", "T-5", "XCP-8", "A-1", "P-1", "M-3", "Sigma", "MST-8", "EVS-16"))

stack.vtx <- data.frame(ID = c("XTD-PRI", "XTD-PRI", "EVS-16", "EVS-16", "EVS-16", "J-4", "J-4", "Sigma", "Sigma", "T-1"), Freq = c(1, 2, 2, 2, 1, 2, 2, 2, 2, 1), 
    color = c("#F0027F", "#F0027F", "#7FC97F", "#7FC97F", "#7FC97F", "#F0027F", "#F0027F", "#FDC086", "#FDC086", "#7FC97F"))

Graphing the network

library(igraph)
stack_graph <- graph_from_data_frame(stack.edges, directed = TRUE)

plot(stack_graph, 
     layout = layout_in_circle(stack_graph),
     edge.width = 1.5,
     edge.arrow.size = 0.3,
     vertex.shape = "circle", 
     vertex.color = stack.vtx$color, 
     vertex.label.color = "black") 
     #vertex.size = stack.vtx$Freq)

Now, compare the above graph by removing the '#' in front of the vertex.size parameter. To note, passing ex) vertex.size = 10 will work.

My objective: to graph the vertices by the size of the stack.vtx$Freq vector, so 7 of the circles (vertices) should be twice as large as the other 3 circles (vertices).

During my research for this error, I have found the following:

  1. This error occurs when performing a function on vectors when they are not the same length. However, this is not the case here, as both vectors (stack.edges & stack.vtx) are both the same length (ex source: Why do I get "warning longer object length is not a multiple of shorter object length"?).
  2. The command rescale_vertex_igraph by the package netdiffuseR. According to the documentation: "This function rescales a vertex size before passing it to plot.igraph." I tried vertex.size = rescale_vertex_igraph(stack.vtx$Freq, adjust = 200). This does resize the size of the vertices, but not proportional (instead of the 7 vertices being 2x's as large as the other 3 vertices, they look like they are 4x's as large and I still get the same error.
  3. Following the advice on this post: igraph edges disappear when specifying vertex size I have also tried to rescale the stack.vtx$Freq values by 'playing' around with them and passing values such as: vertex.size = stack.vtx$Freq/2); vertex.size = stack.vtx$Freq * 3.14 but none of these options work and remove edges altogether and does not resize it the way I would like.

Any help on resizing my vertices based on the stack.vtx$Freq vector would be greatly appreciated!

Szabolcs
  • 24,728
  • 9
  • 85
  • 174
Purrsia
  • 712
  • 5
  • 18

1 Answers1

3

If you look at the collection of vertices:

verts <- c(stack.edges$from, stack.edges$to)
unique(verts)
 [1] "XTD-PRI" "EVS-16"  "J-4"     "Sigma"   "T-1"     "E-6"     "T-5"     "XCP-8"   "A-1"     "P-1"     "M-3"     "MST-8"  

There are 12 unique vertices defined. The frequency column in stack.vtx is only 10 elements long. In fact only 5 of the 12 vertices are mentioned in stack.vtx data.frame and with conflicting values for some of the duplicate vetices.

One can use:

vertex_attr(stack_graph)

to obtain the list of vertices in the proper order and use this as a guide to create the vector of vertex.size. Also check to ensure the coloring is correct.
I don't know why "vertex.color" did not generate the same error. Maybe just a quirk or color is handled slightly differently.

Dave2e
  • 22,192
  • 18
  • 42
  • 50
  • 2
    After correcting the vertex set as advised above, include the definition of the vertices into: `stack_graph <- graph_from_data_frame(stack.edges, directed = TRUE, vertices=stack.vtx)`. The advantage is that any inconsistency between edges and vertices is detected when creating the graph. – clp Dec 31 '22 at 11:49
  • Thank you for answering this. To make sure I understand correctly, every single string in the stack.edges$from and stack.edges$to vectors need to be included in the stack.vtx$ID column - even if this means the number of rows of both data-frames will not be the same? Yes, there are duplicates in the stack.vtx$ID column - because each ID corresponds to a project ID and some of these projects - ex) XTD-PRI reach out to w/in their own organization (edge: XTD-PRI-XTD-PRI), or to a different organization (edge: XTD-PRI-E-6) and the stack.vtx$Freq states how many times. Can this not be graphed? – Purrsia Jan 01 '23 at 05:32
  • You could represent projects as vertices, and the relationships between projects as edges. Use project names as vertex ids. In that case, `freq` is an edge property, representing the number of relationships between projects. There is a useful example in `>help(graph_from_data_frame)`. Any project that appears in the edges (`from` or `to`) must be defined in the vertex set, otherwise it is impossible to draw an edge. As a guide to modelling use vertex entities as nouns (project) and edges as verbs. – clp Jan 01 '23 at 11:12
  • Thank you for your response. I have chosen the 'checkmark' to say this is the answer, bc you have identified exactly why I'm getting this error. Thank-you for this suggestion about representing projects as vertices but that is not what I am aiming for. I need the stack.vtx$ID to be my vertices, not individual projects as there is no relationship between projects, only within projects . The graph above is exactly what I need - each edge in the graph above is an individual project - I will repost with this exact issue on a different post bc its past the issue for this post. Thank-you. – Purrsia Jan 01 '23 at 17:55