【问题标题】:Create static report from dynamic shiny markdown从动态闪亮的降价创建静态报告
【发布时间】:2018-03-12 22:22:05
【问题描述】:

我有一个shiny markdown 应用程序,其中有几个数字,比如一周中的不同日子。这些数字上方是我写一些 cmets 的文本区域。

我希望能够将此报告导出为static markdown 格式。

我将在下面展示一个(主要)可重现的示例,第一部分是我想要编辑的代码,以便它在单独的文件中从第二部分创建代码。

---
title: "WEEKLY REPORT"
runtime: shiny
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = F)
```

```{r header, echo=FALSE}
selectInput("x", label = "x",choices = 1:10,width="100%")
actionButton("button", "Export report")
```

## Monday

```{r monday}
textAreaInput("mon", label = NULL)
renderPlot({
plot(log(1:input$x))
})
```

## Tuesday

```{r tuesday}
textAreaInput("tue", label = NULL)
renderPlot({
plot(sin(1:input$x))
})
```

如何编辑它,以便操作按钮创建一个新的 Rmd 文件,其中包含以下代码(或创建类似输出的 Rmd 文件)? (将 png url 更改为任何现有文件以使其可重现)。

---
#  title: "WEEKLY REPORT"
output: html_document
---

## Monday

The text I would have put on the first box

![](plot_monday.png)    

## Tuesday

The text I would have put on the second box

![](plot_tuesday.png)

所以基本上输入选择器必须离开,文本区域需要更改为标准文本(可能包含降价),并且必须将绘图导出为相关输入的图片文件,然后作为图片插入回报告。

理想情况下,我还希望能够将星期一和星期二导出到不同的 Rmd 文件中。

【问题讨论】:

  • 有一个包webshot 可让您从闪亮的应用程序中制作png 屏幕截图。您可以通过将 Rmd 文档包装在闪亮的应用程序中来使用它。见here

标签: r shiny r-markdown


【解决方案1】:

我认为最简单的方法是使用报告模板并将输入作为参数传递。

因此,您在与 Shiny 报告相同的目录中创建一个文件名为“sampleRmdReport.Rmd”的报告,其内容如下:

---
title: "Weekly Report"
author: "Moody_Mudskipper"
date: '`r format(Sys.Date(),"%Y-%B-%d")`'
output: html_document
params:
  mondayText: "holder"
  tuesdayText: "holder"
  x: "holder"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, results = "asis")
```
# Monday

```{r}
cat(params$mondayText)
```

```{r}
plot(log(1:params$x))
```

# Tuesday

```{r}
cat(params$tuesdayText)
```

```{r}
plot(sin(1:params$x))
```

然后,将以下内容添加到您的闪亮报告中:

Download the weekly report:

```{r}
downloadHandler(
  filename = function(){
    paste0("weeklyReport_generated_"
           , format(Sys.Date(), "%Y%b%d")
           , ".html")
  }
  , content = function(file){
    rmarkdown::render(input = "sampleRmdReport.Rmd"
                      , output_file = file
                      , params = list(mondayText = input$mon
                                      , tuesdayText = input$tue
                                      , x = input$x
    ))
  }
  , contentType = "text/html"
)

```

制作完整文件:

---
title: "WEEKLY REPORT"
runtime: shiny
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = F)



```

```{r header}
selectInput("x", label = "x",choices = 1:10,width="100%")
```

Download the weekly report:

```{r}
downloadHandler(
  filename = function(){
    paste0("weeklyReport_generated_"
           , format(Sys.Date(), "%Y%b%d")
           , ".html")
  }
  , content = function(file){
    rmarkdown::render(input = "sampleRmdReport.Rmd"
                      , output_file = file
                      , params = list(mondayText = input$mon
                                      , tuesdayText = input$tue
                                      , x = input$x
    ))
  }
  , contentType = "text/html"
)

```




## Monday

```{r monday}
textAreaInput("mon", label = NULL)

renderPlot({
  plot(log(1:input$x))
})


```


## Tuesday

```{r tuesday}
textAreaInput("tue", label = NULL)

