rigraph icon indicating copy to clipboard operation
rigraph copied to clipboard

feat: add `as.vector` parameter to `as_edgelist()`

Open Copilot opened this issue 4 months ago • 0 comments

Users need edge lists in the flat vector format c(from1, to1, from2, to2, ...) for make_graph() and C library interop. Currently requires inefficient transpose workaround: as.vector(t(as_edgelist(g))).

Changes

  • Added as.vector parameter to as_edgelist() (defaults to FALSE for backward compatibility)
  • When TRUE, returns flat vector directly from C layer without matrix conversion
  • Works with both numeric IDs and vertex names
  • ~38% faster than transpose workaround

Usage

g <- make_graph(c(1, 2, 2, 3, 3, 4, 4, 5))

# Before: inefficient transpose
edges <- as.vector(t(as_edgelist(g, names = FALSE)))

# After: direct vector output
edges <- as_edgelist(g, names = FALSE, as.vector = TRUE)

# Suitable for make_graph()
g2 <- make_graph(edges)

Addresses use cases in leidenbase (#39) and leidenAlg (#13) for efficient graph conversion.

Original prompt

This section details on the original issue you should resolve

<issue_title>Obtain an edges vector in a form suitable for make_graph()</issue_title> <issue_description>What is the feature or improvement you would like to see?

There should be a function that retrieves an edge list in a form suitable for make_graph(), as well as suitable for the C function igraph_create().

as_edgelist() returns a matrix, not a vector, and converting to a vector gives the vertex IDs in the wrong order:

> g<-make_graph(c(1,2, 2,3, 3,4, 4,5))
> as.vector(as_edgelist(g, names=F))
[1] 1 2 3 4 2 3 4 5

Instead one must transpose the matrix first, which is inefficient:

> as.vector(t(as_edgelist(g, names=F)))
[1] 1 2 2 3 3 4 4 5

A more efficient way is

> .Call(igraph:::R_igraph_get_edgelist, g, F)
[1] 0 1 1 2 2 3 3 4

but this uses an internal function.

Use cases for the feature

For libraries that need to convert igraph graphs efficiently, such as leidenbase or leidenalg.

References

  • https://github.com/cole-trapnell-lab/leidenbase/issues/39
  • https://github.com/kharchenkolab/leidenAlg/issues/13 </issue_description>

Comments on the Issue (you are @copilot in this section)

@schochastics This is `as_edgelist` ```r as_edgelist res }

Simple solution would be to a add a bool (just `arg` here) that defaults to `TRUE`?

```r
as_edgelist <- function(graph, names = TRUE, arg = TRUE) {
  ensure_igraph(graph)
  on.exit(.Call(R_igraph_finalizer))
  res <- matrix(.Call(R_igraph_get_edgelist, graph, TRUE), ncol = 2)
  res <- res + 1
  if(arg){
	res <- matrix(.Call(R_igraph_get_edgelist, graph, TRUE), ncol = 2)
  	if (names && "name" %in% vertex_attr_names(graph)) {
      res <- matrix(V(graph)$name[res], ncol = 2)
  	}
  } else{
    res <- .Call(R_igraph_get_edgelist, graph, FALSE)
    if (names && "name" %in% vertex_attr_names(graph)) {
      res <- V(graph)$name[res]
  	}
  }

  res
}
```</body></comment_new>
</comments>

  • Fixes igraph/rigraph#864

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot avatar Oct 26 '25 21:10 Copilot