【问题标题】:Are there global variables in R Shiny?R Shiny 中有全局变量吗?
【发布时间】:2013-12-18 11:05:43
【问题描述】:

如何在 R Shiny 中声明全局变量,从而无需多次运行相同的代码?作为一个非常简单的示例,我有 2 个使用相同精确数据的图,但我只想计算一次数据。

这是 ui.R 文件:

library(shiny)

# Define UI for application that plots random distributions 
shinyUI(pageWithSidebar(

# Application title
headerPanel("Hello Shiny!"),

# Sidebar with a slider input for number of observations
sidebarPanel(
sliderInput("obs", 
            "Number of observations:", 
            min = 1,
            max = 1000, 
            value = 500)
  ),

# Show a plot of the generated distribution
 mainPanel(
   plotOutput("distPlot1"),
  plotOutput("distPlot2")
 )
))

这是 server.R 文件:

library(shiny)

shinyServer(function(input, output) {

  output$distPlot1 <- renderPlot({ 
    dist <- rnorm(input$obs)
    hist(dist)
  })

  output$distPlot2 <- renderPlot({ 
    dist <- rnorm(input$obs)
    plot(dist)
  })

})

请注意,output$distPlot1output$distPlot2 都执行 dist &lt;- rnorm(input$obs),这会重新运行相同的代码两次。如何使“dist”向量运行一次并使其可用于所有渲染图函数?我试图将 dist 放在以下功能之外:

library(shiny)

shinyServer(function(input, output) {

  dist <- rnorm(input$obs)

  output$distPlot1 <- renderPlot({ 
    hist(dist)
  })

  output$distPlot2 <- renderPlot({ 
    plot(dist)
  })

})

但我收到一条错误消息,提示找不到“dist”对象。这是我真实代码中的一个玩具示例,我将 50 行代码粘贴到多个“渲染...”函数中。有什么帮助吗?

哦,是的,如果你想运行这段代码,只需创建一个文件并运行它: 图书馆(闪亮) getwd() runApp("C:/Desktop/R Projects/testShiny")

其中“testShiny”是我的 R 工作室项目的名称。

【问题讨论】:

  • 只要dist &lt;- reactive(rnorm(input$obs))。现在你可以在你的函数中使用它作为dist()
  • 是的,这行得通,但是当你有 50 行代码需要计算 dist 时你会怎么做?
  • 只需将 50 行放入 reactive({...}) 中,最后一行返回 dist 的值。 reactive 只是一个包装器,使其内容具有反应性。
  • 更好的做法是将大部分函数放在全局中并从 reactive() 调用它,这样您就可以在运行应用程序时测试您的函数而不必停止执行

标签: r shiny global-variables


【解决方案1】:

Shiny webpage 上的此页面解释了 Shiny 变量的作用域。

全局变量可以放在server.R(根据里卡多的回答)或global.R

在 global.R 中定义的对象与在 shinyServer() 之外的 server.R 中定义的对象类似,但有一个重要区别:它们对 ui.R 中的代码也是可见的。这是因为它们被加载到 R 会话的全局环境中; Shiny 应用程序中的所有 R 代码都在全局环境或其子环境中运行。

实际上,不需要在 server.R 和 ui.R 之间共享变量的情况并不多见。 ui.R 中的代码运行一次,当 Shiny 应用程序启动时,它会生成一个 HTML 文件,该文件被缓存并发送到每个连接的 Web 浏览器。这对于设置一些共享配置选项可能很有用。

【讨论】:

  • 全局变量不是reactive。所以你不能在global.R中做类似dist &lt;- rnorm(input$dist)的事情。
  • @Ramnath:如果你想要全局反应变量,你可以将它们定义为reactiveValues
  • 但不是input$...。这些必须在shinyServer 中定义。
【解决方案2】:

如上面@nico 列出的链接中所述,您还可以在函数内部使用

foo <<- runif(10)

而不是

foo <- runif(10)

链接显示“如果对象发生更改,则更改的对象将在每个用户会话中可见。但请注意,您需要使用

我已经使用它在闪亮方面取得了不同程度的成功。与往常一样,请小心使用全局变量。

【讨论】:

  • 谢谢!这个答案绝对拯救了我的一天,希望我能为此给你更多的声望!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
  • 2012-06-09
  • 2010-11-17
  • 1970-01-01
  • 2019-08-26
相关资源
最近更新 更多