R/RShiny 范围界定 - 全局环境,避免 re-calculations 反应输出?

R/RShiny Scoping - Global environment, avoid re-calculations reaction output?

我有一个关于用户何时更改 Shiny 中的输入值以及如何有效地响应该更改的一般性问题。

首先,我会用文字来描绘图片,然后我会尝试用代码创建我正在谈论的内容的最小版本。

操作: 用户将下拉菜单更改为 select 特定项目。

反应: 基于该用户输入的过滤函数应用于输出变量并显示在屏幕上。

问题: 我想为显示的所有输出值应用该过滤器(无需再次调用该过滤器函数)。

目前,我正在使用我的过滤器调用相同的函数作为我的每个输出变量的函数的参数。这似乎是一种计算浪费,因为我真的只需要调用一次函数,使用所有这些数据来填充我所有的输出值。

我觉得我在这里缺少一些基本的东西。

理想情况下,我希望能够调用这样的东西(returns 一个包含小标题和其他一些计算值的列表):

test <- reactive({se_report_filtered(my_filter = input$PM_ID, 
                                          start_year = input$obs[1], 
                                          end_year = input$obs[2])})

se_report_filtered 是一个实际为我和 returns 计算新值的函数。

然后使用 test 填充所有其他输出值。我似乎无法让它发挥作用。相反,我为每个输出调用 se_report_filtered。这似乎是错误的方法。

这不是一个完全可复制的片段,但我希望这个想法仍然存在。

library(shiny)
library(shinydashboard)

header <- dashboardHeader(title = "Home")

frow1 <- fluidRow(
  valueBoxOutput("value2"), 
)


body <- dashboardBody(frow1)

#completing the ui part with dashboardPage
ui <- dashboardPage(title = 'Review', header, sidebar, body, skin='red')


server <- function(input, output) {

output$value2 <- renderValueBox({ 
    valueBox(
      formatC(se_report_filtered(my_filter = input$PM_ID, 
                                 start_year = input$obs[1], 
                                 end_year = input$obs[2])[[2]], 
              format="d", big.mark=',')
      ,'Total Met'
      ,icon = icon("stats",lib='glyphicon')
      ,color = "green")  
  })
}

shinyApp(ui, server)

所以,基本上,我想替换:

output$value2 <- renderValueBox({ 
        valueBox(
          formatC(se_report_filtered(my_filter = input$PM_ID, 
                                     start_year = input$obs[1], 
                                     end_year = input$obs[2])[[2]], 
                  format="d", big.mark=',')
          ,'Total Met'
          ,icon = icon("stats",lib='glyphicon')
          ,color = "green")  
      })

output$value2 <- renderValueBox({ 
        valueBox(
          formatC(test[[2]], 
                  format="d", big.mark=',')
          ,'Total Met'
          ,icon = icon("stats",lib='glyphicon')
          ,color = "green")  
      })

我相信在处理反应变量时我遗漏了一些基本的东西。

同样,我不确定你的函数是做什么的,所以我创建了一个反应列表,其中第四个元素是来自滑块的输入。当我调用反应变量时,我在子设置第四个之前将它分配给一个常规变量。这一切都在渲染函数中完成。

library(shiny)
library(shinydashboard)

ui  <- fluidPage(
  fluidRow(
    valueBoxOutput("value2"),
    sliderInput("slider","Fourth Element", 1, 10, 5)
  ))

server <- function(input, output, session) { 

  test<-reactive(list(1,2,3,input$slider))

  output$value2 <- renderValueBox({ 
    Test<-test()
    Test<-Test[4]
    valueBox(
      formatC(Test, 
              format="d", big.mark=',')
      ,'Total Met'
      ,icon = icon("stats",lib='glyphicon')
      ,color = "green")  
  })



}


shinyApp(ui = ui, server = server)

由于渲染函数是一个反应性环境,它会响应反应性变量的变化,在这种情况下test()

在你的例子中 test() returns 无论在 se_report_filtered 中创建什么,它都可以以相同的方式进行子集化。