闪亮的反应性与data.tables失败 [英] Shiny Reactivity Fails with data.tables

查看:78
本文介绍了闪亮的反应性与data.tables失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为对的后续操作反应性值应触发一个观察块,我进一步调查了该问题,并意识到该问题可能源于我对 data.table s的使用。 data.table 是通过引用修改的,与 data.frame s不同,这使它们更有效地使用,但显然也不可见。

As a follow up to Modifying a reactive value should trigger an observe chunk, I investigated the issue further and realised that the issue probably stems from my usage of data.tables. data.tables are modified by reference unlike data.frames which makes them more efficient to use but also apparently invisible to shiny's reactivity.

在下面的示例中,按下提交按钮将触发 data.frame 的情况,但在 data.table 的情况下则不是。一种解决方法是将一个值链接到 data.table 的更改,这也有助于触发反应。

In the below example, pressing the commit button triggers the observe chunk in the data.frame case but not in the data.table case. A workaround could be to have a value linked to the changing of data.table which also helps trigger the reactivity.

shinyServer ( 

   function(input, output, session) {

      lReactiveValues = reactiveValues(a = data.frame(firstcol = runif(1)))

      voidaA = observeEvent(
         input$buttonCommit,
         {
            new = runif(1)
            cat(new,' one\t')
            lReactiveValues$a[letters[ncol(isolate(lReactiveValues$a))]] = new
         }
      )

      voidB = observe(priority = 50,{
         # input$buttonCommit
         cat(ncol(lReactiveValues$a))

         counter = runif(1)
         cat(counter,' two\t'); 

         if (counter > 0.5) {

            cat('\n')

            cat(ncol(lReactiveValues$a),' three\n')

         }
      }
      )

   }
)



with data.table



with data.table

shinyServer ( 

   function(input, output, session) {

      lReactiveValues = reactiveValues(a = data.table(firstcol = runif(1)))
      # lReactiveValues = reactiveValues(a = data.frame(firstcol = runif(1)))

      voidaA = observeEvent(
         input$buttonCommit,
         {
            new = runif(1)
            cat(new,' one\t')
            setnames(
               lReactiveValues$a[, newcol := new],
               'newcol',
               letters[ncol(isolate(lReactiveValues$a))]
            )
            cat(ncol(lReactiveValues$a))
         }
      )

      voidB = observe(priority = 50,{
         # input$buttonCommit
         cat(ncol(lReactiveValues$a))

         counter = runif(1)
         cat(counter,' two\t'); 

         if (counter > 0.5) {

            cat('\n')

            cat(ncol(lReactiveValues$a),' three\n')

         }
      }
      )

   }
)



ui.r



ui.r

dashboardPage(

   dashboardHeader(

      title = "Analytics"

   ),

   ## Sidebar content
   dashboardSidebar(
   menuItem("Analysis", tabName = "tabAnalysis", icon = icon("calculator"))
   ),

   ## Body content
   dashboardBody(
      tabItems(
         tabItem(
            tabName = "tabAnalysis",
            actionButton("buttonCommit", "Commit!")
         )
      )
      #, style='width: 100%; height: 100%;'

   )
)

代码功能的简短摘要-按下按钮,应在控制台上打印一些文本,其中包括字符串 one。该按钮应进一步触发观察块,提示打印一些包含字符串 two的文本。根据观察块中的if条件,可能会打印出另一组包括三的文本。在data.frame的server.r情况下,此行为一直持续到应用程序运行。在data.table的server.r情况下,单击按钮几次就会发生这种情况,此后仅打印一个字符串,而没有打印两个和三个。可以认为,这种行为转变是在首次发现if条件为false之后发生的。

Short summary of what the code does - Pressing button should print some text to the console which includes the string 'one'. The button should further trigger the observe chunk prompting the printing of some text containing the string 'two'. Depending on the if condition in the observe chunk, another set of text including 'three' might get printed. In the data.frame's server.r case this behaviour persists all the time the app runs. In the data.table's server.r case, this behaviour occurs for a few clicks of the button after which only the 'one' string is printed and the 'two' and 'three' aren't. This flip in behaviour, think, occurs after the if condition is found to be false for the first time.

推荐答案

一个hacky解决方案如果您担心内存:

A hacky solution if you are concerned about memory:

添加DTControl值:

Add A DTControl value:

lReactiveValues = reactiveValues(a = data.table(firstcol = runif(1)), DTControl = 0)

然后在您的引用更改后与以下内容配对:

Then pair that with the following after your reference change:

lReactiveValues$a[, newcol := new]
lReactiveValues$DTControl <- lReactiveValues$DTControl + 1

然后在您的观察函数中添加以下行:

Then add this line in your observe function:

lReactiveValues$DTControl

由于您的DTControl更新,因此触发了反应式功能。需要花点时间来确保始终将两者配对,但是它可以覆盖此参考问题,而不会增加任何内存。

Because your DTControl updates, the reactive function gets triggered. Takes a bit of diligence to make sure you are always pairing the two together, but it can override this reference issue without any memory load.

无论如何,应突出显示为闪亮的问题。

Regardless, this should be highlighted as an issue in shiny.

这篇关于闪亮的反应性与data.tables失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