s_scolary
s_scolary

Reputation: 1399

Change table header colour using htmlTable

I've been having some issues with changing the thead background colour using the htmlTable package in R. By playing around with the css.cell options I was able to change the colour of part of the table header but not all (run code snippet).

require(htmlTable)
mat <- matrix(1:20, ncol=5)

htmlTable(mat,cgroup = c("","Rank",""),n.cgroup = c(1,3,1),
      header = LETTERS[1:5],
      css.cell = rbind(rep("background: lightgrey;", 
                           times=ncol(mat)),
                       matrix("", ncol=ncol(mat), nrow=nrow(mat))))

# Not Run
# x = htmlTable(mat,cgroup = c("","Rank",""),n.cgroup = c(1,3,1),
#               header = LETTERS[1:5],
#               css.cell = rbind(rep("background: lightgrey;", 
#                                times=ncol(mat)),
#                                matrix("", ncol=ncol(mat), nrow=nrow(mat))))
# get the output
# as.character(x)

The output from the code produces the following

<table class='gmisc_table' style='border-collapse: collapse; margin-top: 1em; margin-bottom: 1em;'>\n
  <thead>\n
    <tr>\n
      <th colspan='1' style='font-weight: 900; border-top: 2px solid grey; text-align: center;'></th>
      <th style='border-top: 2px solid grey;; border-bottom: hidden;'>&nbsp;</th>\n
      <th colspan='3' style='font-weight: 900; border-bottom: 1px solid grey; border-top: 2px solid grey; text-align: center;'>Rank</th>
      <th style='border-top: 2px solid grey;; border-bottom: hidden;'>&nbsp;</th>\n
      <th colspan='1' style='font-weight: 900; border-top: 2px solid grey; text-align: center;'></th>\n</tr>\n
    <tr>\n
      <th style='background: lightgrey; border-bottom: 1px solid grey; text-align: center;'>A</th>\n
      <th style='border-bottom: 1px solid grey;' colspan='1'>&nbsp;</th>\n
      <th style='background: lightgrey; border-bottom: 1px solid grey; text-align: center;'>B</th>\n
      <th style='background: lightgrey; border-bottom: 1px solid grey; text-align: center;'>C</th>\n
      <th style='background: lightgrey; border-bottom: 1px solid grey; text-align: center;'>D</th>\n
      <th style='border-bottom: 1px solid grey;' colspan='1'>&nbsp;</th>\n
      <th style='background: lightgrey; border-bottom: 1px solid grey; text-align: center;'>E</th>\n</tr>\n</thead>\n
  <tbody>\n
    <tr>\n
      <td style='text-align: center;'>1</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>5</td>\n
      <td style='text-align: center;'>9</td>\n
      <td style='text-align: center;'>13</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>17</td>\n</tr>\n
    <tr>\n
      <td style='text-align: center;'>2</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>6</td>\n
      <td style='text-align: center;'>10</td>\n
      <td style='text-align: center;'>14</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>18</td>\n</tr>\n
    <tr>\n
      <td style='text-align: center;'>3</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>7</td>\n
      <td style='text-align: center;'>11</td>\n
      <td style='text-align: center;'>15</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>19</td>\n</tr>\n
    <tr>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>4</td>\n
      <td style='border-bottom: 2px solid grey;' colspan='1'>&nbsp;</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>8</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>12</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>16</td>\n
      <td style='border-bottom: 2px solid grey;' colspan='1'>&nbsp;</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>20</td>\n</tr>\n</tbody>\n</table>

Obviously the "\n" output is annoying, but easily manageable. But does anyone have any ideas on how to control the background colour in the table header directly from R?

I know I can adjust the thead style manually by adding the following to the html output: style="background-color: lightgrey;", but it would be very nice if I could just get the desired output directly from R.

Here is my desired table output, when I manually change the background-color in thead:

<table class='gmisc_table' style='border-collapse: collapse; margin-top: 1em; margin-bottom: 1em;'>\n
  <thead style="background-color: lightgrey;">\n
    <tr>\n
      <th colspan='1' style='font-weight: 900; border-top: 2px solid grey; text-align: center;'></th>
      <th style='border-top: 2px solid grey;; border-bottom: hidden;'>&nbsp;</th>\n
      <th colspan='3' style='font-weight: 900; border-bottom: 1px solid grey; border-top: 2px solid grey; text-align: center;'>Rank</th>
      <th style='border-top: 2px solid grey;; border-bottom: hidden;'>&nbsp;</th>\n
      <th colspan='1' style='font-weight: 900; border-top: 2px solid grey; text-align: center;'></th>\n</tr>\n
    <tr>\n
      <th style='border-bottom: 1px solid grey; text-align: center;'>A</th>\n
      <th style='border-bottom: 1px solid grey;' colspan='1'>&nbsp;</th>\n
      <th style='border-bottom: 1px solid grey; text-align: center;'>B</th>\n
      <th style='border-bottom: 1px solid grey; text-align: center;'>C</th>\n
      <th style='border-bottom: 1px solid grey; text-align: center;'>D</th>\n
      <th style='border-bottom: 1px solid grey;' colspan='1'>&nbsp;</th>\n
      <th style='border-bottom: 1px solid grey; text-align: center;'>E</th>\n</tr>\n</thead>\n
  <tbody>\n
    <tr>\n
      <td style='text-align: center;'>1</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>5</td>\n
      <td style='text-align: center;'>9</td>\n
      <td style='text-align: center;'>13</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>17</td>\n</tr>\n
    <tr>\n
      <td style='text-align: center;'>2</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>6</td>\n
      <td style='text-align: center;'>10</td>\n
      <td style='text-align: center;'>14</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>18</td>\n</tr>\n
    <tr>\n
      <td style='text-align: center;'>3</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>7</td>\n
      <td style='text-align: center;'>11</td>\n
      <td style='text-align: center;'>15</td>\n
      <td style='' colspan='1'>&nbsp;</td>\n
      <td style='text-align: center;'>19</td>\n</tr>\n
    <tr>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>4</td>\n
      <td style='border-bottom: 2px solid grey;' colspan='1'>&nbsp;</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>8</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>12</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>16</td>\n
      <td style='border-bottom: 2px solid grey;' colspan='1'>&nbsp;</td>\n
      <td style='border-bottom: 2px solid grey; text-align: center;'>20</td>\n</tr>\n</tbody>\n</table>

