粗略地说,问题是:如何formattable
在 RNW 文档中使用(或一般而言:生成 markdown/HTML 输出的函数)?
背景
起初,我认为可以应用我在此答案中建议的方法。它允许在 RNW 文档中嵌入 markdown 标记。但事实证明,它formattable
会产生 Markdown 和 HTML 输出的混合——在这种情况下,这种方法是行不通的。
大约 3 周前,fdetsch 发布了一个很好的答案,展示了如何在 RNW 文档中嵌入leaflet
(或一般而言: s)。htmlWidget
这个答案建立在并扩展了 fdetsch 的解决方案。
解决方案(原始)
从 GitHub安装webshot
库,如有必要,devtools
安装htmlwidgets
.
devtools::install_github("wch/webshot")
- 将返回值保存
formattable
在一个对象中(我用过mytable
)。
- 转换
mytable
为htmlWidget
:as.htmlwidget(mytable)
将小部件保存到临时 HTML 文件中(应该在当前工作目录中,见下文):
tmpHTML <- basename(tempfile(fileext = ".html"))
saveWidget(as.htmlwidget(mytable), file = tmpHTML)
拍摄 HTML 文件的“屏幕截图”。出于某种原因,webshot
在传递路径而不是文件名时会生成空图像文件。
myImage <- "image.pdf"
webshot(tmpHTML, file = myImage, cliprect = "viewport")
将图添加到文档中:
knitr::include_graphics(myImage)
问题和改进
- 问题 1:图像对于小部件来说太大。这应该可以通过传递
selector = "#htmlwidget_container"
而不是cliprect = "viewport"
to 来解决webshot
,但这在我的测试中不起作用。或者,plot_crop(myImage, quiet = TRUE)
可以在webshot
使用knitr
' 裁剪机制之后立即添加。
- 问题 2:由于某种原因,生成的 PDF 是黑白的。将屏幕截图保存为 PNG 时,将保留颜色:
myImage <- "image.png"
. 但是,字体会很模糊,我没有找到提高分辨率的方法(这个webshot
参数vwidth
没有帮助)。因此,我会说这是一种权衡:您可以使用非模糊字体 (PDF) 或颜色 (PNG)。
- 问题 3:凌乱的临时文件。喜欢的可以加
unlink(tmpHTML)
。
完整示例
\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}