Created
May 19, 2013 23:25
-
-
Save mbacou/5609519 to your computer and use it in GitHub Desktop.
R: htmlTable()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' This is a simple function for outputting a more advanced | |
#' table than xtable allows. It's aim is to provide the Hmisc | |
#' latex() colgroup and rowgroup functions. | |
#' | |
#' @param x The matrix/data.frame with the data | |
#' @param headings a vector of character strings specifying column | |
#' headings, defaulting to \code{x}'s \code{colnames} | |
#' @param align a character strings specifying column alignments, defaulting to | |
#' \code{paste(rep('c',ncol(x)),collapse='')} to center. | |
#' You may specify \code{align='c|c'} and other LaTeX tabular formatting. | |
#' @param halign a character strings specifying alignment for column headings, | |
#' defaulting to centered. | |
#' @param cgroup a vector of character strings defining major column headings. The default | |
#' is to have none. This is also known as "the column spanner". | |
#' @param n.cgroup a vector containing the number of columns for which each element in | |
#' cgroup is a heading. For example, specify \code{cgroup=c("Major 1","Major 2")}, | |
#' \code{n.cgroup=c(3,3)} if \code{"Major 1"} is to span columns 1-3 and | |
#' \code{"Major 2"} is to span columns 4-6. | |
#' \code{rowlabel} does not count in the column numbers. You can omit \code{n.cgroup} | |
#' if all groups have the same number of columns. | |
#' @param cgroup.just | |
#' @param rgroup a vector of character strings containing headings for row groups. | |
#' \code{n.rgroup} must be present when \code{rgroup} is given. The first | |
#' \code{n.rgroup[1]}rows are sectioned off and \code{rgroup[1]} is used as a bold | |
#' heading for them. The usual row dimnames (which must be present if \code{rgroup} is) | |
#' are indented. The next \code{n.rgroup[2]} rows are treated likewise, etc. | |
#' @param n.rgroup integer vector giving the number of rows in each grouping. If \code{rgroup} | |
#' is not specified, \code{n.rgroup} is just used to divide off blocks of rows by horizontal | |
#' lines. If \code{rgroup} is given but \code{n.rgroup} is omitted, \code{n.rgroup} will | |
#' default so that each row group contains the same number of rows. | |
#' @param 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. | |
#' @param rowname Default is rownames of matrix or data.frame. Specify \code{rowname=NULL} | |
#' to suppress the use of row names. | |
#' @param 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. | |
#' @param caption.loc set to \code{"bottom"} to position a caption below the table | |
#' instead of the default of \code{"top"}. | |
#' @param label a text string representing a symbolic label for the | |
#' table for referencing as an anchor | |
#' @param ctable If the table should have a double top border or a single a' la LaTeX ctable style | |
#' @param ... | |
#' @param output Set to false if you don't want an immediate print | |
#' @return Returns a string with the output table if output is not set | |
#' | |
#' @example examples/htmlTable_example.R | |
#' @author max | |
#' @export | |
htmlTable <- function(x, | |
title=first.word(deparse(substitute(x))), | |
headings=colnames(x), | |
align =paste(rep('c',ncol(x)),collapse=''), | |
halign=paste(rep('c',ncol(x)),collapse=''), | |
cgroup=NULL, n.cgroup=NULL, | |
cgroup.just=rep("c",length(n.cgroup)), | |
rgroup=NULL, n.rgroup=NULL, | |
rowlabel=title, | |
ctable=FALSE, | |
rowname=rownames(x), | |
caption=NULL, | |
caption.loc='top', | |
label=title, | |
output = TRUE, | |
...) | |
{ | |
if (ctable) | |
table_str <- "<table class='gmisc_table' style='border-top: 2px solid grey; border-bottom: 2px solid grey;'>" | |
else | |
table_str <- "<table class='gmisc_table' style='border-top: 4px double grey; border-bottom: 1px solid grey;'>" | |
if (length(label) > 0){ | |
table_str <- sprintf("%s\n\t<a name='%s'></a>", table_str, label) | |
} | |
# Not quite as intended but close enough | |
if(length(list(...))) x <- format.df(x, numeric.dollar=FALSE, ...) | |
# Remove some specifics for LaTeX | |
if (is.character(x)) | |
x <- matrix(str_replace(x, "\\\\%", "%"), ncol=ncol(x)) | |
if (length(caption) > 0){ | |
if (caption.loc == "bottom"){ | |
table_str <- sprintf("%s\n\t<caption align=bottom>", table_str) | |
}else{ | |
table_str <- sprintf("%s\n\t<caption align=top>", table_str) | |
} | |
table_str <- sprintf("%s%s</caption>", table_str, caption) | |
} | |
if (length(rowname) > 0) | |
set_rownames <- TRUE | |
else | |
set_rownames <- FALSE | |
# Add the cgroup table header | |
if (length(cgroup) > 0){ | |
if (length(n.cgroup) == 0 && ncol(x) %% length(cgroup) == 0){ | |
n.cgroup <- rep(ncol(x)/length(cgroup), times=length(cgroup)) | |
}else if(sum(n.cgroup) != ncol(x)){ | |
stop(sprintf("Your columns don't match in the n.cgroup, i.e. %d != %d", sum(n.cgroup), ncol(x))) | |
} | |
table_str <- sprintf("%s\n\t<tr>", table_str) | |
if (set_rownames && length(rowlabel) > 0){ | |
table_str <- sprintf("%s\n\t\t<th style='font-weight: 900;'>%s</th>", table_str, rowlabel) | |
} | |
for (i in 1:length(cgroup)){ | |
table_str <- sprintf("%s\n\t\t<th colspan=%d style='font-weight: 900; border-bottom: 1px solid grey;'>%s</th>", table_str, n.cgroup[i], cgroup[i]) | |
if (i != length(cgroup)) | |
table_str <- sprintf("%s<th> </th>", table_str) | |
} | |
table_str <- sprintf("%s\n\t</tr>", table_str) | |
} | |
addCells <- function(table_str, rowcells, cellcode, align){ | |
cgroup_iterator <- 0 | |
for (nr in 1:length(rowcells)){ | |
if (length(cgroup) > 0){ | |
if (cgroup_iterator > 0){ | |
if (sum(n.cgroup[1:cgroup_iterator]) < nr ){ | |
table_str <- sprintf("%s\n\t\t<%s> </%s>", table_str, cellcode, cellcode) | |
cgroup_iterator = cgroup_iterator + 1 | |
} | |
}else{ | |
cgroup_iterator = cgroup_iterator + 1 | |
} | |
} | |
table_str <- sprintf("%s\n\t\t<%s align='%s'>%s</%s>", table_str, cellcode, align, rowcells[nr], cellcode) | |
} | |
return (table_str) | |
} | |
# Add the headings | |
if (length(headings) > 0){ | |
table_str <- sprintf("%s\n\t<tr style='border-bottom: 1px solid grey;'>", table_str) | |
if (set_rownames && length(cgroup) == 0 && length(rowlabel) > 0){ | |
table_str <- sprintf("%s\n\t\t<th style='font-weight: 900;'>%s</th>", table_str, rowlabel) | |
}else if(set_rownames){ | |
table_str <- sprintf("%s\n\t\t<th> </th>", table_str) | |
} | |
table_str <- addCells(table_str = table_str, rowcells = headings, cellcode = "th", align="center") | |
table_str <- sprintf("%s\n\t</tr>", table_str) | |
} | |
if (length(rgroup) > 0 && | |
sum(n.rgroup) != nrow(x)) | |
stop(sprintf("Your rows don't match in the n.rgroup, i.e. %d != %d", sum(n.rgroup), nrow(x))) | |
rgroup_iterator <- 0 | |
for (row_nr in 1:nrow(x)){ | |
if (length(rgroup) > 0){ | |
if (rgroup_iterator == 0){ | |
rgroup_iterator = rgroup_iterator + 1 | |
table_str <- sprintf("%s\n\t<tr><td colspan=%d style='font-weight: 900'>%s</tr>", table_str, | |
ncol(x)+set_rownames, rgroup[rgroup_iterator]) | |
}else if(row_nr > sum(n.rgroup[1:rgroup_iterator])){ | |
rgroup_iterator = rgroup_iterator + 1 | |
table_str <- sprintf("%s\n\t<tr><td colspan=%d style='font-weight: 900; border-top: 1px solid grey;'>%s</tr>", table_str, | |
ncol(x)+set_rownames, rgroup[rgroup_iterator]) | |
} | |
} | |
table_str <- sprintf("%s\n\t<tr>", table_str) | |
if (set_rownames){ | |
if (rgroup_iterator > 0) | |
table_str <- sprintf("%s\n\t\t<td style='padding-left: .5em;'>%s</td>", table_str, rowname[row_nr]) | |
else | |
table_str <- sprintf("%s\n\t\t<td>%s</td>", table_str, rowname[row_nr]) | |
} | |
table_str <- addCells(table_str = table_str, rowcells = x[row_nr,], cellcode = "td", align="right") | |
table_str <- sprintf("%s\n\t</tr>", table_str) | |
} | |
table_str <- sprintf("%s\n</table>", table_str) | |
if (output){ | |
cat(table_str) | |
}else{ | |
return(table_str) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment