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

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

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

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

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