【问题标题】:R shiny: cannot download interactive reportR闪亮:无法下载交互式报告
【发布时间】:2018-08-15 14:54:12
【问题描述】:

我希望下载一个交互式 R 闪亮文档并将其保存到一个文件中以供其他用户(不拥有 R 或 Rstudio)查看和交互。 R 闪亮文档运行良好,但是当我尝试将下载的文件保存在某处时,下载按钮失败。这是我的代码;我使用了数据集“汽车”,因此可以重现错误:

闪亮的代码:

library(knitr)
library(shiny)
library(ggplot2)
library(readr)

x <- cars
x$dist_cut <- cut(x$dist, breaks = c(-1, 25, 50, 75, 100, 9999), 
                       labels = c("0-25", "26-50", "51-75", "76-100", ">100"))

t.cut <- table(x$dist_cut)

# Define UI for dataset viewer app ----
ui <- fluidPage(

  # App title ----
  titlePanel("Cars Data"),

  # Sidebar layout with a input and output definitions ----
  sidebarLayout( position = "right",

                 # Sidebar panel for inputs ----
                 sidebarPanel(

                   # Input: Selector for choosing dataset ----
                   selectInput(inputId = "dataset",
                               label = "Choose a range for dist:",
                               choices = c("show all", ">100", "76-100", "51-75", "26-50", "0-25")),
                   downloadButton('downloadReport')

                 ),

                 # Main panel for displaying outputs ----
                 mainPanel(

                   # Output: Barplot ----
                   plotOutput(outputId = "distPlot"),

                   # Output: HTML table with requested number of observations ----

                   DT::dataTableOutput("view")


                 )
  )
)

# Define server logic to summarize and view selected dataset ----
server <- function(input, output) {

  # Return the requested dataset ----
  datasetInput <- reactive({
    switch(input$dataset,
           "show all" = x,
           ">100" = x[x$dist_cut == ">100",],
           "76-100" = x[x$dist_cut == "76-100",],
           "51-75" = x[x$dist_cut == "51-75",],
           "26-50" = x[x$dist_cut == "26-50",],
           "0-25" = x[x$dist_cut == "0-25",])
  })

  # display the plot
  output$distPlot <- renderPlot({

    barplot(t.cut, beside = TRUE, col = c("green", "blue", "yellow", "orange", "red"), main = "Cars sorted by dist", ylim = c(0, 20), cex.main = 1.5, xlab = "dist", ylab = "Frequency")

  })

  # create the DT datatable
  output$view = DT::renderDataTable({
    DT::datatable(datasetInput(), filter = 'top', 
                  options = list(lengthMenu = c(5, 10, nrow(x)), pageLength = 5))

  })

  output$report <- downloadHandler(
    filename = function() paste0("report", ".html"),
    content = function(file) {
      tempReport <- file.path(tempdir(), "report.rmd")
      file.copy("report.rmd", tempReport, overwrite = TRUE)

      # Set up parameters to pass to Rmd document
      params <- list(data = x,
                     title = "Plot Title",
                     limits = c(-10,10))
      # Knit the document, passing in the `params` list, and eval it in a
      # child of the global environment (this isolates the code in the document
      # from the code in this app).
      rmarkdown::render(tempReport, output_file = file,
                        params = params,
                        envir = new.env(parent = globalenv())
      )
    }     
  )

}

# Create Shiny app ----
shinyApp(ui = ui, server = server)

降价代码:

---
output: html_document
params:
    data: NULL
    limits: NULL
    title: "Cars Data"
title: "`r params$title`"
---

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

```{r}
print(params$title)
barplot(table(params$x$dist_cut), beside = TRUE, col = c("green", "blue", "yellow", "orange", "red"), main = "Cars Split by dist", ylim = c(0, 20), cex.main = 1.5, xlab = "dist", ylab = "Frequency") 
library(DT) 
datatable(params$x, filter = 'top', options = list(lengthMenu = c(5, 10, nrow(x)), pageLength = 5))
```

使用此代码,我在单击下载按钮后收到以下警告和错误:

Warning: Error in : path for html_dependency not provided
  [No stack trace available]
Warning in min(w.l) : no non-missing arguments to min; returning Inf
Warning in max(w.r) : no non-missing arguments to max; returning -Inf
Warning in min(x) : no non-missing arguments to min; returning Inf
Warning in max(x) : no non-missing arguments to max; returning -Inf
Warning: Error in plot.window: need finite 'xlim' values

我还收到一个标题为“下载失败”的弹出窗口:

Error downloading {R shiny html link} - server replied: Internal Service Error

我花了大约一周的时间尝试调试它,但我还没有完全弄清楚我缺少什么。我是 R Shiny Web 应用程序的新手,我真的很想允许非 R 用户查看这些交互式报告以帮助他们完成工作。我希望这是足够的信息来帮助找到我的问题的解决方案。

谢谢!

