【问题标题】:R/RShiny Scoping - Global environment, avoid re-calculations reaction output?R/RShiny Scoping - 全球环境,避免重新计算反应输出?
【发布时间】:2019-04-09 00:44:27
【问题描述】:

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

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

操作:用户更改下拉菜单以选择特定项目。

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

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

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

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

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

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

se_report_filtered 是一个实际为我计算新值并返回列表的函数。

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

这不是一个完全可重复的 sn-p,但我希望这个想法仍然存在。

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")  
      })

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

【问题讨论】:

  • 我不认为您可以对反应变量进行子集化,而是您可能需要考虑使用reactiveValues,但这取决于se_report_filtered 创建的结构。通常,当您调用反应变量时,您会将其视为“函数”,例如test()
  • 您也可以在将反应变量传递给renderValueBox之前将其分配给普通变量,例如在反应环境中test&lt;-test()

标签: r shiny shiny-server shinydashboard reactive


【解决方案1】:

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

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() 返回在 se_report_filtered 内部创建的任何内容,它可以以相同的方式作为子集。

【讨论】:

  • 这很有效,这正是我想要的。除了我必须使用带有双括号的Test[[4]]
猜你喜欢
  • 2018-10-10
  • 2016-02-10
  • 1970-01-01
  • 2018-12-16
  • 2020-11-01
  • 2017-06-04
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多