# How to Derive the Edge List From Adjacency Matrix with Given Row/Col Headers

I've written the following code. It correctly is deriving the edge list from the matrix but it is by row # and col # instead of row name and column name. My questions are (1) how can I add the row and col names to the edge list instead of the row/col numbers and (2) how can I control the edge list to be directed or undirected as options to be generated?

data = {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0,
1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 1,
1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
0}, {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0}}; head = {{S0, S1, S2, S3, S4, S5, S6, S7, S8}, {c1, c2, c3, c4,
c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16}};
2] // Grid
rownames = {S0, S1, S2, S3, S4, S5, S6, S7, S8};
colnames = {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13,
c14, c15, c16}; edgelist =
Rest[Rule @@@ SparseArray[data]["NonzeroPositions"]]

• "I've written the following code" - did you mean to paste the code here? You need to add an example to show what you mean. Commented Apr 26, 2022 at 21:56
• had trouble with the code block; just re-entered the code Commented Apr 26, 2022 at 21:57

Here's a suggestion:

(1) Apply[rownames[[#1]] -> colnames[[#2]] &, SparseArray[data]["NonzeroPositions"], {1}]

(2) Apply[rownames[[#1]] \[UndirectedEdge] colnames[[#2]] &, SparseArray[data]["NonzeroPositions"], {1}]

As for directed or undirected being options, I would guess what you're wanting is to turn this into a function. It should probably take the row names and column names as arguments. Maybe something like this:

NamedDirectedEdges[rownames_, colnames_, edgelist_] :=
Apply[rownames[[#1]] -> colnames[[#2]] &, edgelist, {1}];
NamedUndirectedEdges[rownames_, colnames_, edgelist_] :=
Apply[rownames[[#1]] \[UndirectedEdge] colnames[[#2]] &, edgelist, {1}];

(*Usage: NamedDirectedEdges[rownames, colnames, SparseArray[data]["NonzeroPositions"]]*)

• Very nice and many thanks for sharing your insights ... regards ... prg Commented Apr 26, 2022 at 22:31
ClearAll[toEdges]
toEdges[e : (DirectedEdge | UndirectedEdge) : DirectedEdge] :=
MapThread[{r, c} |-> e[#2[[r]], #3[[c]]]] @
Transpose[SparseArray[#]["NonzeroPositions"]] &;


Examples:

Graph[toEdges[][data, rownames, colnames], VertexLabels -> Automatic]


Graph[toEdges[UndirectedEdge][data, rownames, colnames], VertexLabels -> Automatic]


You can also use data to construct an AdjacencyMatrix and use it with AdjacencyGraph (specifying vertex names in the first argument) and extract the EdgeList:

dam = ArrayFlatten[{{0, data}, {  0 Transpose @ data , 0}}];

del = EdgeList @ AdjacencyGraph[Join[rownames, colnames], dam];

Graph[del, VertexLabels -> Automatic]


To get an undirected graph replace 0 Transpose @ data with Transpose @ data:

uam = ArrayFlatten[{{0, data}, {   Transpose@data , 0}}];

uel = EdgeList @ AdjacencyGraph[Join[rownames, colnames], uam];

Graph[uel, VertexLabels -> Automatic]


• thank you, kglr the undirected switchover is very clever!! Commented May 7, 2022 at 19:40