更新:当我保存 HTML 文件并在 Internet Explorer 中打开它时,我只看到页面顶部的标题(汽车数据)和侧边栏面板(包含下拉框和下载按钮)。此外,我收到一条提示“Internet Explorer 限制此网页运行脚本或 ActiveX 控件”,当我按“允许阻止的内容”时没有任何反应。这和问题有关系吗?

对于最初没有发布可重现的示例,我深表歉意:这是我的第一篇 stackoverflow 帖子。

【问题讨论】:

标签: r shiny shiny-reactivity


【解决方案1】:

server replied: Internal Service Error 只是一个通用错误,这意味着您的.Rmd 无法正确呈现。您真正的问题可能出在您的.Rmd 上。

如果你查看堆栈跟踪错误,它会说:

Warning in min(w.l) : no non-missing arguments to min; returning Inf

当您单击下载按钮时,它会在您的 .Rmd 上运行 render 函数并尝试渲染它。从错误的外观来看,您正在尝试绘制某些东西,但是您的绘图函数试图用来制作绘图的部分或全部对象无法找到,因此它失败并出现错误。

由于您的绘图数据来自闪亮的应用程序,您必须将其传递到.Rmd。更好的方法是将.Rmd 需要的数据作为列表直接传递给rmarkdown::renderparams= 参数。

# NOTE: downloadHandler must be assigned to the ID of your downloadButton
output$downloadReport <- downloadHandler(
    filename = function() paste0("report", ".html"),
    content = function(file) {
        tempReport <- file.path(tempdir(), "report.rmd")
        file.copy("report.rmd", tempReport, overwrite = TRUE)

        # Set up parameters to pass to Rmd document
        #  these can be any time of R objects
        #  that you want your .Rmd to have access to
        params <- list(data = x,
                       title = "Plot Title",
                       limits = c(-10,10))
        # Knit the document, passing in the `params` list, and eval it in a
        #  child of the global environment (this isolates the code in the document
        #  from the code in this app).
        rmarkdown::render(tempReport, output_file = file,
                          params = params,
                          envir = new.env(parent = globalenv())
        )
    }     
)

现在在您的.Rmd 中,您可以在标题中定义这些参数:

---
output: html_document
params:
    data: NULL
    limits: NULL
    title: "Default title"
title: "`r params$title`"
---

然后通过访问params 对象来使用它。将对象作为param 传递到.Rmd 后,您可以使用您在参数列表中提供的名称在.Rmd 中访问它。因此,即使您的数据框在您的闪亮应用程序中被命名为x,由于您将它传递给参数data,您将使用params$data.Rmd 中访问它。

```{r}
print(params$title)
barplot(table(params$data$dist_cut), beside = TRUE,
        col = c("green", "blue", "yellow", "orange", "red"),
        main = "Cars Split by dist", ylim = c(0, 20),
        cex.main = 1.5, xlab = "dist", ylab = "Frequency")

library(DT)
DT::datatable(params$data, filter = 'top',
              options = list(lengthMenu = c(5, 10, nrow(params$data)),
                             pageLength = 5))
```

通过params 参数显式传递对象(并在新环境中呈现.rmd)确保您需要的数据对您的.rmd 可用,并且它具有正确 em> 数据(在 Shiny 中尤其重要,因为用户输入可能会导致对象的内容以意想不到的方式发生变化)并防止命名空间冲突(环境中存在具有相同名称的意外对象)

【讨论】:

  • 这成功了!我有几个后续问题:1)为了让它工作,我必须复制我的 R-markdown 文件并粘贴到一个临时目录(C:\Users\U1335567\AppData\Local\Temp\RtmpkHyWYg) .如果没有,R 就找不到报告。每次我尝试下载报告时都必须这样做吗,或者我可以更改代码以便它从我的工作目录中读取降价文件吗?
  • 2) 我有另一个带有交互式图表的报告。在数据框“汽车”中——使用 R shiny——说我想为特定的“速度”显示一个“距离”的条形图(使用 numericInput() 框选择速度)。条形图会根据我选择的速度而变化。下载后此功能会丢失,还是有办法保留它?如果我的问题不清楚,如果您需要我给您一个可验证的示例,请告诉我。
  • 这些行:tempReport &lt;- file.path(tempdir(), "report.rmd")file.copy("report.rmd", tempReport, overwrite = TRUE) 应该将您的报告复制到一个临时目录中以进行呈现。您不必手动移动文件。至于您的第二个问题,您可以使用参数将您想要的任何信息传递给.rmd,因此您没有理由不能传递您选择的速度并使用它来子集您的数据或其他任何东西。
  • 如果你有更多问题,你真的应该问另一个问题。此处的问答格式仅适用于您有特定问题和特定答案的情况。您可以提出的问题数量没有限制,所以如果您还有其他问题,请再问一个问题
猜你喜欢
  • 2021-07-31
  • 2021-10-14
  • 2019-05-20
  • 1970-01-01
  • 2017-04-20
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
相关资源
最近更新 更多