htmlTable: Outputting HTML tables

Description Usage Arguments Value Important knitr-note Table counter Possible issues See Also Examples

View source: R/htmlTable.R

Description

This is a function for outputting a more advanced table than xtable allows. It's aim is to provide the Hmisc latex() colgroup and rowgroup functions in HTML. The code outputted is perhaps a little raw compared to fully CSS formatted HTML. The reason for this is that I've chosen maximum compatibility with LibreOffice/OpenOffice that lacks any more advanced understanding of HTML & CSS.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
htmlTable(x, title = first.word(deparse(substitute(x))), headings,
  align = paste(c("l", rep("c", ncol(x) - 1)), collapse = ""),
  halign = paste(rep("c", ncol(x)), collapse = ""), cgroup, n.cgroup,
  cgroup.just, rgroup, n.rgroup, rgroupCSSstyle = "font-weight: 900;",
  rgroupCSSseparator = "", tspanner, n.tspanner,
  tspannerCSSstyle = "font-weight: 900; text-transform:capitalize; text-align: center;",
  tspannerCSSseparator = "border-top: 1px solid grey;", rowlabel = title,
  rowlabel.pos = "bottom", ctable = FALSE, compatibility = "LibreOffice",
  rowname, caption, caption.loc = "top", tfoot, label, altcol = "white",
  tableCSSclass = "gmisc_table", ...)

## S3 method for class 'htmlTable'
print(x, useViewer, ...)

Arguments

x

The matrix/data.frame with the data

title

The title of the table. Used for labeling etc.

headings

a vector of character strings specifying column headings, defaulting to x's colnames

align

a character strings specifying column alignments, defaulting to paste(c("l", rep('c',ncol(n_table)-1)),collapse='') to center. Valid alignments are l = left, c = center and r = right. You can also specify align='c|c' and other LaTeX tabular formatting.

halign

a character strings specifying alignment for column headings, defaulting to centered.

cgroup

a vector or a matrix of character strings defining major column headings. The default is to have none. This is also known as "the column spanner". If you want a column not to have a spanner then put that column as "". If you pass cgroup and n.crgroup as matrices you can have multiline cgroups. If the different levels have different number of elements you need to set the ones that lack elements to NA. For instance cgroup = rbind(c("first", "second", NA), c("a", "b", "c")).

n.cgroup

a vector or matrix containing the number of columns for which each element in cgroup is a heading. For example, specify cgroup=c("Major 1","Major 2"), n.cgroup=c(3,3) if "Major 1" is to span columns 1-3 and "Major 2" is to span columns 4-6. rowlabel does not count in the column numbers. You can omit n.cgroup if all groups have the same number of columns.

cgroup.just

The justification of the c.groups

rgroup

A vector of character strings containing headings for row groups. n.rgroup must be present when rgroup is given. The first n.rgroup[1]rows are sectioned off and rgroup[1] is used as a bold heading for them. The usual row dimnames (which must be present if rgroup is) are indented. The next n.rgroup[2] rows are treated likewise, etc. If you don't want a row to be part of a row group then you just put "" for that row, remember to add the corresponding number of rows in n.rgroup.

n.rgroup

integer vector giving the number of rows in each grouping. If rgroup is not specified, n.rgroup is just used to divide off blocks of rows by horizontal lines. If rgroup is given but n.rgroup is omitted, n.rgroup will default so that each row group contains the same number of rows.

rgroupCSSstyle

CSS style for the rgorup, if different styles are wanted for each of the rgroups you can just specify a vector with the number of elements

rgroupCSSseparator

