澄清一起使用observeEvent和eventReactive

时间:2017-05-25 17:27:31

标签: r shiny

我对反应性感到困惑,我希望你们其中一个人可以提供帮助。

当我在代码中使用eventReactive时,我包含了一个涉及变量rpcMatrix的计算,但不会返回。 (相反,另一个变量DF_new会被返回。)我承认这是一种草率的做事方式,但我认为没有理由不这样做。

现在,变量RPCobserveEvent函数中定义。虽然RPC不是被动的,但我认为其值在observeEvent函数中会根据wb被动变量的states()更改而发生变化。当RPC发生变化时,我希望eventReactive函数会导致rpcMatrixfor循环中发生变化。

如果两个变量都在rpcMatrix中,RPC会根据eventReactive的变化进行更改吗?

我之所以避免使用reactive关键字,是因为在使用wb命令分配loadWorkbook时遇到了麻烦。 非常感谢你的帮助。我希望我明白我的问题。

observeEvent(input$submit,{
   #NEXT 2 LINE ARE PERTINENT TO QUESTION: 

   wb <<- loadWorkbook(file =file.path(src,"www","State_Vectors",states()))
...
  RPC<<-read.xlsx(wb,sheet=1,startRow=1,cols=11)
})

data = eventReactive(input$submit,{
       ...
          DF_new<<- hot_to_r(input$tbl)

          *NEXT 2 LINES ARE PERTINENT TO QUESTION:
       rpcMatrix<<-as.data.frame(matrix(0, nrow= dim(as.matrix(category))[1], ncol =dim(as.matrix(category))[1]))
      for(i in 1:dim(category)[1]) #NTP
      {
        for(j in 1:dim(category)[1])
        {
          rpcMatrix[i,j]<<-as.matrix(RPC[i,1])
      }
      }
          DF_new<<-DF_new[,-c(1,2,6)] 
        }
       return(DF_new) 
        })

1 个答案:

答案 0 :(得分:0)

不能可靠地运作。这是有问题的,因为它需要在同一input$submit上触发的两个被动语句的特定执行顺序。虽然您可以设置一些优先级值,从而使其更频繁地工作,但优先级功能不可靠,并且非常不鼓励使用它。

但是这个&#34;执行顺序&#34;问题正是反应堆旨在解决的问题。我建议你考虑使用reactiveValues

它们有两个主要特征:

  • 反应性调用的长寿正如您现在可能已经意识到的那样,反应函数有自己的环境/范围,并且您在那里创建的变量不会存在。一种解决方法是使用<<-语句,但这是一个&#34;全局变量&#34;在R的功能世界中应该避免这种方法。它有很多问题。另一个reactiveValues可用于您在Shiny程序中创建的所有反应范围。它们正是您所需要的,以避免必须使用<<-语句来保护您的被动代码的调用状态。

  • 反应效应作为额外的好处,它们会产生input$..变量所具有的相同类型的反应效果。这是一个非常强大的功能,意味着您可以创建一个完整的计算反应网 - 您可以在此处使用它。

所以我可能会推荐这样的方法:

rv <- reactiveValues(wb=NULL,RPC=NULL)

observeEvent(input$submit,{

   rv$wb <- loadWorkbook(file =file.path(src,"www","State_Vectors",states()))
   ...
   rv$RPC<-read.xlsx(rv$wb,sheet=1,startRow=1,cols=11)
})

data <- reactive({
      ...
      DF_new<- isolate(hot_to_r(input$tbl))

      rpcMatrix<-as.data.frame(matrix(0, nrow= dim(as.matrix(category))[1], 
                                         ncol =dim(as.matrix(category))[1]))
      for(i in 1:dim(category)[1]) #NTP
      {
        for(j in 1:dim(category)[1])
        {
          rpcMatrix[i,j]<-as.matrix(rv$RPC[i,1])
      }
    }
    DF_new<-DF_new[,-c(1,2,6)] 
  }
  return(DF_new) 
})

它的工作原理如下:

  1. 我们设置了一个名为reactiveValues的{​​{1}}列表来保留rv
  2. 现在,当RPC被触发时,工作簿将被加载,input$submit将会更改。
  3. 然后,当rv$RPC更改时,将触发被动data(如果用作data())。
  4. 执行令是保证的,这就是我认为你想要的。

    其他说明:

    • 我认为你不希望在rv$RPC更改时触发它,所以我把它放在input$tbl中。这就是isolate对待它的方式。
    • 我认为您从头开始计算eventReactiveDF_new,因此您不需要使用rpcMatrix运算符(正如HubertL在评论)。
    • 例外情况是,如果您想在其他地方使用<<-DF_new,例如显示它们以进行调试或其他事情。然后,您可以将其放在rpcMatrix中,然后在rv reactiveStatementsrv$DF_new中解决。

    • 我不确定rv$rpcMatrix列表中是否需要wb,您可能只需要reactiveValues本地需要它。

    通常也会observeEvent注意

    • 在反应范围之外,可以使用reactiveValues
    • 访问reactiveValues中的元素
    • 它是被动的元素(如上面的isolate(rv$NPC)),而不是根(即上面的rv$NPC不是被动的)
    • 实际上并不需要使用NULL初始化rv语句中的变量,您可以为它们提供其他初始值,甚至可以将它们保留,并在它们用于分配时创建它们。但是当我看到我的程序列在那里时,我发现它有助于我理解我的程序。