4
$\begingroup$

I have a list mapping two keys to each element, {{key1, key2}, value}, and would like to display this as a table with horizontal headers for each key1 and vertical headers for each key2, with the values being in the cells.

For example, I would like to display

{{{1, 1}, 0.54}, {{1, 2}, 0.85}, {{1, 3}, 0.24}, {{2, 1}, 0.43}, {{2, 2}, 0.99}, {{2, 3}, 0.11}, {{3, 1}, 0.10}, {{3, 2}, 0.23}, {{3, 3}, 0.94}}

as:

    1       2       3
1   0.54    0.85    0.24
2   0.43    0.99    0.11
3   0.10    0.23    0.94

What is the easiest way to do this?

$\endgroup$
3
  • 2
    $\begingroup$ Could you post a representative example? $\endgroup$
    – Feyre
    Commented Aug 10, 2016 at 13:49
  • $\begingroup$ @Feyre, I've added an example $\endgroup$
    – user42220
    Commented Aug 10, 2016 at 13:56
  • $\begingroup$ If your list is called lst, does this work in general? TableForm[GatherBy[lst, #[[1, 1]] &][[All, All, 2]], TableHeadings -> Transpose@lst[[All, 1]]] $\endgroup$
    – march
    Commented Aug 10, 2016 at 15:48

3 Answers 3

5
$\begingroup$

If

lst = {{{1, 1}, 0.54}, {{1, 2}, 0.85}, {{1, 3}, 0.24}, {{2, 1}, 0.43},
       {{2, 2}, 0.99}, {{2, 3}, 0.11}, {{3, 1}, 0.10}, {{3, 2}, 0.23},
       {{3, 3}, 0.94}, {{4, 1}, 0.10}, {{4, 2}, 0.23}, {{4, 3}, 0.94}};

Then

TableForm[
  GatherBy[lst, #[[1, 1]] &][[All, All, 2]], 
  TableHeadings -> DeleteDuplicates /@ Transpose@lst[[All, 1]]
 ]

enter image description here

If your elements are always indexed in order, starting with 1, etc., then

TableForm[
  SparseArray[Rule @@@ lst], 
  TableHeadings -> DeleteDuplicates /@ Transpose@lst[[All, 1]]
 ]

also works.

$\endgroup$
2
$\begingroup$

A bit ugly, but still can give you what you need.

show[list_] := 
 Module[{xvalues, yvalues, assox, assoy, tab}, {xvalues, yvalues} = 
   DeleteDuplicates /@ Transpose@list[[;; , 1]];
  {assox, assoy} = 
   Association@Thread[# -> Range@Length@#] & /@ {xvalues, yvalues};
  tab = ConstantArray[Missing[], {Length@xvalues, Length@yvalues}];
  (tab[[assox[#[[1, 1]]], assoy[#[[1, 2]]]]] = #[[2]]) & /@ list;
  Grid[Transpose@
    Prepend[Transpose@Prepend[tab, yvalues], Prepend[xvalues, ""]], 
   Dividers -> {2 -> Red, 2 -> Red}]]

show[yourlist]

The main idea is to create an empty list first, then filling them according to {x,y} in each pair like {{x,y},value}.

you can test this function more throughly with, check the behaviour with larger list and missing elements here:

show[{#, RandomInteger[{0, 10}]} & /@ 
  Delete[Tuples[RandomSample[Range[20], 7] & /@ {1, 1}], {{3}, {7}}]]

your situation

my situation

$\endgroup$
1
$\begingroup$

Example

Module[
 {data, rows, columns},

 data = Partition[row[[All, 2]], 3];
 rows = Range @ Length @ data;
 columns = Range @ Length @ First @ data;

 Grid @ Prepend[MapThread[Prepend, {data, rows}], Prepend[columns, ""]]
 ]
$\endgroup$

Your Answer

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