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

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

问题描述

作为 修改 a反应值应该触发一个观察块,我进一步调查了这个问题并意识到这个问题可能源于我对 data.tables 的使用.data.table 是通过引用来修改的,这与 data.frame 不同,这使得它们使用起来更高效,但对 shiny 的反应性显然不可见.

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	')
            lReactiveValues$a[letters[ncol(isolate(lReactiveValues$a))]] = new
         }
      )

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

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

         if (counter > 0.5) {

            cat('
')

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

         }
      }
      )

   }
)

带有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	')
            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	'); 

         if (counter > 0.5) {

            cat('
')

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

         }
      }
      )

   }
)

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".该按钮应进一步触发观察块,提示打印一些包含字符串二"的文本.根据观察块中的 if 条件,可能会打印另一组包含三"的文本.在 data.frame 的 server.r 情况下,此行为在应用程序运行时一直存在.在 data.table 的 server.r 案例中,单击几下按钮会发生此行为,之后仅打印one"字符串,而不会打印two"和three".想一想,这种行为的翻转发生在第一次发现 if 条件为假之后.

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.

推荐答案

可以使用 [[ 或 $ 修改 data.table 并保存到响应式表达式中.如:

A data.table can be modified using [[ or $ and saved into the reactive expression. Such as:

dt <- reactiveVal(data.table(a=c(1,2),b=c(10,20))

在反应式表达式中,以下将 b 的值从 10 更改为 100 并触发观察者

Within a reactive expression the following will change value of b from 10 to 100 and trigger an observer

observeEvent(dt(), { print(dt()) })
observeEvent(input$mybutton, { 
  x <- dt()
  x[a==1][["b"]] <- 100
  dt(x)
})

使用您的示例代码和 reactiveValues

Following using your example code and reactiveValues

server <- 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	')
        
        lRV <- lReactiveValues$a
        lRV[["newcol"]] <- new
        lReactiveValues$a <- lRV
        
        cat(ncol(lReactiveValues$a))
      }
    )
    
    voidB = observe(priority = 50,{
      # input$buttonCommit
      cat(ncol(lReactiveValues$a))
      
      counter = runif(1)
      cat(counter,' two	'); 
      
      if (counter > 0.5) {
        
        cat('
')
        
        cat(ncol(lReactiveValues$a),' three
')
        
      }
    }
    )
    
  }
)

ui <- 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%;'
    
  )
)

shinyApp(ui,server)

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

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