2

I have read the R igraph - save layout?, but in my case it is requared to save positions of begin's and end's edges into a file with the edge list together.

I have a tree igraph object and predefined mylayout layout on the plane.

tree <- make_tree(5, 2, mode = "undirected")
mylayout <- matrix(c(1, 2, 0, 3, 2, 
                     1, 2, 0, 2, 3), ncol=2)

I have add a new attribute name

tree <- make_tree(5, 2, mode = "undirected") %>% 
            set_vertex_attr("name", value = seq(1:vcount(tree)))

and I get the edge list of graph via the get.edgelist() function, and I am going to use name attribute:

   df1 <- data.frame(V1 = get.edgelist(tree)[,1], 
                  V2 = get.edgelist(tree)[,2], 
#           V1_x = mylayout[as.integer(names(V(tree))), 1],
#           V1_y = mylayout[as.integer(names(V(tree))), 2],
#           V2_x = mylayout[, 1],
#           V2_y = mylayout[, 2],
            stringsAsFactors = FALSE)

Question. How to match the nodes positions with the begin's and end's positions of edges?

Nick
  • 1,086
  • 7
  • 21

2 Answers2

2

You can try this

get.data.frame(tree) %>%
  cbind(
    split(
      data.frame(mylayout)[match(unlist(.), 1:nrow(mylayout)), ],
      c(col(.))
    )
  )

which gives

  from to 1.X1 1.X2 2.X1 2.X2
1    1  2    1    1    2    2
2    1  3    1    1    0    0
3    2  4    2    2    3    2
4    2  5    2    2    2    3
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
  • your code works on the my toy example. Now I try to rewrite it on the common case. My problem is the order of edges and nodes. In the output one can see ordered rows, but in common case I have another order. – Nick Aug 17 '21 at 04:48
1

I don't know if there's an existing way to do this, but it's not too much work to write a helper function to do this

join_layout <- function(g, layout) {
  edges <- as_edgelist(g)
  idx1 <- match(edges[,1], V(g)$name)
  idx2 <- match(edges[,2], V(g)$name)
  result <- cbind(data.frame(edges),
        layout[idx1, ],
        layout[idx2, ]
  )
  names(result) <- c("V1", "V2", "V1_x", "V1_y", "V2_x","V2_y")
  result
}

Basically we use match() to match up the vertex names to rows in the layout matrix. You call it by passing in the igraph object and your layout

join_layout(tree, mylayout)
#   V1 V2 V1_x V1_y V2_x V2_y
# 1  1  2    1    1    2    2
# 2  1  3    1    1    0    0
# 3  2  4    2    2    3    2
# 4  2  5    2    2    2    3
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • your code works. I have tried to create the graph from the result date.frame, but have a problem with layout. Is it an optimal way to save edge's relations and node's positions? – Nick Aug 16 '21 at 10:50
  • I hope I found the problem for common case, I open the new question https://stackoverflow.com/questions/68858311/how-to-define-the-order-of-rows-before-writing-to-file – Nick Aug 20 '21 at 07:20