如何在 RMarkdown 文档中排列 HTML 小部件(PDF,HTML)

How to arrange HTML Widgets inside of a RMarkdown Document (PDF, HTML)

我在 R notebook 中工作,想用它来创建两个输出:HTML 文档和 PDF 文档。

我的分析包括传单地图(html 小部件),这在我将笔记本编织成 PDF 文档时导致问题。感谢 webshot function now included in the knitr package, "knitr will try to generate static screenshots for HTML widgets automatically using the webshot package" (https://github.com/yihui/knitr/blob/master/NEWS.md).

当我的输出是一系列相互堆叠的传单地图时,这很好用,但我想以更简洁的行排列方式将这些地图分组在一起(见下图)。

这是我的 R 笔记本的可重现示例:gist

不幸的是,当我尝试将其编织成 PDF 文档时,我收到以下错误消息:

Error: Functions that produce HTML output found in document targeting latex output.
Please change the output type of this document to HTML. Alternatively, you can allow
HTML output in non-HTML formats by adding this option to the YAML front-matter of
your rmarkdown file:

  always_allow_html: yes

Note however that the HTML output will not be visible in non-HTML formats.

如何在 PDF 文档中获得这种单行排列方式?

如果我没理解错的话,那么你所要做的就是添加一些块选项。这里的关键是选项 fig.show='hold',它决定块中的所有图都将被 收集 并在块的最后一起显示。

---
title: "R Notebook"
output:
  pdf_document: 
    keep_tex: yes
  html_notebook: default
---

###Default Arrangement
```{r, echo=FALSE,message=FALSE, fig.height=4, fig.width=2, fig.show='hold'}
#devtools::install_github("wch/webshot")

library(leaflet)
library(htmltools)
library(RColorBrewer)

m1 <- leaflet(quakes) %>% 
        addTiles() %>% 
        addMarkers(lng=174.768, lat=-36.852)

m2 <- leaflet(quakes) %>% 
        addProviderTiles("Esri.WorldGrayCanvas") %>% 
        addMarkers(lng=174.768, lat=-36.852)

m3 <- leaflet(quakes) %>%
        addProviderTiles("Stamen.Toner") %>%
        addMarkers(lng=174.768, lat=-36.852)
m1
m2
m3
```

如果您希望 pdf 和 html 输出都采用这种格式,您可以将此脚本添加到您的 Rmd 文档的正文中(不在块内):

<script>
  $(document).ready(function() {
    $('.leaflet').css('float','left');
  });
</script>

尝试通过块选项 out.extra 添加这个 CSS 片段是行不通的,因为 LaTeX 不知道如何处理 CSS。虽然在编译为pdf时忽略了JS代码。

虽然所选答案确实解决了我的问题,但我决定采取稍微不同的方法。

我仍然调整 CSS 样式,但我没有使用针对所有 .leaflet 元素的 JS 脚本,而是将每个传单 htmlwidget 传递给一个名为 styleWidget 的辅助函数,它可以调整CSS 单独。这个函数有解释here,但我还是会在下面添加它的定义:

styleWidget <- function(hw=NULL, style="", addl_selector="") {
        stopifnot(!is.null(hw), inherits(hw, "htmlwidget"))

        # use current id of htmlwidget if already specified
        elementId <- hw$elementId
        if(is.null(elementId)) {
                # borrow htmlwidgets unique id creator
                elementId <- sprintf(
                        'htmlwidget-%s',
                        htmlwidgets:::createWidgetId()
                )
                hw$elementId <- elementId
        }

        htmlwidgets::prependContent(
                hw,
                htmltools::tags$style(
                        sprintf(
                                "#%s %s {%s}",
                                elementId,
                                addl_selector,
                                style
                        )
                )
        )
}

这改进了 Martin 的解决方案,因为它提供了更多控制 – 例如,我现在可以将第三张地图的麦粒更改为 float: none;,这样地图旁边就不会显示以下元素。 styleWidget 函数可用于修改 any htmlwidget 的 CSS(尽管不是 Shiny widget),使其成为一个很好的通用工具工具箱。