R Sweave(RNW)文档中的formattable对象

时间:2016-03-14 11:38:24

标签: r knitr sweave formattable

我正在使用formattable包来获得R中更好看的数据帧。假设我的数据如下所示:

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)))
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)))
)

这样一切正常(在RStudio预览和HTML文档中),但是当我尝试将此表放在R Sweave文档中时,它不会被渲染。

我尝试使用format_table输出为knit_kable个对象或knit_print,但都没有效果。

1 个答案:

答案 0 :(得分:2)

简而言之,问题是:如何在RNW文档中使用formattable(或者一般来说:生成降价/ HTML输出的函数)?

背景

首先,我认为可以应用this answer中建议的方法。它允许在RNW文档中嵌入markdown标记。但事实证明,formattable产生了markdown和HTML输出的混合 - 在这种情况下,这种方法将无效。

大约3周前,fdetsch posted a nice answer显示了如何在RNW文档中嵌入leaflet(或一般来说:htmlWidget s)。这个答案建立在并扩展了fdetsch的解决方案之上。

解决方案(原始)

  • 从GitHub安装webshot库,并在必要时安装devtoolshtmlwidgets

    devtools::install_github("wch/webshot")
    
  • formattable的返回值保存在对象中(我使用mytable)。
  • mytable转换为htmlWidgetas.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"传递给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}