Hard_Course
Hard_Course

Reputation: 311

Counting number of viable pathways in a network diagram from a specific node input

small network example

I'm trying to identify and count all non-zero pathways starting from a specific node in a network (here N2). Each step through a node is 1, so from N2 to Z3 would be a length of 2. I'd like to extract each possible pathway as rows with node ID in separate columns, and have a count as well. This is the matrix from the above diagram and as far as I got:

mat1 <- read.table(text = "
  X1 N1 N2 A2 Z3  M
1 N1 -1  0 -1  0  0
2 N2  0 -1 -1  0  0
3 A2  1  1  0 -1 -1
4 Z3  0  0  1 -1  0
5  M  0  0  1  0 -1
", header = TRUE)

mat1 <- as.matrix(mat1)

nzpath <- which(mat1 != 0, arr.ind = TRUE)

pathways <- data.frame(
  row = nzpath[, 1],
  column = nzpath[, 2],
  value = mat1[nzpath[, 1], nzpath[, 2]])

the desired output example:

out <- read.table(text = "
  node1 node2 node3 count
1 N2 A2 Z3 2
", header = TRUE)

Upvotes: 3

Views: 69

Answers (1)

Friede
Friede

Reputation: 7979

You might want to find a less convoluted (removing at least some lapply()'s) solution from

v0

result = local({
  l <-
    lapply(colnames(mat1), \(v) igraph::all_simple_paths(g, v, mode = "out")) |>
    unlist(recursive = FALSE) |>
    lapply(\(x) names(x))

  n <- lengths(l)
  m <- max(n)
  l <- lapply(l, `length<-`, m)

  data.frame(
    do.call("rbind", l) |>
      data.frame() |>
      setNames(c("from", paste0("to", seq(m-1)))),
    count = n - 1,
    row.names = NULL
  )
})

giving

> result 
  from to1  to2 count
1   N1  A2 <NA>     1
2   N1  A2    M     2
3   N1  A2   Z3     2
4   N2  A2 <NA>     1
5   N2  A2    M     2
6   N2  A2   Z3     2
7   A2   M <NA>     1
8   A2  Z3 <NA>     1

Corrected input:

mat1 <- matrix(
  c(
    1, 0, 0, 0, 0,
    0, 1, 0, 0, 0,
    0, 0, 1, 0, 1,
    0, 0, 0, 1, 1,
    1, 1, 0, 0, 0
  ),
  nrow = 5, ncol = 5, byrow = TRUE, 
  dimnames = list(NULL, c("M", "Z3", "N1", "N2", "A2"))
)
g <- igraph::graph_from_adjacency_matrix(mat1, mode = "directed")

One advantage of {base} + {igraph} is that we do not need to care about changes in, say, {tidyverse}, which has alternatives to the advertised base functions.

Upvotes: 3

Related Questions