【问题标题】:Inside Shiny app, use external R script to generate variables passed to an R Markdown rendering在 Shiny 应用程序中,使用外部 R 脚本生成传递给 R Markdown 渲染的变量
【发布时间】:2020-06-24 16:40:49
【问题描述】:

我对这个可复制的 Shiny 小应用程序感到疯狂:

基本上3步:

  1. 我有一个input$text,用户可以选择
  2. 用户触发 R 文件 create_text.R 转换此文本,创建 my_text 字符串。 (IRL 基本上是一个下载和数据准备步骤)
  3. 用户触发 R Markdown 渲染,其中打印了 my_text

我的基本代码如下:

app.R

library(shiny)

ui <- fluidPage(
  selectInput(inputId = "text",
              label = "Choose a text",
              choices = c("Hello World!", "Good-bye World!")),
  actionButton("create_text", "Prepare text"),
  downloadButton("report", "Render markdown"))
)

server <- function(input, output) {
  
  observeEvent(input$create_text, {
    text_intermediate <- input$text
    source('create_text.R')
    })
  
  output$report <- downloadHandler(
    filename = "report_test.html",
    content = function(file) {
      rmarkdown::render(input = "report_test.Rmd",
                        output_file = file)
      })

  }

shinyApp(ui, server)

create_text.R

my_text <- paste("transfomation //", text_intermediate)

report_test.Rmd

---
title: "My title"
output: html_document
---

```{r}
my_text
```

我的问题是中间步骤(2.),可能是因为我对环境感到困惑。

  • 如果我运行 source('create_text.R', local = FALSE),它会失败,因为 R 文件是从空环境中运行的,然后无法识别 text_intermediate
# Warning: Error in paste: object 'text_intermediate' not found
  • 相反,如果我运行source('create_text.R', local = TRUE),则创建的my_text 字符串不会“保存”到下一个闪亮的应用程序中,那么由于my_text is not found,因此无法呈现Rmd。
# Warning: Error in eval: object 'my_text' not found

我尝试过的:

两个丑陋的解决方案是:

  • 不要使用中间 R 文件并将整个代码包含在应用程序中,但这会使其非常不可读
  • 甚至更丑,只在R文件中使用硬赋值&lt;--,比如my_text &lt;&lt;- paste("transfomation //", text_intermediate)

使用render() 函数的env 参数也无济于事。

最后,从头开始我会在任何地方都使用响应式值,但是我的 R 和 Rmd 文件都非常大并且“已完成”,并且很难调整代码。

有什么帮助吗?

【问题讨论】:

  • 试试source('create_text.R', local = TRUE),它将使用当前(调用)环境而不是全局环境。
  • 另外,参数化降价可能是您实际用例所需要的。看看this...
  • 也可以将create_text.R文件中的语句写成函数,然后在server中使用该函数。
  • @Limey 是的,没有提到它作为可能的选项,但我宁愿避免它,因为我的脚本中定义了许多变量。
  • @phago29 确实是个好主意,你会如何使用它?如果我用create_text &lt;- function() {my_text &lt;- paste("transfomation //", text_intermediate) } 定义它然后调用create_text(),由于“简单”分配(&lt;-),它不会在环境中加载my_text&lt;-

标签: r shiny r-markdown


【解决方案1】:

好的,最后我用这个不优雅的解决方案绕过了这个问题:

我在运行外部 R 脚本后添加了一段代码,它将所有创建的对象存储到全局环境中。这样,这些对象稍后可以在 server 函数中调用。这允许在没有eventReactive() 的情况下使用。不是很愉快,但很有效。

为此,我在lapply 中使用assign。在我的例子中,它相当于写:my_text &lt;&lt;- my_text。 lapply 允许对所有对象执行此操作。

observeEvent(input$create_text, {
  text_intermediate <- input$text
  source('create_text.R')
  lapply(X = (ls()), FUN = function(object) {assign(object, get(object), envir = globalenv())})
})

【讨论】:

    猜你喜欢
    • 2021-07-11
    • 1970-01-01
    • 2023-03-08
    • 2019-03-04
    • 2021-07-29
    • 2016-10-13
    • 2019-03-02
    • 1970-01-01
    • 2019-10-03
    相关资源
    最近更新 更多