# Get positions of all non zero matrix elements

I want to find all non zero elements of a table and I want to create a list that contains the name of the table the element was removed from, the position of the element, and the value of the element.

Then to the generated list I would like to apply a replacment rule to the row and the column.

rule = {1 -> "a", 2 -> "b", 3 -> "c"}

{ {tablename, row, col, value} }


For example I have tried

dataTable1 = {{1,0,0}, {0,1,0}, {0,0,-1}}

Position[Abs[dataTable1], # > 0 &]


but I am unable to get get the position. I would like the final out put to be

 { {"dataTable1", 1,1,1}, {"dataTable1", 2,2,1}, {"dataTable1", 3,3,-1} }


If we apply the replacment.

  { {"dataTable1", 1,1,1}, {"dataTable1", 2,2,1}, {"dataTable1", 3,3,-1} } /. rule


Then the output should be

 { {"dataTable1", "a","a",1}, {"dataTable1", "b","b",1}, {"dataTable1", "c","c",-1} }

-
SparseArray[dataTable1]["NonzeroPositions"] gives you your {{1, 1}, {2, 2}, {3, 3}} and "NonzeroValues" gives {1, 1, -1}. It is not quite clear from your question how the tables are organized to be able to extract their names, but I suppose you can figure the rest of it out by yourself. – Oleksandr R. Apr 27 '14 at 3:54
In this case their names are just the name of variable. IE: datatable1 is named "datatable1" – olliepower Apr 27 '14 at 3:58
@olliepower: lol, typing as you commented... same idea – ciao Apr 27 '14 at 4:06

info[tbl_] := With[{s = SparseArray[tbl]},
{0, {1, 0}}, ToString@Unevaluated@tbl]]

SetAttributes[info, HoldFirst]

result=info[dataTable1]

(* {{"dataTable1", 1, 1, 1}, {"dataTable1", 2, 2, 1}, {"dataTable1", 3, 3, -1}} *)


As to the second part of your query, assume the result from the info function is in a symbol named result, then using your example rule list,

MapAt[(# /. rule) &, result, {All, 2 ;; 3}]

(*
{{"dataTable1", "a", "a", 1}, {"dataTable1", "b", "b", 1},{"dataTable1", "c", "c", -1}}
*)

-
this worked. I have one other question. What if I want to apply a replacemnt rule to only the positions after the list has been constructed. For example info[dataTables1] /. rules Where rules should only apply to the second and third elements of each sublist. – olliepower Apr 27 '14 at 4:16
@olliepower: Need to clarify what you mean, and to where (replace things in the generated list, the original array?). Perhaps append to your OP. – ciao Apr 27 '14 at 4:20
I have appended to my OP. Thank you once again. – olliepower Apr 27 '14 at 5:26
@olliepower: appended answer – ciao Apr 27 '14 at 7:05

Is it what you want?

SetAttributes[getPos, HoldFirst];
getPos[t_Symbol] :=
Module[{pos = Position[Abs[t], _?Positive]},
Join[ConstantArray[{ToString[Unevaluated@t]}, Length[pos]], pos,
List /@ Extract[t, pos], 2]]

getPos[dataTable1]

{{"dataTable1", 1, 1, 1}, {"dataTable1", 2, 2, 1}, {"dataTable1", 3, 3, -1}}

-
The only problem with this code is if a row of the table contains all zeros. then I get {{"dataTable1"}}. I would not like to have those in the output. – olliepower Apr 27 '14 at 4:05
I have updated the answer. Please check new version. – Alexey Popkov Apr 27 '14 at 8:24
@AlexeyPopkov please take a look at chat – Kuba Apr 27 '14 at 8:37