Added bonus, if anyone knows how to get rid of the "\n" output that would also be very helpful

Upvotes: 2

Views: 2070

Answers (2)

LyzandeR
LyzandeR

Reputation: 37879

You might want to consider tableHTML for this one, because it adds full control over CSS. tableHTML uses the pipe operator to chain commands.

Using your data:

library(tableHTML)
mat %>%
 as.data.frame() %>%
 #tableHTML is the main function that creates the html table
 tableHTML(border = 0, rownames = FALSE, 
           second_header = list(c(1, 3, 1), c('', 'Rank', ''))) %>%
 #the add_css family of functions add CSS to the corresponding
 #parts of the table
 add_css_thead(list(c('background-color'), c('lightgrey'))) %>%
 add_css_table(list(c('text-align'), c('center'))) %>%
 add_css_row(css = list('border-top', '2px solid black'), rows = 1) %>%
 add_css_row(css = list('border-bottom', '1px solid black'), rows = 2) %>%
 add_css_row(css = list('border-bottom', '2px solid black'), rows = 6) %>%
 add_css_second_header(css = list('border-bottom', '1px solid black'), second_headers = 2)

Which would result in the table you want, but without needing to use a hack to modify tablehtml or any other package (or needing to manually deal with the /ns):

enter image description here

You can still modify it further if you wish. There is also an online tutorial here if you are interested.

Upvotes: 2

Chris Conlan
Chris Conlan

Reputation: 2962

I am not very familiar with htmlTable in R, but here is an overkill solution using the XML package to manipulate the output of htmlTable.

require(htmlTable)
mat <- matrix(1:20, ncol=5)

tab <- htmlTable(mat,cgroup = c("","Rank",""),n.cgroup = c(1,3,1),
      header = LETTERS[1:5],
      css.cell = rbind(rep("background: lightgrey;", 
                           times=ncol(mat)),
                       matrix("", ncol=ncol(mat), nrow=nrow(mat))))


library(XML)

# Parse the HTML table and add the background color attribute
doc <- htmlParse(tab)
addAttributes(doc[['//thead']], 'style' = "background-color: lightgrey;")

# Convert HTML DOM object to string
html_str <- toString.XMLNode(doc)

# Remove line escapes, as requested
html_str <- gsub('\\\n', '', html_str)

# Remove the DOCTYPE included by htmlParse()
html_str <- gsub('<!DOCTYPE[^>]*>', '', html_str)

cat(html_str)

It outputs an HTML string that creates the desired table:

<html><body><table class="gmisc_table" style="border-collapse: collapse; margin-top: 1em; margin-bottom: 1em;"><thead style="background-color: lightgrey;"><tr><th colspan="1" style="font-weight: 900; border-top: 2px solid grey; text-align: center;"></th><th style="border-top: 2px solid grey;; border-bottom: hidden;"> </th><th colspan="3" style="font-weight: 900; border-bottom: 1px solid grey; border-top: 2px solid grey; text-align: center;">Rank</th><th style="border-top: 2px solid grey;; border-bottom: hidden;"> </th><th colspan="1" style="font-weight: 900; border-top: 2px solid grey; text-align: center;"></th></tr><tr><th style="background: lightgrey; border-bottom: 1px solid grey; text-align: center;">A</th><th style="border-bottom: 1px solid grey;" colspan="1"> </th><th style="background: lightgrey; border-bottom: 1px solid grey; text-align: center;">B</th><th style="background: lightgrey; border-bottom: 1px solid grey; text-align: center;">C</th><th style="background: lightgrey; border-bottom: 1px solid grey; text-align: center;">D</th><th style="border-bottom: 1px solid grey;" colspan="1"> </th><th style="background: lightgrey; border-bottom: 1px solid grey; text-align: center;">E</th></tr></thead><tbody><tr><td style="text-align: center;">1</td><td style="" colspan="1"> </td><td style="text-align: center;">5</td><td style="text-align: center;">9</td><td style="text-align: center;">13</td><td style="" colspan="1"> </td><td style="text-align: center;">17</td></tr><tr><td style="text-align: center;">2</td><td style="" colspan="1"> </td><td style="text-align: center;">6</td><td style="text-align: center;">10</td><td style="text-align: center;">14</td><td style="" colspan="1"> </td><td style="text-align: center;">18</td></tr><tr><td style="text-align: center;">3</td><td style="" colspan="1"> </td><td style="text-align: center;">7</td><td style="text-align: center;">11</td><td style="text-align: center;">15</td><td style="" colspan="1"> </td><td style="text-align: center;">19</td></tr><tr><td style="border-bottom: 2px solid grey; text-align: center;">4</td><td style="border-bottom: 2px solid grey;" colspan="1"> </td><td style="border-bottom: 2px solid grey; text-align: center;">8</td><td style="border-bottom: 2px solid grey; text-align: center;">12</td><td style="border-bottom: 2px solid grey; text-align: center;">16</td><td style="border-bottom: 2px solid grey;" colspan="1"> </td><td style="border-bottom: 2px solid grey; text-align: center;">20</td></tr></tbody></table></body></html>

Upvotes: 1

Related Questions