Output an HTML table
This is a function for outputting a more advanced
tables using HTML. The core philosophy is to bring column and row groups
into the table and allow for a dense representation of
complex tables. The HTML-output is designed for
maximum compatibility with copy-paste functionality into
word-processors. For adding styles, see addHtmlTableStyle()
and themes setHtmlTableTheme()
. Note: If you are using
tidyverse and dplyr you may want to check out
tidyHtmlTable()
that automates many of the arguments
that htmlTable
requires.
htmlTable( x, header = NULL, rnames = NULL, rowlabel = NULL, caption = NULL, tfoot = NULL, label = NULL, rgroup = NULL, n.rgroup = NULL, cgroup = NULL, n.cgroup = NULL, tspanner = NULL, n.tspanner = NULL, total = NULL, ctable = TRUE, compatibility = getOption("htmlTableCompat", "LibreOffice"), cspan.rgroup = "all", escape.html = FALSE, ... ) ## Default S3 method: htmlTable( x, header = NULL, rnames = NULL, rowlabel = NULL, caption = NULL, tfoot = NULL, label = NULL, rgroup = NULL, n.rgroup = NULL, cgroup = NULL, n.cgroup = NULL, tspanner = NULL, n.tspanner = NULL, total = NULL, ctable = TRUE, compatibility = getOption("htmlTableCompat", "LibreOffice"), cspan.rgroup = "all", escape.html = FALSE, ... ) ## S3 method for class 'htmlTable' knit_print(x, ...) ## S3 method for class 'htmlTable' print(x, useViewer, ...)
x |
The matrix/data.frame with the data. For the |
header |
A vector of character strings specifying column
header, defaulting to |
rnames |
Default row names are generated from |
rowlabel |
If the table has row names or |
caption |
Adds a table caption. |
tfoot |
Adds a table footer (uses the |
label |
A text string representing a symbolic label for the
table for referencing as an anchor. All you need to do is to reference the
table, for instance |
rgroup |
A vector of character strings containing headings for row groups.
|
n.rgroup |
An integer vector giving the number of rows in each grouping. If |
cgroup |
A vector, matrix or list of character strings defining major column header. The default
is to have none. These elements are also known as column spanners. If you want a column not
to have a spanner then put that column as "". If you pass cgroup and |
n.cgroup |
An integer vector, matrix or list containing the number of columns for which each element in
cgroup is a heading. For example, specify |
tspanner |
The table spanner is somewhat of a table header that you can use when you want to join different tables with the same columns. |
n.tspanner |
An integer vector with the number of rows or |
total |
The last row is sometimes a row total with a border on top and
bold fonts. Set this to |
ctable |
If the table should have a double top border or a single a' la LaTeX ctable style |
compatibility |
Is default set to |
cspan.rgroup |
The number of columns that an |
escape.html |
logical: should HTML characters be escaped? Defaults to FALSE. |
... |
Passed on to |
useViewer |
If you are using RStudio there is a viewer thar can render
the table within that is envoced if in |
string
Returns a string of class htmlTable
cgroup
If you want to have a column spanner in multiple levels you can
set the cgroup
and n.cgroup
arguments to a matrix
or
list
.
If the different levels have different number of elements and you have
provided a matrix you need to set the ones that lack elements to NA. For instance
cgroup = rbind(c("first", "second", NA), c("a", "b", "c"))
.
And the corresponding n.cgroup
would be n.cgroup = rbind(c(1, 2, NA), c(2, 1, 2))
.
for a table consisting of 5 columns. The "first" spans the first two columns,
the "second" spans the last three columns, "a" spans the first two, "b"
the middle column, and "c" the last two columns.
It is recommended to use list
as you will not have to bother with the NA
.
If you want leave a cgroup
empty then simply provide ""
as the cgroup
.
rgroup
argumentThe rgroup
allows you to smoothly group rows. Each row within a group
receives an indention of two blank spaces and are grouped with their
corresponding rgroup
element. The sum(n.rgroup)
should always
be equal or less than the matrix rows. If less then it will pad the
remaining rows with either an empty rgroup
, i.e. an "" or if the
rgroup
is one longer than the n.rgroup
the last n.rgroup
element will
be calculated through nrow(x) - sum(n.rgroup)
in order to make
the table generating smoother.
rgroup
You can now have an additional element at the rgroup
level by specifying the
attr(rgroup, 'add')
. The value can either be a vector
, a list
,
or a matrix
. See vignette("general", package = "htmlTable")
for examples.
A vector
of either equal number of rgroup
s to the number
of rgroup
s that aren't empty, i.e. rgroup[rgroup != ""]
. Or a named vector where
the name must correspond to either an rgroup
or to an rgroup
number.
A list
that has exactly the same requirements as the vector.
In addition to the previous we can also have a list with column numbers within
as names within the list.
A matrix
with the dimension nrow(x) x ncol(x)
or
nrow(x) x 1
where the latter is equivalent to a named vector.
If you have rownames
these will resolve similarly to the names to the
list
/vector
arguments. The same thing applies to colnames
.
This function will only work with knitr outputting HTML, i.e. markdown mode. As the function returns raw HTML-code the compatibility with non-HTML formatting is limited, even with pandoc.
Thanks to the the knitr::knit_print()
and the knitr::asis_output()
the results='asis'
is no longer needed except within for-loops.
If you have a knitr-chunk with a for loop and use print()
to produce
raw HTML you must set the chunk option results='asis'
. Note:
the print-function relies on the base::interactive()
function
for determining if the output should be sent to a browser or to the terminal.
In vignettes and other directly knitted documents you may need to either set
useViewer = FALSE
alternatively set options(htmlTable.cat = TRUE)
.
RStudio has an interactive notebook that allows output directly into the document.
In order for the output to be properly formatted it needs to have the class
of html
. The htmlTable
tries to identify if the environment is a
notebook document (uses the rstudioapi and identifies if its a file with and Rmd
file ending or if there is an element with html_notebook
). If you don't want this
behavior you can remove it using the options(htmlTable.skip_notebook = TRUE)
.
If you set the option table_counter you will get a Table 1,2,3
etc before each table, just set options(table_counter=TRUE)
. If
you set it to a number then that number will correspond to the start of
the table_counter. The table_counter
option will also contain the number
of the last table, this can be useful when referencing it in text. By
setting the option options(table_counter_str = "<b>Table %s:</b> ")
you can manipulate the counter table text that is added prior to the
actual caption. Note, you should use the sprintf()
%s
instead of %d
as the software converts all numbers to characters
for compatibility reasons. If you set options(table_counter_roman = TRUE)
then the table counter will use Roman numerals instead of Arabic.
An empty data frame will result in a warning and output an empty table, provided that
rgroup
and n.rgroup
are not specified. All other row layout options will be ignored.
There are multiple options that can be set, here is a set of the perhaps most used
table_counter
- logical - activates a counter for each table
table_counter_roman
- logical - if true the counter is in Roman numbers, i.e. I, II, III, IV...
table_counter_str
- string - the string used for generating the table counter text
useViewer
- logical - if viewer should be used fro printing the table
htmlTable.cat
- logical - if the output should be directly sent to cat()
htmlTable.skip_notebook
- logical - skips the logic for detecting notebook
htmlTable.pretty_indentation
- logical - there was some issues in previous Pandoc versions
where HTML indentation caused everything to be interpreted as code. This seems to be fixed
and if you want to look at the raw HTML code it is nice to have this set to TRUE
so that
the tags and elements are properly indented.
htmlTableCompat
- string - see parameter description
Copy-pasting: As you copy-paste results into Word you need to keep the original formatting. Either right click and choose that paste option or click on the icon appearing after a paste. Currently the following compatibilities have been tested with MS Word 2016:
Internet Explorer (v. 11.20.10586.0) Works perfectly when copy-pasting into Word
RStudio (v. 0.99.448) Works perfectly when copy-pasting into Word.
Note: can have issues with multi-line cgroup
s -
see bug
Chrome (v. 47.0.2526.106) Works perfectly when copy-pasting into Word.
Note: can have issues with multi-line cgroup
s -
see bug
Firefox (v. 43.0.3) Works poorly - looses font-styling, lines and general feel
Edge (v. 25.10586.0.0) Works poorly - looses lines and general feel
Direct word processor opening: Opening directly in Libre Office or Word is no longer recommended. You get much prettier results using the cut-and-paste option.
Google docs: Copy-paste directly into a Google docs document is handled rather well. This seems to work especially well when the paste comes directly from a Chrome browser.
Note that when using complex cgroup
alignments with multiple levels
not every browser is able to handle this. For instance the RStudio
webkit browser seems to have issues with this and a
bug has been filed.
As the table uses HTML for rendering you need to be aware of that headers,
row names, and cell values should try respect this for optimal display. Browsers
try to compensate and frequently the tables still turn out fine but it is
not advised. Most importantly you should try to use
<
instead of <
and
>
instead of >
. You can find a complete list
of HTML characters here.
Lastly, I want to mention that function was inspired by the Hmisc::latex()
that can be an excellent alternative if you wish to switch to PDF-output.
For the sibling function tidyHtmlTable()
you can directly switch between
the two using the table_fn
argument.
library(magrittr) # Basic example output <- matrix(1:4, ncol=2, dimnames = list(list("Row 1", "Row 2"), list("Column 1", "Column 2"))) htmlTable(output) ############################################ # Below saves all outputs to a list that # # it outputted all at once at the end # # this is mostly for allowing you to view # # and evaluate each example section as # # they would otherwise be overwritten by # # eachother # ############################################ all_tables <- list() htmlTable(output) -> all_tables[["Basic table"]] # An advanced output output <- matrix(ncol=6, nrow=8) for (nr in 1:nrow(output)){ for (nc in 1:ncol(output)){ output[nr, nc] <- paste0(nr, ":", nc) } } output %>% addHtmlTableStyle(align="r", col.columns = c(rep("none", 2), rep("#F5FBFF", 4)), col.rgroup = c("none", "#F7F7F7"), css.cell = "padding-left: .5em; padding-right: .2em;") %>% htmlTable(header = paste(c("1st", "2nd", "3rd", "4th", "5th", "6th"), "hdr"), rnames = paste(c("1st", "2nd", "3rd", paste0(4:8, "th")), "row"), rgroup = paste("Group", LETTERS[1:3]), n.rgroup = c(2,4,nrow(output) - 6), cgroup = rbind(c("", "Column spanners", NA), c("", "Cgroup 1", "Cgroup 2†")), n.cgroup = rbind(c(1,2,NA), c(2,2,2)), caption="Basic table with both column spanners (groups) and row groups", tfoot="† A table footer commment", cspan.rgroup = 2) -> all_tables[["Advanced table"]] # An advanced empty table suppressWarnings({ matrix(ncol = 6, nrow = 0) %>% addHtmlTableStyle(col.columns = c(rep("none", 2), rep("#F5FBFF", 4)), col.rgroup = c("none", "#F7F7F7"), css.cell = "padding-left: .5em; padding-right: .2em;") %>% htmlTable(align="r", header = paste(c("1st", "2nd", "3rd", "4th", "5th", "6th"), "hdr"), cgroup = rbind(c("", "Column spanners", NA), c("", "Cgroup 1", "Cgroup 2†")), n.cgroup = rbind(c(1,2,NA), c(2,2,2)), caption="Basic empty table with column spanners (groups) and ignored row colors", tfoot="† A table footer commment", cspan.rgroup = 2) -> all_tables[["Empty table"]] }) # An example of how to use the css.cell for header styling simple_output <- matrix(1:4, ncol=2) simple_output %>% addHtmlTableStyle(css.cell = rbind(rep("background: lightgrey; font-size: 2em;", times=ncol(simple_output)), matrix("", ncol=ncol(simple_output), nrow=nrow(simple_output)))) %>% htmlTable(header = LETTERS[1:2]) -> all_tables[["Header formatting"]] concatHtmlTables(all_tables) # See vignette("tables", package = "htmlTable") # for more examples
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.