简体   繁体   中英

How to convert a symmetric matrix in an adjacency list?

I would like to know what is the fastest way to create an adjacency list from an adjacency matrix in R. I am currently using a for-for approach, but as I have to deal with big matrices a fastest approach would be helpful.

An example matrix:

  A B C D
A 1 2 3 4
B 2 1 2 3
C 3 2 1 2
D 4 3 2 1

The expected adjacency list:

A B 2
A C 3 
A D 4
B C 2
B D 3
C D 2

Below is a testthat test that covers my current code:

test_that("Matrix to List", {
  mat <- matrix(c(1,2,3,4,
                  2,1,2,3,
                  3,2,1,2,
                  4,3,2,1), ncol=4)
  colnames(mat) <- rownames(mat) <- letters[1:4]
  adj <- matrixToAdjacencyList(mat)
  expected <- data.frame(Columns=c("a", "a", "a", "b", "b", "c"),
                            Rows=c("b", "c", "d", "c", "d", "d"),
                           Value=c(2,3,4,2,3,2))
  expect_identical(adj, expected)
})

Thanks a lot.

You can treat your matrix like a table and use the data.frame method.

mat[lower.tri(mat, diag = TRUE)] <- NA
na.omit(data.frame(as.table(mat)))
#    Var1 Var2 Freq
# 5     A    B    2
# 9     A    C    3
# 10    B    C    2
# 13    A    D    4
# 14    B    D    3
# 15    C    D    2

From here, it's just a matter of cleaning up your dimnames and reordering your output to get your exact desired output for your testthat .

(Or, use upper.tri instead of lower.tri in the first line, and then it's a matter of changing the column order to c(2, 1, 3) to get the right column order--that might be more efficient than ordering many rows.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM