3
$\begingroup$

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}}; 
Join[Transpose[{Join[{""}, head[[1]]]}], Join[head[[{2}]], data], 
  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"]]
$\endgroup$
2
  • $\begingroup$ "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. $\endgroup$
    – Jason B.
    Commented Apr 26, 2022 at 21:56
  • 1
    $\begingroup$ had trouble with the code block; just re-entered the code $\endgroup$
    – user42700
    Commented Apr 26, 2022 at 21:57

3 Answers 3

4
$\begingroup$

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"]]*)
$\endgroup$
1
  • $\begingroup$ Very nice and many thanks for sharing your insights ... regards ... prg $\endgroup$
    – user42700
    Commented Apr 26, 2022 at 22:31
1
$\begingroup$
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]

enter image description here

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

enter image description here

$\endgroup$
0
$\begingroup$

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]

enter image description here

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]

enter image description here

$\endgroup$
1
  • $\begingroup$ thank you, kglr the undirected switchover is very clever!! $\endgroup$
    – user42700
    Commented May 7, 2022 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.