
Basics
The htmlTable package is intended for generating tables using HTML formatting. This format is compatible with Markdown when used for HTML-output. The most basic table can easily be created by just passing a matrix
or a data.frame
to the htmlTable
-function:
|
Column 1
|
Column 2
|
Row 1
|
1
|
3
|
Row 2
|
2
|
4
|
As of version 1.0.2 you no longer need to specify results='asis'
for each knitr
chunk.
Advanced
While it may be sufficient for basic tables a more advanced layout is often needed in medical publications with elements such as:
- row groups
- column spanners
- table spanners
- caption
- table footer
- zebra coloring (also know as banding):
As many journals require that a MS Word-document is submitted it is furthermore also important that the table imports correctly to a word processor, i.e. that the table doesn’t only look nice in a web browser but also in the final document. The htmlTable
-function is written for all these purposes.
Note: Due to GitHub CSS-styles the rows get automatically zebra-striped (in a bad way), borders get overridden and I haven’t been able to figure out how to change this. See the vignette for a correct example: vignette("general", package = "htmlTable")
For demonstration purposes we will setup a basic matrix:
mx <-
matrix(ncol=6, nrow=8)
rownames(mx) <- paste(c("1st", "2nd",
"3rd",
paste0(4:8, "th")),
"row")
colnames(mx) <- paste(c("1st", "2nd",
"3rd",
paste0(4:6, "th")),
"hdr")
for (nr in 1:nrow(mx)){
for (nc in 1:ncol(mx)){
mx[nr, nc] <-
paste0(nr, ":", nc)
}
}
Row groups
The purpose of the row groups is to group variables that belong to the same group, e.g. a factored variable with more than two levels often benefit from grouping variables together.
|
1st hdr
|
2nd hdr
|
3rd hdr
|
4th hdr
|
5th hdr
|
6th hdr
|
Group A
|
1st row
|
1:1
|
1:2
|
1:3
|
1:4
|
1:5
|
1:6
|
2nd row
|
2:1
|
2:2
|
2:3
|
2:4
|
2:5
|
2:6
|
Group B
|
3rd row
|
3:1
|
3:2
|
3:3
|
3:4
|
3:5
|
3:6
|
4th row
|
4:1
|
4:2
|
4:3
|
4:4
|
4:5
|
4:6
|
5th row
|
5:1
|
5:2
|
5:3
|
5:4
|
5:5
|
5:6
|
6th row
|
6:1
|
6:2
|
6:3
|
6:4
|
6:5
|
6:6
|
Group C
|
7th row
|
7:1
|
7:2
|
7:3
|
7:4
|
7:5
|
7:6
|
8th row
|
8:1
|
8:2
|
8:3
|
8:4
|
8:5
|
8:6
|
We can easily mix row groups with regular variables by having an empty row group name ""
:
|
1st hdr
|
2nd hdr
|
3rd hdr
|
4th hdr
|
5th hdr
|
6th hdr
|
Group A
|
1st row
|
1:1
|
1:2
|
1:3
|
1:4
|
1:5
|
1:6
|
2nd row
|
2:1
|
2:2
|
2:3
|
2:4
|
2:5
|
2:6
|
Group B
|
3rd row
|
3:1
|
3:2
|
3:3
|
3:4
|
3:5
|
3:6
|
4th row
|
4:1
|
4:2
|
4:3
|
4:4
|
4:5
|
4:6
|
5th row
|
5:1
|
5:2
|
5:3
|
5:4
|
5:5
|
5:6
|
6th row
|
6:1
|
6:2
|
6:3
|
6:4
|
6:5
|
6:6
|
7th row
|
7:1
|
7:2
|
7:3
|
7:4
|
7:5
|
7:6
|
8th row
|
8:1
|
8:2
|
8:3
|
8:4
|
8:5
|
8:6
|
When mixing row groups with variables without row groups we may want to omit the bold formatting of the row group label:
|
1st hdr
|
2nd hdr
|
3rd hdr
|
4th hdr
|
5th hdr
|
6th hdr
|
Group A
|
1st row
|
1:1
|
1:2
|
1:3
|
1:4
|
1:5
|
1:6
|
2nd row
|
2:1
|
2:2
|
2:3
|
2:4
|
2:5
|
2:6
|
Group B
|
3rd row
|
3:1
|
3:2
|
3:3
|
3:4
|
3:5
|
3:6
|
4th row
|
4:1
|
4:2
|
4:3
|
4:4
|
4:5
|
4:6
|
5th row
|
5:1
|
5:2
|
5:3
|
5:4
|
5:5
|
5:6
|
6th row
|
6:1
|
6:2
|
6:3
|
6:4
|
6:5
|
6:6
|
7th row
|
7:1
|
7:2
|
7:3
|
7:4
|
7:5
|
7:6
|
8th row
|
8:1
|
8:2
|
8:3
|
8:4
|
8:5
|
8:6
|
Column spanners
A column spanner spans 2 or more columns:
|
Cgroup 1
|
|
Cgroup 2
|
|
1st hdr
|
2nd hdr
|
|
3rd hdr
|
4th hdr
|
5th hdr
|
6th hdr
|
1st row
|
1:1
|
1:2
|
|
1:3
|
1:4
|
1:5
|
1:6
|
2nd row
|
2:1
|
2:2
|
|
2:3
|
2:4
|
2:5
|
2:6
|
3rd row
|
3:1
|
3:2
|
|
3:3
|
3:4
|
3:5
|
3:6
|
4th row
|
4:1
|
4:2
|
|
4:3
|
4:4
|
4:5
|
4:6
|
5th row
|
5:1
|
5:2
|
|
5:3
|
5:4
|
5:5
|
5:6
|
6th row
|
6:1
|
6:2
|
|
6:3
|
6:4
|
6:5
|
6:6
|
7th row
|
7:1
|
7:2
|
|
7:3
|
7:4
|
7:5
|
7:6
|
8th row
|
8:1
|
8:2
|
|
8:3
|
8:4
|
8:5
|
8:6
|
It can sometimes be convenient to have column spanners in multiple levels:
htmlTable(mx,
cgroup = rbind(c("", "Column spanners", NA),
c("", "Cgroup 1", "Cgroup 2")),
n.cgroup = rbind(c(1,2,NA),
c(2,2,2)))
|
|
|
Column spanners
|
|
|
|
Cgroup 1
|
|
Cgroup 2
|
|
1st hdr
|
2nd hdr
|
|
3rd hdr
|
4th hdr
|
|
5th hdr
|
6th hdr
|
1st row
|
1:1
|
1:2
|
|
1:3
|
1:4
|
|
1:5
|
1:6
|
2nd row
|
2:1
|
2:2
|
|
2:3
|
2:4
|
|
2:5
|
2:6
|
3rd row
|
3:1
|
3:2
|
|
3:3
|
3:4
|
|
3:5
|
3:6
|
4th row
|
4:1
|
4:2
|
|
4:3
|
4:4
|
|
4:5
|
4:6
|
5th row
|
5:1
|
5:2
|
|
5:3
|
5:4
|
|
5:5
|
5:6
|
6th row
|
6:1
|
6:2
|
|
6:3
|
6:4
|
|
6:5
|
6:6
|
7th row
|
7:1
|
7:2
|
|
7:3
|
7:4
|
|
7:5
|
7:6
|
8th row
|
8:1
|
8:2
|
|
8:3
|
8:4
|
|
8:5
|
8:6
|
Above example allows the column spanner to be a sum of the underlying cgroups (see n.cgroup), this is not required by the function:
htmlTable(mx,
cgroup = rbind(c("", "Column spanners", NA),
c("", "Cgroup 1", "Cgroup 2")),
n.cgroup = rbind(c(1,5,NA),
c(2,1,3)))
|
|
|
Column spanners
|
|
|
|
Cgroup 1
|
|
Cgroup 2
|
|
1st hdr
|
|
2nd hdr
|
|
3rd hdr
|
|
4th hdr
|
5th hdr
|
6th hdr
|
1st row
|
1:1
|
|
1:2
|
|
1:3
|
|
1:4
|
1:5
|
1:6
|
2nd row
|
2:1
|
|
2:2
|
|
2:3
|
|
2:4
|
2:5
|
2:6
|
3rd row
|
3:1
|
|
3:2
|
|
3:3
|
|
3:4
|
3:5
|
3:6
|
4th row
|
4:1
|
|
4:2
|
|
4:3
|
|
4:4
|
4:5
|
4:6
|
5th row
|
5:1
|
|
5:2
|
|
5:3
|
|
5:4
|
5:5
|
5:6
|
6th row
|
6:1
|
|
6:2
|
|
6:3
|
|
6:4
|
6:5
|
6:6
|
7th row
|
7:1
|
|
7:2
|
|
7:3
|
|
7:4
|
7:5
|
7:6
|
8th row
|
8:1
|
|
8:2
|
|
8:3
|
|
8:4
|
8:5
|
8:6
|
Table spanners
A table spanner is similar to rgroup but has the primary purpose of combining 2 or more tables with the same columns into one:
|
1st hdr
|
2nd hdr
|
3rd hdr
|
4th hdr
|
5th hdr
|
6th hdr
|
Spanner A
|
1st row
|
1:1
|
1:2
|
1:3
|
1:4
|
1:5
|
1:6
|
2nd row
|
2:1
|
2:2
|
2:3
|
2:4
|
2:5
|
2:6
|
Spanner B
|
3rd row
|
3:1
|
3:2
|
3:3
|
3:4
|
3:5
|
3:6
|
4th row
|
4:1
|
4:2
|
4:3
|
4:4
|
4:5
|
4:6
|
5th row
|
5:1
|
5:2
|
5:3
|
5:4
|
5:5
|
5:6
|
6th row
|
6:1
|
6:2
|
6:3
|
6:4
|
6:5
|
6:6
|
Spanner C
|
7th row
|
7:1
|
7:2
|
7:3
|
7:4
|
7:5
|
7:6
|
8th row
|
8:1
|
8:2
|
8:3
|
8:4
|
8:5
|
8:6
|
Table caption
The table caption is simply the table description and can be either located above or below the table:
Table 5: A table caption above
|
|
1st hdr
|
2nd hdr
|
1st row
|
1:1
|
1:2
|
2nd row
|
2:1
|
2:2
|
|
1st hdr
|
2nd hdr
|
1st row
|
1:1
|
1:2
|
2nd row
|
2:1
|
2:2
|
Table 6: A table caption below
|
A more interesting detail that the function allows for is table numbering, initialized by:
Table 1: A table caption with a numbering
|
|
1st hdr
|
2nd hdr
|
1st row
|
1:1
|
1:2
|
2nd row
|
2:1
|
2:2
|
As we often want to reference the table number in the text there are two associated functions:
## [1] 1
## [1] 2
The footer usually contains specifics regarding variables and is always located at the foot of the table:
|
1st hdr
|
2nd hdr
|
1st row
|
1:1
|
1:2
|
2nd row
|
2:1
|
2:2
|
A table footer
|
Putting it all together
Now if we want to do everything in one table it may look like this:
htmlTable(mx,
align="r",
rgroup = paste("Group", LETTERS[1:3]),
n.rgroup = c(2,4,nrow(mx) - 6),
cgroup = rbind(c("", "Column spanners", NA),
c("", "Cgroup 1", "Cgroup 2†")),
n.cgroup = rbind(c(1,2,NA),
c(2,2,2)),
caption="A table with column spanners, row groups, and zebra striping",
tfoot="† A table footer commment",
cspan.rgroup = 2,
col.columns = c(rep("none", 2),
rep("#F5FBFF", 4)),
col.rgroup = c("none", "#F7F7F7"),
css.cell = "padding-left: .5em; padding-right: .2em;")
Table 2: A table with column spanners, row groups, and zebra striping
|
|
|
|
Column spanners
|
|
|
|
Cgroup 1
|
|
Cgroup 2†
|
|
1st hdr
|
2nd hdr
|
|
3rd hdr
|
4th hdr
|
|
5th hdr
|
6th hdr
|
Group A
|
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right;'></td>
<td style='font-weight: 900;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td>
<td style='font-weight: 900; background-color: #f5fbff;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td></tr>
<tr>
<td style='text-align: left;'> 1st row</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right;'>1:1</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right;'>1:2</td>
<td style='' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>1:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>1:4</td>
<td style='background-color: #f5fbff;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>1:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>1:6</td>
</tr>
<tr>
<td style='text-align: left;'> 2nd row</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right;'>2:1</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right;'>2:2</td>
<td style='' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>2:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>2:4</td>
<td style='background-color: #f5fbff;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>2:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>2:6</td>
</tr>
<tr><td colspan='2' style='font-weight: 900; background-color: #f7f7f7;'>Group B</td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; background-color: #f7f7f7; text-align: right;'></td>
<td style='font-weight: 900; background-color: #f7f7f7;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #F6F9FB;'></td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #F6F9FB;'></td>
<td style='font-weight: 900; background-color: #F6F9FB;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #F6F9FB;'></td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #F6F9FB;'></td></tr>
<tr style='background-color: #f7f7f7;'>
<td style='background-color: #f7f7f7; text-align: left;'> 3rd row</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>3:1</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>3:2</td>
<td style='background-color: #f7f7f7;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>3:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>3:4</td>
<td style='background-color: #F6F9FB;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>3:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>3:6</td>
</tr>
<tr style='background-color: #f7f7f7;'>
<td style='background-color: #f7f7f7; text-align: left;'> 4th row</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>4:1</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>4:2</td>
<td style='background-color: #f7f7f7;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>4:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>4:4</td>
<td style='background-color: #F6F9FB;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>4:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>4:6</td>
</tr>
<tr style='background-color: #f7f7f7;'>
<td style='background-color: #f7f7f7; text-align: left;'> 5th row</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>5:1</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>5:2</td>
<td style='background-color: #f7f7f7;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>5:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>5:4</td>
<td style='background-color: #F6F9FB;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>5:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>5:6</td>
</tr>
<tr style='background-color: #f7f7f7;'>
<td style='background-color: #f7f7f7; text-align: left;'> 6th row</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>6:1</td>
<td style='padding-left: .5em; padding-right: .2em; background-color: #f7f7f7; text-align: right;'>6:2</td>
<td style='background-color: #f7f7f7;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>6:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>6:4</td>
<td style='background-color: #F6F9FB;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>6:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #F6F9FB;'>6:6</td>
</tr>
<tr><td colspan='2' style='font-weight: 900;'>Group C</td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right;'></td>
<td style='font-weight: 900;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td>
<td style='font-weight: 900; background-color: #f5fbff;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td>
<td style='padding-left: .5em; padding-right: .2em; font-weight: 900; text-align: right; background-color: #f5fbff;'></td></tr>
<tr>
<td style='text-align: left;'> 7th row</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right;'>7:1</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right;'>7:2</td>
<td style='' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>7:3</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>7:4</td>
<td style='background-color: #f5fbff;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>7:5</td>
<td style='padding-left: .5em; padding-right: .2em; text-align: right; background-color: #f5fbff;'>7:6</td>
</tr>
<tr>
<td style='border-bottom: 2px solid grey; text-align: left;'> 8th row</td>
<td style='padding-left: .5em; padding-right: .2em; border-bottom: 2px solid grey; text-align: right;'>8:1</td>
<td style='padding-left: .5em; padding-right: .2em; border-bottom: 2px solid grey; text-align: right;'>8:2</td>
<td style='border-bottom: 2px solid grey;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; border-bottom: 2px solid grey; text-align: right; background-color: #f5fbff;'>8:3</td>
<td style='padding-left: .5em; padding-right: .2em; border-bottom: 2px solid grey; text-align: right; background-color: #f5fbff;'>8:4</td>
<td style='border-bottom: 2px solid grey; background-color: #f5fbff;' colspan='1'> </td>
<td style='padding-left: .5em; padding-right: .2em; border-bottom: 2px solid grey; text-align: right; background-color: #f5fbff;'>8:5</td>
<td style='padding-left: .5em; padding-right: .2em; border-bottom: 2px solid grey; text-align: right; background-color: #f5fbff;'>8:6</td>
</tr>
</tbody>
<tfoot><tr><td colspan='9'>
† A table footer comment</td></tr></tfoot>