renderPlot({
  plot(sin(1:input$x))
})
```

然后,单击“下载”按钮将生成报告并提示用户下载。请注意,如果您在 RStudio 中进行测试,则文件名将不起作用。我建议在浏览器中打开它进行测试。

然后,如果您希望能够生成单独的每日报告,只需为您想要的报告添加一个模板,并为每个报告添加一个下载按钮。或者,您可以让您的downloadHandler 生成每天的报告(从模板中)并将它们放在一个压缩目录中以便一起下载。

(注意:我倾向于发现这在 Shiny App 中比在降价文档中更灵活,特别是因为它允许更多地控制下载按钮。根据您的用例,可能值得考虑将其作为一种方法.)

基于 cmets,这是一个可以上传到 Imgur 并以这种方式插入图像的版本。用这个替换另一个模板或添加第二个按钮。请注意,我没有让 imgur 上传功能工作,因为我没有 API 密钥(我假设你有,因为你打算这样做)。

---
title: "Weekly Report"
author: "Moody_Mudskipper"
date: '`r format(Sys.Date(),"%Y-%B-%d")`'
output:
  html_document:
    self_contained: false
params:
  mondayText: "holder"
  tuesdayText: "holder"
  x: 1
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, results = "asis")
library(ggplot2)
tempDir <- tempdir()

uploadImgur <- function(fileName){
  # This function would need to upload with the Imgur API
  # I don't have a key, and don't want to set one up
  # for this example.

  # It would return the url that imgur assigns the image
  # here, I am using a placeholder
  outUrl <- "https://i.imgur.com/WsUV4DK.gif"

  return(outUrl)
}
```

# Monday

```{r}
cat(params$mondayText)
```


```{r}
tempPlot <-
  ggplot(mapping = aes(x = 1:params$x
                       , y = log(1:params$x))) +
  geom_point() +
  xlab("X") +
  ylab("Y")

tempFile <- tempfile("plot_", tempDir, ".png")
ggsave(tempFile, tempPlot, width = 4, height = 4)

imgurURL <- uploadImgur(tempFile)

cat("![](", imgurURL,")", sep = "")
```



# Tuesday

```{r}
cat(params$tuesdayText)
```


```{r}
tempPlot <-
  ggplot(mapping = aes(x = sin(1:params$x)
                       , y = log(1:params$x))) +
  geom_point() +
  xlab("X") +
  ylab("Y")

tempFile <- tempfile("plot_", tempDir, ".png")
ggsave(tempFile, tempPlot, width = 4, height = 4)

imgurURL <- uploadImgur(tempFile)

cat("![](", imgurURL,")", sep = "")

```

【讨论】:

  • 我喜欢这种方法,在某些情况下可能会令人满意,但也存在一些问题。
  • 首先它给了我 html 而不是 markdown 文件作为输出,这意味着当结构已经全部布局在动态报告中时,我必须构建模板。这是可以接受的,因为我不会构建非常复杂的报告,但这仍然是额外的时间和错误和调试的风险。我认为它可以通过一些动态报告的解析和一些正则表达式的乐趣来处理。
  • 第二个问题是它渲染的是情节而不是图片。为了透明,我想使用 wordpress 包从 R 博客,使用一个名为 knit2wp 的函数,它不适用于绘图(所以对于这个用途,我必须插入一个步骤来上传pngs 到 imgur 并使用这个 url,但这是另一个问题)。 @Nice 使用 ggsave 发布了一个解决方案,我认为它可能与您的方法混合在一起,尽管他出于某种原因快速删除了它。
  • 我听到了,如果它不起作用,它就不起作用。然而,对于您的第一个问题,我认为构建一个单独的模板实际上可能会更好。它提供了构建稍微不同的东西(如果你想要的话)的灵活性,这意味着你不必被锁定在闪亮的报告格式中(例如,如果你想切换到一个应用程序来获得一个选项卡或侧面面板或向报告中添加动态切片等)。其次,您可以将 imgur 步骤添加到您的模板中。例如,使用 ggsave,上传到 imgur,然后使用 cat 将 url(而不是绘图)动态添加到报告中。
  • 这两点都很好,我想如果我用正确的代码替换您的downloadHandler,我可以保存图片、上传它们、通过 url 渲染它们并在博客中完成整个事情。
【解决方案2】:

如果您可以使用ggplot,您可以使用ggsave 将绘图在本地保存为 png。

你可以在你的主文件上试试这个:

---
title: "WEEKLY REPORT"
runtime: shiny
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = F)
library(ggplot2)
```

```{r header, echo=FALSE}
selectInput("x", label = "x",choices = 1:10,width="100%")
actionButton("button", "Export report")
observeEvent(input$button,{
  params <- list(text = input$mon)
  render('report.Rmd',params = params)
})
```

## Monday

```{r monday}
textAreaInput("mon", label = NULL)
renderPlot({
  p <- ggplot(data.frame(x=1:input$x,y=log(1:input$x)),aes(x=x,y=y))+
    geom_point()   
  ggsave("plot.png",plot=p)
  p
})
```

对于您的静态报告(需要与其他 .Rmd 位于同一文件夹中):

---
#  title: "WEEKLY REPORT"
output: html_document
---

## Monday
```{r}
params$text
```

![plot](plot.png)

我不确定如何在闪亮的 Rmd 中使用下载处理程序制作正确的下载按钮,因此这只适用于从 RStudio 运行而不是在浏览器中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2020-12-04
    • 2015-03-26
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多