The line between different rgroups. The line is set to the TR element of the lower rgroup, i.e. you have to set the border-top/padding-top etc to a line with the expected function. This is only used for rgroups that are printed. You can specify different separators if you give a vector of rgroup - 1 length (this is since the first rgroup doesn't have a separator).

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

The number of rows in the original matrix that the table spanner should span

tspannerCSSstyle

The CSS style for the table spanner

tspannerCSSseparator

The line between different spanners

rowlabel

If x has row dimnames, rowlabel is a character string containing the column heading for the row dimnames. The default is the name of the argument for x.

rowlabel.pos

Where the rowlabel should be positioned. This value can be "top", "bottom", "header", or a integer between 1 and nrow(cgroup) + 1. The options "bottom", "header" are the same, where the row label is presented at the same level as the header.

ctable

If the table should have a double top border or a single a' la LaTeX ctable style

compatibility

Is default set to LibreOffice as some settings need to be in old html format as Libre Office can't handle some commands such as the css caption-alignment. Note: this option is not yet fully implemented for all details, in the future I aim to generate a html-correct table and one that is aimed at Libre Office compatibility. Word-compatibility is difficult as Word ignores most settings and destroys all layout attempts (at least that is how my 2010 version behaves).

rowname

Default is rownames of matrix or data.frame.

caption

a text string to use as a caption to print at the top of the first page of the table. Default is no caption.

caption.loc

set to "bottom" to position a caption below the table instead of the default of "top".

tfoot

Add a table footer if needed at the bottom of the table using the <tfoot> html element.

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 <a href="#anchor_name">see table 2</a>

altcol

alternating colors for each rgroup; one or two colors is recommended and will be recycled (will throw warning if the number of rgroups is not a multiple of length(altcol)). Note that the altcol currently only works when copy-pasting from the browser and not when opening directly in LibreOffice.

tableCSSclass

The html CSS class for the table. This allows directing html formatting through CSS directly at all instances of that class. Note: unfortunately the CSS is frequently ignored by word processors. This option is mostly inteded for web-presentations.

...

Passed on to print.htmlTable function and any argument except the useViewer will be passed on to the cat function.

useViewer

If you are using RStudio there is a viewer thar can render the table within that is envoced if in interactive mode. Set this to FALSE if you want to remove that functionality.

Value

string Returns a string of class htmlTable

Important knitr-note

This funciton will only work with knitr outputting html, i.e. markdown mode. For each section where you want a table to be outputted you need to specify: results="asis". As the function returns raw html-code the compatibility with non-html formatting is limited, even with pandoc.

Table counter

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 numumerals instead of Arabic.

Possible issues

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.

If you in your knitr html-document get a "structure" noted under the rowlabel heading then this is an effect from the automated rowlabel name. It is copied from the title that in turn uses the

x to find an apropriate name: title=first.word(deparse(substitute(x))). All you need to do is simply set either the title or the rowlabel arguments to get rid of this "bug".

As the table uses html for rendering you need to be aware of that headers, rownames, and cell values should try respect this for optimal display. Browsers try to compensate and frequently the tables still turn out OK but it is not advized. Most importantly you should try to use &lt; instead of < and &gt; instead of >. You can find a complete list of html characters here.

See Also

latex, getDescriptionStatsBy, splitLines4Table

Examples

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# A simple example
# note that this won't show due to the second example
mx <- matrix(1:6, ncol=3)
rownames(mx) <- LETTERS[1:NROW(mx)]
colnames(mx) <- sprintf("Col %s", LETTERS[1:NCOL(mx)])

# If you just want to output your matrix, this is all you need
# We also force the output to be printed to std_out instead of th
# graphical viewer
htmlTable(mx, useViewer=FALSE)

# Now add more interesting options
htmlTable(mx,
          n.rgroup=c(2), rgroup=c("Nice!"),
          n.cgroup=c(2,1), cgroup=c("First", "Second"))


# A slightly more advanced example
data(mtcars)

label(mtcars$mpg) <- "Gas"
units(mtcars$mpg) <- "Miles/(US) gallon"

label(mtcars$wt) <- "Weight"
units(mtcars$wt) <- "10^3 kg" # not sure the unit is correct

mtcars$am <- factor(mtcars$am, levels=0:1, labels=c("Automatic", "Manual"))
label(mtcars$am) <- "Transmission"

mtcars$gear <- factor(mtcars$gear)
label(mtcars$gear) <- "Gears"

# Make up some data for making it slightly more interesting
mtcars$col <- factor(sample(c("red", "black", "silver"),
                            size=NROW(mtcars), replace=TRUE))
label(mtcars$col) <- "Car color"

mpg_data_mean <- getDescriptionStatsBy(mtcars$mpg, mtcars$am,
                                       use_units = TRUE, html=TRUE)
mpg_data_median <- getDescriptionStatsBy(mtcars$mpg, mtcars$am,
                                         use_units = TRUE, html=TRUE,
                                         continuous_fn=describeMedian)
wt_data <- getDescriptionStatsBy(mtcars$wt, mtcars$am,
                                 use_units = TRUE, html=TRUE)

vars <- rbind(mpg_data_mean, mpg_data_median, wt_data)
rownames(vars) <- c("Mean (SD)", "Median (IQR)", "Mean (SD)")
htmlTable(
  vars,
  caption  = "Continuous & binary variables",
  n.rgroup = c(2,1), rgroup=c("Gas", "Weight"),
  n.cgroup = c(2,1),
  cgroup   = c(splitLines4Table("Results",
                                sprintf("n=%d", NROW(mtcars)), html=TRUE),
               ""),
  headings =c(sprintf("%s (SD)", levels(mtcars$am)), "Units"),
  rowlabel = "Variable",
  ctable   = TRUE)

## again with altcol
htmlTable(
  vars,
  caption  = "Continuous & binary variables",
  n.rgroup = c(2,1), rgroup=c("Gas", "Weight"),
  n.cgroup = c(2,1),
  cgroup   = c(splitLines4Table("Results",
                                sprintf("n=%d", NROW(mtcars)), html=TRUE),
               ""),
  headings =c(sprintf("%s (SD)", levels(mtcars$am)), "Units"),
  rowlabel = "Variable",
  ctable   = TRUE,
  altcol   = c('#f2f2f2','ivory'))


## another example
describeMedian_minmax <- function(...) describeMedian(..., iqr = FALSE)

## t1 wrapper function 1
getT1stat <- function(varname, digits = 0) {
  getDescriptionStatsBy(data[ , varname],
                        data$treat,
                        add_total_col = TRUE,
                        show_all_values = TRUE,
                        hrzl_prop = FALSE,
                        statistics = FALSE,
                        html = TRUE,
                        digits = digits,
                        continuous_fn = describeMedian_minmax)
}

set.seed(1)
f <- function(...) sample(..., 100, replace = TRUE)
data <- data.frame(age = rpois(100, 50),
                   cat_var = f(LETTERS[1:5]),
                   sex = f(c('Male','Female')),
                   race = f(c('Black','White','Asian')),
                   treat = factor(f(1:3),
                                  # The factor helps arranging the order
                                  labels=c('Treatment A', 'Treatment B', 'Placebo')))

## table 1 stats
table_data <- list()
table_data[['Age']] <- getT1stat('age')
table_data[['Some categorical<br />&nbsp;&nbsp;variable']] <- getT1stat('cat_var')
table_data[['Sex']] <- getT1stat('sex')
table_data[['Race']] <- getT1stat('race')

## combine into matrix
output_data <- do.call(rbind, table_data)
rgroup <- names(table_data)
n.rgroup <- unname(sapply(rgroup, function(x) nrow(table_data[[x]])))

# add a column spanner for the status columns
cgroup <- c("", "Type of treatment<sup>&dagger;</sup>")
n.cgroup <- c(1, 3)
colnames(output_data) <-
  c(paste0('Total<br />\n',
           '<span style="weight = normal; font-size: .6em;">',
            'n = ', nrow(data),
           '</span>'),
    paste0('Treated A<br />\n',
           '<span style="weight = normal; font-size: .6em;">',
            'n = ', sum(data$treat == 'Treatment A'),
           '</span>'),
    paste0('Treatment B&Dagger;<br />\n',
           '<span style="weight = normal; font-size: .6em;">',
            'n = ', sum(data$treat == 'Treatment B'),
           '</span>'),
    paste0('Placebo<br />',
           '<span style="weight = normal; font-size: .6em;">',
            'n = ', sum(data$treat == 'Placebo'),
           '</span>'))


htmlTable(output_data, align = 'rccc',
          rgroup = rgroup, n.rgroup = n.rgroup,
          rgroupCSSseparator = '',
          cgroup = cgroup,
          n.cgroup = n.cgroup,
          tspanner=c("Base", "Other"),
          n.tspanner=c(sum(sapply(table_data, nrow)[1:2]),
                       sum(sapply(table_data, nrow)[3:4])),
          rowlabel = '',
          ctable = TRUE, # latex-style table lines
          caption = "Table 1: Patient demographics",
          altcol = c('white','lightblue1'),
          tfoot = paste0(
            '<span style="font-size: .6em;">',
              'Abbreviations:',
              ' ECOG, Eastern Cooperative Oncology Group;',
              ' PS, performance score',
            '</span><br />\n',
            '<span style="font-size: .6em;">',
              '<sup>&dagger;</sup>',
              ' Note 1. Trial groups for a new wonder drug</span><br />\n',
            '<span style="font-size: .6em;">',
              '<sup>&Dagger;</sup>',
              ' Note 2. Twice the dosage of treatment A',
            '</span>'))

raredd/Gmisc0 documentation built on May 27, 2019, 2:02 a.m.