Loosely speaking, the question is: How to use formattable
(or in general: a function that generates markdown/HTML output) in a RNW document?
Background
At first, I thougt the approach I suggested in this answer could be applied. It allows to embed markdown markup in a RNW document. But as it turned out, formattable
produces a mix of markdown and HTML output – in this case, that approach won't work.
About 3 weeks ago, fdetsch posted a nice answer that shows how to embed leaflet
(or in general: htmlWidget
s) in RNW documents. This answer builds on and extends fdetsch's solution.
The solution (raw)
Install the webshot
library from GitHub and, if necessary, devtools
and htmlwidgets
.
devtools::install_github("wch/webshot")
- Save the return value of
formattable
in an object (I used mytable
).
- Convert
mytable
to an htmlWidget
: as.htmlwidget(mytable)
Save the widget to a temporary HTML file (should be in current working directory, see below):
tmpHTML <- basename(tempfile(fileext = ".html"))
saveWidget(as.htmlwidget(mytable), file = tmpHTML)
Take a "screenshot" of the HTML file. For some reason, webshot
produces empty image files when passing in a path instead of a filename.
myImage <- "image.pdf"
webshot(tmpHTML, file = myImage, cliprect = "viewport")
Add the figure to the document:
knitr::include_graphics(myImage)
Issues and improvements
- Issue 1: The image is too large for the widget. This should be solveable by passing
selector = "#htmlwidget_container"
instead of cliprect = "viewport"
to webshot
, but this didn't work in my tests. Alternatively, plot_crop(myImage, quiet = TRUE)
can be added right after webshot
to use knitr
's cropping mechanism.
- Issue 2: For some reason, the produced PDF is in black and white. When saving the screenshot as PNG, color will be preserved:
myImage <- "image.png"
. However, the fonts will be blurry and I didn't find a way to increase the resolution (the webshot
argument vwidth
doesn't help). Therefore, I would say it is a trade-off: You can either have non-blurry fonts (PDF), or colors (PNG).
- Issue 3: Messy temporary files. You can add
unlink(tmpHTML)
if you like.
Full example
\documentclass{article}
\begin{document}
<<>>=
library(htmlwidgets)
library(webshot)
library(formattable)
# Data from the question
df <- data.frame(
Typ = c("Winners", "", "Losers", ""),
Time = c("1.", "2.", "1.", "2."),
Value = percent(c(0.22, 0.18, 0.78, 0.82)),
Change = percent(c(NA, -0.04, NA, 0.04))
)
mytable <- formattable(df, list(Change = formatter(
"span",
style = x ~ style(color = ifelse(x < 0 , "red", "green")),
x ~ icontext(ifelse(x < 0, "arrow-down", "arrow-up"), x)
)))
tmpHTML <- basename(tempfile(fileext = ".html"))
saveWidget(as.htmlwidget(mytable), file = tmpHTML)
myImage <- "image.pdf"
webshot(tmpHTML, file = myImage, cliprect = "viewport")
plot_crop(myImage, quiet = TRUE)
knitr::include_graphics(myImage)
unlink(tmpHTML)
@
\end{document}