Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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} }
share|improve this question
3  
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 at 3:54
    
In this case their names are just the name of variable. IE: datatable1 is named "datatable1" –  olliepower Apr 27 at 3:58
    
@olliepower: lol, typing as you commented... same idea –  rasher Apr 27 at 4:06
add comment

2 Answers 2

up vote 8 down vote accepted
info[tbl_] := With[{s = SparseArray[tbl]},
  ArrayPad[Append @@@ Transpose[{s["NonzeroPositions"], s["NonzeroValues"]}], 
          {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}} 
*)
share|improve this answer
    
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 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. –  rasher Apr 27 at 4:20
    
I have appended to my OP. Thank you once again. –  olliepower Apr 27 at 5:26
    
@olliepower: appended answer –  rasher Apr 27 at 7:05
add comment

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}}
share|improve this answer
    
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 at 4:05
    
I have updated the answer. Please check new version. –  Alexey Popkov Apr 27 at 8:24
    
@AlexeyPopkov please take a look at chat –  Kuba Apr 27 at 8:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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