15

Is it possible to apply a class attribute to individual table cells using knitr? I have successfully applied a class attribute to the section heading that contains a knitr::kable generated table and used that to format the entire table. However, I would like to be able to conditionally format individual cells which would require being able to apply a class to specific <td> elements.

My current workaround is to programmatically wrap the cell contents in a pair of <span> tags and pass that on to knitr::kable. This approach only allows me to format the text inside the cell versus the entire cell (e.g. setting the cell background color). Here's an example of what I'm currently using:

## Read in the report, process the data, send to kable
rpt <- generate.report()
mutate(rpt, Col2 = ifelse(abs(Col2) > Threshold,
                          paste('<span class="warning">',
                                sprintf("%.2f", Col2), '</span>'),
                          sprintf("%.2f", Col2))) %>%
  knitr::kable(format="markdown", align = c("l", rep("r", 4)),
               col.names = gsub("\\.", "<br>", colnames(.)))

Which results in the following example HTML output:

<td align="right"><span class="warning"> -1.74 </span></td>

I would like to be able to have knitr::kable generate something like this:

<td align="right" class="warning"> -1.74 </td>

That way I could apply css styles to the <td> tag vice the <span> tag.

  • If bold/italic styles are enough for your use case, then `pander` offers a rather user-friendly solution for this: http://rapporter.github.io/pander/#highlighting-cells And of course you could tweak how strong/italics look like with JS/CSS, so the above mentioned limitation simply means that you can have only two extra styles in a table. Please let me know if it helps (by mentioning me in the comment, like @daroczig for an e-mail notification), and I can come up with a reproducible example. – daroczig Dec 30 '14 at 12:49
  • @daroczig Thanks for the idea. Unfortunately, while your suggestion produces a nice markdown output, as you clearly state, it only allows for strong/italics. I'm looking for a solution that enables greater flexibility in applying unique styles to individual cells. – Daddy the Runner Dec 30 '14 at 13:59
  • One idea I've thought about is to write an R function that will post-process the `knitr::kable` generated HTML output to find the `` tags and remove them and edit the parent `` tags. But if I don't have to go through that complexity, I would like to use an existing solution if one is available. – Daddy the Runner Dec 30 '14 at 14:02

2 Answers2

7

package ReporteRs may help. Have a look here FlexTable.

You can then get the corresponding HTML code with function as.html and reuse it within your knitr code.

David Gohel
  • 9,180
  • 2
  • 16
  • 34
  • 1
    I took a look at FlexTable and I agree it provides a lot of nice enhancements over kable and a lot of customization. Unfortunately FlexTable applies all of the formatting using embeded style attributes. This precludes using css stylesheets. (Unless I'm missing something from the ReporteRs package.) Is there any way to apply class attributes instead of style attributes using FlexTable? Or is that a feature request I should submit via GitHub? – Daddy the Runner Dec 31 '14 at 05:14
  • Unfortunately it is not possible to apply css class attributes. – David Gohel Dec 31 '14 at 09:58
  • the flextable link is https://cran.r-project.org/web/packages/flextable/index.html – N Brouwer Jun 12 '18 at 20:06
0

Ok, this may not be the answer but it may point you in the right direction. I had a similar problem formatting individual cells in knitr to prepare a pdf. In the end, I use xtable and wrote a function that relied on a logical matrix to decide whether or not a cell in the output table would be formatted.

I couldn't quite get it to work smoothly by myself so I had to post it on here and with the help of ivyleavedtoadflax I was able to develop a reasonably easy to use function to apply formatting to certain cells in an xtable in knitr.

Here's the link to my post

As I say, it's not the exact solution to your problem but it may point you in the right direction.

Community
  • 1
  • 1
Matt
  • 541
  • 1
  • 4
  • 8
  • The issue with the xtable package, as well as with the ReporteRs' Flextable is that the default table format isn't nice and requires a lot of work from the user side, especially when a lot of tables are used in a report. The point of my bounty is to find a solution that allows cell level formatting without losing the advantages of the kable() function. – Jon Nagra May 27 '15 at 07:40