Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract edge types for all shortest paths in R with igraph?

Tags:

r

igraph

igraph has two useful functions, shortest_paths and all_shortest_paths. The former outputs one of the shortest paths, the other outputs all of them. However, the former also is able to output the edge types of the path while the latter doesn't seem to be able to.

How do I use all_shortest_paths to extract the "edge type" for all of the shortest paths? I have provided clarifying code below:

library(igraph)
m <- read.table(row.names=1, header=TRUE, text=
                  " A B C D
                A 0  1  1  0  
                B 0  0 0  1 
                C 0 0  0  1
                D 0  0  0  0")
m <- as.matrix(m)
ig <- graph.adjacency(m, mode="directed")
plot(ig)
E(ig)
for (i in 1:length(E(ig))) {
  
  if (i == 4) {
    
    E(ig)[i]$type <- -1
  } else {

    E(ig)[i]$type <- 1
  }
  
}

###This gets one of the shortest paths
test1 <- shortest_paths(ig, from = V(ig)[1], to = V(ig)[4], mode = "out", output = "epath")

###This outputs the types for the shortest path above
test1$epath[[1]]$type

###This gets all the shortest paths
test2 <- all_shortest_paths(ig, from = V(ig)[1], to = V(ig)[4], mode = "out")

###The code below doesn't work. How do I get the types for ALL the shortest paths?
test2$res[[1]]$type
like image 685
Nova Avatar asked Nov 19 '25 06:11

Nova


2 Answers

Try the code below

df <- get.data.frame(ig)
lapply(
  test2$res,
  function(x) {
    nm <- names(x)
    merge(
      df,
      data.frame(from = head(nm, -1), to = tail(nm, -1))
    )$type
  }
)

and you will get

[[1]]
[1]  1 -1

[[2]]
[1] 1 1

If you want to see more information, you can use

df <- get.data.frame(ig)
lapply(
  test2$res,
  function(x) {
    nm <- names(x)
    merge(
      df,
      data.frame(from = head(nm, -1), to = tail(nm, -1))
    )
  }
)

and you will get

[[1]]
  from to type
1    A  C    1
2    C  D   -1

[[2]]
  from to type
1    A  B    1
2    B  D    1
like image 95
ThomasIsCoding Avatar answered Nov 22 '25 02:11

ThomasIsCoding


This can be done relatively simply while looping through the test2$res and using igraph's accessor function as_ids():

suppressMessages(library(igraph))
m <- read.table(row.names=1, header=TRUE, text=
                  " A B C D
                A 0  1  1  0  
                B 0  0 0  1 
                C 0 0  0  1
                D 0  0  0  0")
m <- as.matrix(m)
ig <- graph.adjacency(m, mode="directed")
plot(ig)
E(ig)
for (i in 1:length(E(ig))) {
  if (i == 4) {
    E(ig)[i]$type <- "green"
  } else {
    E(ig)[i]$type <- "red"
  }
}

OriginalGraph <- get.data.frame(x = ig)
EdgeTypesPresent <- vector(mode = "list",
                           length = length(test2))

for (m1 in seq_along(test2$res)) {
  p1 <- as_ids(test2$res[[m1]])
  EdgeTypesPresent[[m1]] <- unique(OriginalGraph$type[OriginalGraph$from %in% p1 &
                                                        OriginalGraph$to %in% p1])
  
}

This gives us:

> EdgeTypesPresent
[[1]]
[1] "red"   "green"

[[2]]
[1] "red"
like image 28
Nick Avatar answered Nov 22 '25 02:11

Nick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!