【问题标题】:Dynamically loop through htmlwidgets and add knitr formatting for RMarkdown动态循环遍历 htmlwidgets 并为 RMarkdown 添加 knitr 格式
【发布时间】:2016-05-03 15:43:23
【问题描述】:

我正在尝试动态创建和循环通过htmlwidgets(例如DTplotlyrbokeh)来生成自动编织报告。有没有办法将knitr 格式(例如tabset)添加到此github 问题https://github.com/ramnathv/htmlwidgets/pull/110 中概述的tagList 方法中?我也在那里发布了这个问题。

下面是我所想的一些示例代码,但它并不完全有效。我要做的是创建 10 个选项卡,每个选项卡都有一个从 plot_list 生成的图的副本。现在发生的是所有图都进入最后一个选项卡。在实践中,plot_list 会有不同的绘图/表格。

#' ---
#' title: htmltools::tagList test
#' output:
#'    html_document
#' ---

#' # {.tabset}
#+ results='asis', echo=FALSE
library(plotly)
library(printr)

plot_list = lapply(1:10, 
                   function(i){ 
                     as.widget(plot_ly(iris, 
                                       x = iris[["Sepal.Length"]],
                                       y = iris[["Sepal.Width"]], 
                                       mode = "markers")) 
                    } 
                  )

htmltools::tagList( lapply(1:10, 
                            function(i) {
                              pandoc.header(paste0("Tab",i,' {.tabset}'), 2)
                              plot_list[[i]]
                            } 
                          )
                   )

# rmarkdown::render("your_path/htmltoolsTagList_test.r")

以前,我用嵌套的 for 循环成功地做了这样的事情,但是一旦我尝试使用带有 HTML 依赖项的图形,图形当然不会呈现,因为它们不再是顶级表达式。 knitr 可以这样循环吗?

我的后续问题是:假设我想将这些选项卡嵌套到以相同方式创建的另一组选项卡中,这可能吗?我的意思是,我可以使用这样的方法动态嵌套选项卡吗,类似于嵌套的 for 循环?

我仍在学习如何使用knitr,如果有任何帮助,我将不胜感激! 谢谢!

【问题讨论】:

  • 我刚刚在 Github 问题上做了一点演示。让我知道它是否有帮助。谢谢。

标签: r knitr r-markdown htmlwidgets


【解决方案1】:

我将在下面复制我对 Github 问题的回复。

好问题,我认为其他人会从这次讨论中得到帮助。在没有rmarkdown 的帮助下,从头开始构建类似于您建议的东西可能是最简单的。

手动构建

# https://github.com/ramnathv/htmlwidgets/pull/110#issuecomment-216562703

library(plotly)
library(htmltools)
library(markdown)
library(shiny)

browsable(
  attachDependencies(
    tagList(
      tags$div(
        class="tabs",
        tags$ul(
          class="nav nav-tabs",
          role="tablist",
          tags$li(
            tags$a(
              "data-toggle"="tab",
              href="#tab-1",
              "Iris"
            )
          ),
          tags$li(
            tags$a(
              "data-toggle"="tab",
              href="#tab-2",
              "Cars"
            )
          )
        ),
        tags$div(
          class="tab-content",
          tags$div(
            class="tab-pane active",
            id="tab-1",
            as.widget(
              plot_ly(
                iris,
                x = iris[["Sepal.Length"]],
                y = iris[["Sepal.Width"]], 
                mode = "markers"
              )
            )
          ),
          tags$div(
            class="tab-pane",
            id="tab-2",
            as.widget(
              plot_ly(
                cars,
                x = speed,
                y = dist, 
                mode = "markers"
              )
            )
          )
        )
      )
    ),
    # attach dependencies
    #  see https://github.com/rstudio/rmarkdown/blob/master/R/html_document.R#L235
    list(
      rmarkdown::html_dependency_jquery(),
      shiny::bootstrapLib()
    )
  )
)

在 rmarkdown 中

可能有更好的方法来完成这项工作,但在有人让我明白之前,我们可以从上面采用方法并在rmarkdown 中使用它。不幸的是,这仍然是非常手动的。如需更多参考,这里是 RStudio 用来构建 tabsetscode

---
title: "tabs and htmlwidgets"
author: "Kent Russell"
date: "May 3, 2016"
output: html_document
---

```{r echo=FALSE, message=FALSE, warning=FALSE}
library(plotly)
library(htmltools)
library(magrittr)

# make a named list of plots for demonstration
#  the names will be the titles for the tabs
plots <- list(
  "iris" = plot_ly(
    iris,
    x = iris[["Sepal.Length"]],
    y = iris[["Sepal.Width"]], 
    mode = "markers"
  ),
  "cars" = plot_ly(
    cars,
    x = speed,
    y = dist, 
    mode = "markers"
  )
)

# create our top-level div for our tabs
tags$div(
  # create the tabs with titles as a ul with li/a
  tags$ul(
    class="nav nav-tabs",
    role="tablist",
    lapply(
      names(plots),
      function(p){
        tags$li(
          tags$a(
            "data-toggle"="tab",
            href=paste0("#tab-",p),
            p
          )
        )
      }
    )
  ),
  # fill the tabs with our plotly plots
  tags$div(
    class="tab-content",
    lapply(
      names(plots),
      function(p){
         tags$div(
          #  make the first tabpane active
          class=ifelse(p==names(plots)[1],"tab-pane active","tab-pane"),
          #  id will need to match the id provided to the a href above
          id=paste0("tab-",p),
          as.widget(plots[[p]])
        )
      }
    )
  )
) %>%
  # attach the necessary dependencies
  #  since we are manually doing what rmarkdown magically does for us
  attachDependencies(
    list(
      rmarkdown::html_dependency_jquery(),
      shiny::bootstrapLib()
    )
  )
```

【讨论】:

  • 感谢您的回复,肯特!对此,我真的非常感激。我仍在消化它,并且仍在努力查看是否可以以这种方式嵌套tabsets。然而,我有一个问题。要编译这段代码,我必须删除shiny::bootstrapLib() 行,所以我想知道那行代码是做什么的?我确保更新了我的包——也许你可以分享你的sessionInfo()?再次,非常感谢!
  • shiny::bootstrapLib()github.com/rstudio/shiny/blob/master/R/bootstrap.R#L50-L78 行中的辅助函数,于 2016 年 1 月 5 日在 github.com/rstudio/shiny/commit/… 中引入。 bootstrapLib 添加了 Bootstrap JavaScript/CSS 依赖项。我们可以手动执行此操作,但利用 RStudio 的工作会更容易。
  • 也许,我有一些类似的问题。也许你知道,发生了什么事?请参阅Q1Q2Q3。我正在研究 Rmarkdown 级别(首选)。
猜你喜欢
  • 2015-09-02
  • 2021-12-16
  • 1970-01-01
  • 2021-12-24
  • 2020-03-30
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多