How to put a newline into a column header in an xtable in R

PaulHurleyuk picture PaulHurleyuk · Apr 21, 2010 · Viewed 7.4k times · Source

I have a dataframe that I am putting into a sweave document using xtable, however one of my column names is quite long, and I would like to break it over two lines to save space

calqc_table<-structure(list(RUNID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L), ANALYTEINDEX = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L), ID = structure(1:11, .Label = c("Cal A", "Cal B", "Cal C", 
"Cal D", "Cal E", "Cal F", "Cal G", "Cal H", "Cal High", "Cal Low", 
"Cal Mid"), class = "factor"), mean_conc = c(200.619459644855, 
158.264703128903, 102.469121407733, 50.3551544728544, 9.88296440865076, 
4.41727762501703, 2.53494715706024, 1.00602831741361, 199.065054555735, 
2.48063347296935, 50.1499780776199), sd_conc = c(2.3275711264554, 
NA, NA, NA, NA, NA, NA, 0.101636943231162, 0, 0, 0), nrow = c(3, 
1, 1, 1, 1, 1, 1, 3, 2, 2, 2)), .Names = c("Identifier of the Run within the Study", "ANALYTEINDEX", 
"ID", "mean_conc", "sd_conc", "nrow"), row.names = c(NA, -11L
), class = "data.frame")
calqc_xtable<-xtable(calqc_table)

I have tried putting a newline into the name, but this didn't seem to work

names(calqc_table)[1]<-"Identifier of the \nRun within the Study"

Is there a way to do this ? I have seen someone suggest using the latex function from the hmisc package to manually iterate over the table and write it out in latex manually, including the newline, but this seems like a bit of a faf !

Answer

Sharpie picture Sharpie · Apr 22, 2010

The best way I have found to do this is to indicate the table column as a "fixed width" column so that the text inside it wraps. With the xtable package, this can be done with:

align( calqc_xtable ) <- c( 'l', 'p{1.5in}', rep('c',5) )

xtable demands that you provide an alignment for the option "rownames" column- this is the initial l specification. The section specification, p{1.5in}, is used for your first column header, which is quite long. This limits it to a box 1.5 inches in width and the header will wrap onto multiple lines if necessary. The remaining five columns are set centered using the c specifier.

One major problem with fixed width columns like p{1.5in} is that they set the text using a justified alignment. This causes the inter-word spacing in each line to be expanded such that the line will fill up the entire 1.5 inches allotted.

Frankly, in most cases this produces results which I cannot describe using polite language (I'm an amateur typography nut and this sort of behavior causes facial ticks).

The fix is to provide a latex alignment command by prepending a >{} field to the column specification:

align( calqc_xtable ) <- c( 'l', '>{\\centering}p{1.5in}', rep('c',4) )

Other useful alignment commands are:

  • \raggedright -> causes text to be left aligned
  • \raggedleft -> causes text to be right aligned

Remember to double backslashes to escape them in R strings. You may also need to disable the string sanitation function that xtable uses by default.

Note

This alignment technique will fail if used on the last column of a table unless table rows are ended with \tabularnewline instead of \\, which I think is not the case with xtable and is not easily customizable through any user-settable option.

The other thing to consider is that you may not want the entire column line-wrapped to 1.5 inches and centered- just the header. In that case, disable xtable string sanitization and set your header using a \multicolumn cell of width 1:

names(calqc_table)[1]<-"\\multicolumn{1}{>{\\centering}p{1.5in}}{Identifier of the Run within the Study}"