# Center column heading in TableForm

I have a TableForm as follows:

cosine[r_, theta_] := Sqrt[2 r^2 (1 - Cos[theta/360 * 2*Pi])];
rows = Range[1000, 10000, 1000];
cols = Prepend[Range[.5, 2, .5], ""];
TableForm[m, TableHeadings -> {rows, Rest@cols}, TableAlignments -> "."]

which produces:

However, I would like to center the column headings and remove all the trailing decimal points. I have not found any way to center just the column headings while keeping the values decimal/right aligned. I have seen some complicated methods of removing the decimal point by converting the values to a string and then doing string manipulations to remove the decimal point, which seems like a hack to me, so I am hoping there is a straightforward way.

## 2 Answers

Is this what you had in mind?

cosine[r_, theta_] := Sqrt[2 r^2 (1 - Cos[theta/360*2*Pi])];
m = Table[IntegerPart[cosine[r, t]], {r, 1000, 10000, 1000}, {t, 0.5, 2., .5}];
rows = Range[1000, 10000, 1000];
TableForm[m, TableHeadings -> {rows, {"0.5", "1.0", "1.5", "2.0"}}, TableAlignments -> Right]

Note that m is undefined in your question, but I surmise that my definition is close to what you intended.

Of OP's two requirements

1. center the column headings and
2. remove all the trailing decimal points.

@bbgodfrey's answer addresses the second.

Unfortunately, getting both requirements, i.e.,

to center just the column headings while keeping the values decimal/right aligned.

using TableForm is impossible since TableAlignments is not flexible enough to align individual rows, columns or items separately. That is, aligments can only be specified for each dimension (rows and/or columns), and row (column) headers inherit the alignment settings of the rows (columns). This can be seen by modifying the input matrix m in bbgodfrey's answer:

m = Table[IntegerPart[cosine[r, t]], {r, 1000, 10000, 1000}, {t, 0.5, 2., .5}];
mb = RandomChoice[{1, 100, 10000}] # & /@ m;
rows = 1000 Range[10]; cols = .5 Range[4];
Column[Table[Labeled[Grid[{Table[TableForm[i, TableHeadings -> {rows, cols},
TableAlignments -> j], {i, {m, mb}}]}, ItemSize -> All, Dividers -> All],
Style[TableAlignments -> j, 16], Top], {j, {Right, Center}}], Spacer[15], Dividers -> All]

A work-around is to wrap column headings with Pane or Framed:

TableForm[mb, TableHeadings -> {rows,
Pane[#, ImageSize -> {Scaled[.1], Automatic}, Alignment -> Center] & /@ cols},
TableAlignments -> Right]

Using Grid:

A much more flexible approach is to use Grid. To useGridwe need to add row and column headers to the input matrixmb`. This can be done in a number of ways using any of the methods suggested in this answer to the OP's related question. For example,

hF = Fold[Prepend[Transpose@#, #2] &, #, {#2, Join @@ {{""}, #3}}] &;

mb2 = hF[mb, rows, cols];

Now, we can use Item with the option Alignment->Center to modify the the first row of mb2

mb3 = mb2;
mb3[[1]] = Item[#, Alignment -> Center] & /@ mb3[[1]];
Grid[mb3, Dividers -> {2 -> True, 2 -> True}, Alignment -> Right]

Alternatively, we can use the third element of the Alignment option settings for Grid to set the alignments for the elements in the first row:

Grid[mb2, Dividers -> {2 -> True, 2 -> True},
Alignment -> {Right, Center, MapIndexed[{1, 1 + First@#2} -> Center &, cols]},
ItemStyle -> {{Directive[Red, 20, Italic, "Panel"]}, {Directive[Blue, 20, Italic, "Panel"]}}]

• For times with wide numeric columns, such as you have illustrated, one alternative to centering per se, might be to convert the heading to a string with a few spaces at the right. This might position the headings roughly in the middle of the number with an average length, giving an aesthetic result, even though it is not a true centering of the column label. Feb 15, 2015 at 19:11
• @Tyler, you can also use Pane or Frame (both with the option Alignment->Center) to wrap each of the column headers and experiment with different values for ImageSize.
– kglr
Feb 15, 2015 at 21:46