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 '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

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 '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}}
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 '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

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.