2
$\begingroup$

I would like to make a table with row and column headings being the arguments to a function and the values to be the value of the function. So far, I have this:

cosine[r_, theta_] := Sqrt[2 r^2 (1 - Cos[theta/360 * 2*Pi])];

m = Table[cosine[r, theta], {r, 1000, 10000, 1000}, {theta, .5, 2, .5}]

Grid[m]

This prints out the values. How do I get the r-values to be along the side and the theta values as the column headings, ideally with lines to make it clear they are headings?

$\endgroup$

1 Answer 1

3
$\begingroup$

Update 2: Rather than processing the table m to add headers, we can define a function modifyF that modifies f to return first and/or second argument passed to f for specific argument patterns; and, then use modifyF[f] to construct the table. One way, out of many ways, to do that is:

ClearAll[modifyF];
modifyF[f_] := {##} /. {{_String, a_} :> a, {b_, _String} :> b, 
                        {_String, _String} :> "", {x_, y_} :> f[x, y]} &;

Examples:

Table[modifyF[cosine][r, t], 
     {r, Prepend[1000 Range[10], ""]}, {t, Prepend[.5 Range[4], ""]}] // Grid

enter image description here

To get the first argument as the row header, prepend the iterator list for the column index with a String element`:

Table[modifyF[cosine][r, t], {r, 1000 Range[10]}}, {t, Prepend[.5 Range[4], ""]}] // Grid

enter image description here

Similarly, To get the second argument as the colum header, prepend the iterator list for the row index with a String element`:

Table[modifyF[cosine][r, t], {r,  Prepend[1000 Range[10], ""]}, {t, .5 Range[4]}] // Grid

enter image description here

Update: Define a function that takes a matrix and row and column headers:

headersF = Module[{jtF=Join@@{{#2}, Transpose@#}&}, Fold[jtF, #, {#2, Join@@{{""}, #3}}]]&;
headersF[m, 1000 Range[10], .5 Range[4]] // Grid

enter image description here

The following two variations give the same output as headerF:

headersF2 = Module[{ptF=Prepend[Transpose@#, #2]&}, Fold[ptF, #, {#2, Join@@{{""}, #3}}]]&;
headersF3 = Fold[Transpose[ArrayFlatten[{{#2, #}}]] &, #, 
                 List /@ # & /@ {#2, ArrayPad[#3, {1, 0}, ""]}] &;

rows = Range[1000, 10000, 1000];
cols = Prepend[Range[.5, 2, .5], ""];

The following all give the same output as above:

Prepend[Transpose[Prepend[Transpose@m, rows]], cols] // Grid
ptF = Prepend[Transpose@#, #2] &;  Fold[ptF, m, {rows, cols}] // Grid
tF = Join @@ {{#2}, Transpose@#} &; Fold[jtF, m, {rows, cols}] // Grid
ArrayPad[ArrayPad[m, {{0}, {1, 0}}, List /@ rows], {{1, 0}, {0}}, cols]  // Grid

Alternatively, you can use TableForm:

TableForm[m, TableHeadings -> {rows, Rest@cols}]
$\endgroup$
2
  • $\begingroup$ The prepend form certainly is tortuous. I was hoping for a way to do it without going to the length of creating row/col arrays, but I guess that is inevitable. $\endgroup$ Feb 13, 2015 at 23:14
  • $\begingroup$ @Tyler, updated with hopefully less "torturous" alternatives:) I think a single application of ArrayPad should do the job but I could not find right form yet. $\endgroup$
    – kglr
    Feb 13, 2015 at 23:44

Your Answer

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

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