如何在闪亮的某些条件下保持物体相同?

时间:2015-01-06 19:21:31

标签: r shiny

对于我的工作,我正在创建一个闪亮的应用程序。它目前工作正常,但获取数据需要我与SQL接口,这需要一段时间。此应用程序以两种方式使用数据:1)显示数据,2)使用数据运行模拟(这也很耗时)。我需要能够为许多不同的客户获取数据。

到目前为止,我可以将数据与模拟分开,并使用我已经在模拟中直接获得的数据,前提是我已经拥有了正确的数据。如果客户编号发生变化,我可以获取数据并运行模拟。所有这些都很棒,但我不能做的一件事就是显示我得到的数据用于模拟,如果我还没有正确的数据。

我已经尝试了几种方法来实现这一目标,但我正在研究的那个方法是尝试让数据对象保持原样,如果我已经拥有数据,并且客户编号是正确的,但是在所有其他情况。我试图做的所有方法都给了我一个无限循环或空白数据集。我创建了一个愚蠢的应用程序版本(因为我无法显示真正的应用程序),应该突出我遇到的问题。这就是我目前所拥有的:

library(shiny)

shinyUI(fluidPage(
  fluidRow(wellPanel(
    #create at action button to generate data.
    actionButton("gen", "Generate"),
    textOutput("check")
    ),
    wellPanel(
      #'create an action button for simulation.  Here there is no simulation because
      #'I am not having a problem with simulation, but this should also generate
      #'data if there is no data, or the customer numbers do not match
      actionButton("sim", "Simulate"),
      #indicates whether the customer numbers match
      checkboxInput("same", "Same customer number", value = T),
      #output the data table
      dataTableOutput("data")
      ))
  ))

library(mvtnorm)


shinyServer(function(input, output){
  #'every time I hit the sim button, this is set as the gen button's count.
  #'By checking to see if this equals the count of the gen button, I can generate
  #'data every time I hit the gen button, but not every time I hit the sim button
  gen.check<-reactive({
    input$sim
    isolate({as.numeric(input$gen)})
  })
  output$check<-renderText({
    gen.check()<input$gen
  })
  #indicates whether there is already data or not
  check<-reactive({
    if(input$gen==0 & input$sim==0){
      FALSE
    }else{
      TRUE
    }
  })
  #generate the data
  data<-reactive({
    #'this stops the app from displaying data when it opens.  Not super important
    #'here, but in the actual app, getting the data is time consuming, so I don't
    #'want it to start out by getting data I don't need
    if(input$gen==0 & input$sim==0){
      return()
    }
    #This line makes data show up every time I hit the gen button
    if(input$gen>gen.check()){
      rmvnorm(20, 1:5, diag(5))
    }else{
      #'I had hoped this blank loop here would make the data stay the same if there
      #'already was data, and the customer numbers matched, but instead it makes the
      #'data disappear under these conditions
      if(isolate({input$same}) & check()){
      }else{
        #'This generates data if there is none, or if the numbers don't match when
        #'you hit sim
        rmvnorm(200, 1:5, diag(rep(.1, 5)))
      }
    }
  })
  #'This piece is separate because in the actual app I need to use the data generated
  #'above two different ways.  I am just using it here to check when the data changes.
  output$data<-renderDataTable({
    if(input$gen==0 & input$sim==0){
      return()
    }
    as.data.frame(data())
  })
})

当我单击“gen”按钮时,代码成功生成数据。当我单击“sim”按钮时,如果复选框指示数字不相同,它还会生成并显示数据。我希望如果我已经生成了数据,并且我点击了模拟,那么如果客户编号是相同的,那么我所显示的数据就不会发生。

我在这里直接显示的数据()将在我为工作创建的应用程序中使用相同的方式(尽管它将是真实数据,而不是生成的数据),并且相同的数据()直接转到模拟。只有在适当的时候才能改变这一点,这是我遇到的唯一问题。

编辑:这是我第一次提出问题,所以我确信我的格式很差。如果仍不清楚,请尽量让我知道我在哪里失去你。

编辑:memoise包能够完成任务。例如,如果我的数据抓取功能是data.grab(customer_no),并且需要与SQL接口,那么在我的应用程序之前,我包括

grabber<-memoise(data.grab)

然后我用抓取器替换了data.grab的所有实例。如果我使用我之前使用的相同客户,它会使用上次使用这些参数运行函数的结果,而不是再次与SQL连接。

0 个答案:

没有答案