R闪亮:将reactValues()与data.table按引用分配一起使用 [英] R Shiny: Use reactiveValues() with data.table assign-by-reference

查看:44
本文介绍了R闪亮:将reactValues()与data.table按引用分配一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个闪亮的应用程序,其中多个反应性组件使用的函数计算结果相同。为了避免多次计算慢速函数,我可以使用 reactiveValues()在输入改变时重新计算该函数,并使结果可用于需要该函数的所有反应式组件。

I have a shiny app in which more than one reactive component uses the same result from a function that is slow to calculate. To avoid calculating the slow function more than once, I can use reactiveValues() to recalculate the function when its inputs change, and make the result available to all reactive components that require it.

但是,如果 reactiveValues 对象是 data.table ,然后使用:= 对其进行更新,shiny不会检测到更改,并且依赖该输出的输出也不会更新。

But, if the reactiveValues object is a data.table, and I update it using :=, shiny does not detect the change, and the outputs that rely on it do not get updated.

是否有任何方法可以使用data.table通过 reactiveValues 进行引用分配,或者是避免多次重新计算函数的另一种方式。

Is there any way to use data.table assign by reference either with reactiveValues or another way that avoids recalculating the function multiple times.

这是使用data.table按引用分配的可复制示例,其中 output $ result2 在以下情况下无法更新输入更改:

Here is a reproducible example using data.table assign-by-reference in which output$result2 fails to get updated when the input changes:

library(shiny)
library(data.table)
library(plotly)

ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput('x1', 'x1', min=0, max=2, value=1, step=0.1)
    ),
    mainPanel(
      plotlyOutput('result1'),
      verbatimTextOutput('result2')
    )
  )
)

server = function(input, output) {
  values <- reactiveValues()
  values$dt = data.table(v1 = 1:100, v2 = 1)

  slow.func = function(my.dt, x) {
    Sys.sleep(2)
    my.dt[, v2 := v1^x]
  }

  output$result1 = renderPlotly({
    values$dt = slow.func(values$dt, input$x1)
    plot_ly(values$dt) %>%
      add_lines(x = ~v1, y = ~v2)
  })      
  output$result2 = renderText({
    paste('Final value =', values$dt[.N, v2])
  })  
}
shinyApp(ui = ui, server = server)

为进行比较,这是使用data.frames标准分配的服务器功能的一个版本,确实可以按预期执行:

For comparison, here is a version of the server function using standard assignment of data.frames, which does perform as expected:

server = function(input, output) {
  values <- reactiveValues()
  values$dt = data.frame(v1 = 1:100, v2 = 1)

  slow.func = function(my.dt, x) {
    my.dt$v2 = my.dt$v1^x
    Sys.sleep(2)
    my.dt
  }

  output$result1 = renderPlotly({
    values$dt = slow.func(values$dt, input$x1)
    plot_ly(values$dt) %>%
      add_lines(x = ~v1, y = ~v2)
  })

  output$result2 = renderText({
    paste('Final value =', values$dt[100,]$v2)
  })  
}


推荐答案

假设您已定义了反应变量 table_updated ,因此每次执行慢速功能后,都可以将其递增一。其他值/图仅需遵守 table_updated

say you have defined a reactive variable table_updated so you can increment it by one each time the slow function is done. Other values/plots will only need to observe table_updated.

实际上 actionButton(请参见描述部分)做同样的事情,每次被单击时,其值都会增加1 。

Actually the actionButton(see description section) does the same thing, every time it gets clicked, its value is incremented by 1.

values <- reactiveValues(table_updated = 0)

slow.func = function(my.dt, x) {
  # do stuff
  values$table_updated <- values$table_updated + 1
}

output$result2 = renderText({
  values$table_updated
  paste('Final value =', values$dt[100,]$v2)
})  

这篇关于R闪亮:将reactValues()与data.table按引用分配一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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