如何将Shiny应用程序中的响应式值发送到全局环境以供审核?

huangapple go评论126阅读模式
英文:

How to send reactive values from Shiny App into global environment for review?

问题

以下是翻译好的部分:

下面的示例代码使用模块结构从主服务器传递值到两个模块`mod1`和`mod2`,在这些模块中对值进行操作并在模块之间相互传递。这是为了学习目的。

我在主服务器中使用`common <- reactiveValues()`,然后在模块内部分配值给`common$xyz`,然后可以在所有模块中访问它。代码按预期工作:运行时,Shiny窗口顶部显示一个基本数据框`df`,用户使用滑块输入指定要与基本`df`相乘的值,结果呈现在第二个表中,第三个表将每个第二个表的值都加上10,并将其列A发送回第二个表以附加到第二个表的末尾,然后将第二个表的最后一列乘以100并发送回第三个表以附加到其末尾。这是为了练习在模块之间来回发送数据。

我的问题是:如何将完整的`common`反应式对象发送到全局环境进行测试和审查?在构建这个代码时,我需要完整地了解这个`common`对象的演变过程。

在下面的代码中,我尝试使用以下方式实现:`oe1 <- reactive({common})`和`observeEvent(oe1(),{common.R <<- oe1()})`在主服务器部分,但我只得到以下结果:

    > common.R
    <ReactiveValues> 
      Values:    colA_mod2, df, mod1_dat, mod2_table, svc 
      Readonly:  FALSE  

这并没有告诉我太多信息。我希望看到包含在其中的所有值和元素的整个`common`对象。我宁愿以我刚刚描述的方式检索对象,而不是在使用`print()`语句时在R Studio控制台中滚动查看,因为我正在努力构建的`common`对象将非常大。

代码:

    library(shiny)
    library(DT)
    
    mod1_ui &lt;- function(id) {
      ns &lt;- NS(id)
      DTOutput(ns(&quot;tbl&quot;))
    }
    
    mod1_server &lt;- function(id, common) {
      moduleServer(id, function(input, output, session) {
        new_dat &lt;- reactive({
          df &lt;- common$df
          svc &lt;- common$svc()
          df * as.numeric(svc)
        })
        
        observe({
          common$mod1_dat &lt;- new_dat()
          common$colA_mod2 &lt;- common$mod2_table$A
        })
        
        output$tbl &lt;- renderDT({
          dat &lt;- new_dat()
          dat$colA_mod2 &lt;- common$colA_mod2 
          dat
        })
      })
    }
    
    mod2_ui &lt;- function(id) {
      ns &lt;- NS(id)
      DTOutput(ns(&quot;tbl&quot;))
    }
    
    mod2_server &lt;- function(id, common) {
      moduleServer(id, function(input, output, session) {
        output$tbl &lt;- renderDT({
          mod1_dat &lt;- common$mod1_dat
          dat &lt;- data.frame(mod1_dat + 10) 
          if (!is.null(common$colA_mod2)) {
            dat$colA_mod2_mod1 &lt;- common$colA_mod2 * 100
          }
          common$mod2_table &lt;- dat
          dat
        })
      })
    }
    
    ui &lt;- fluidPage(
      mainPanel(
        DTOutput(&quot;table&quot;),
        sliderInput(&quot;svc&quot;, &quot;&quot;, min = 0, max = 10, value = 1),
        mod1_ui(&quot;mod1&quot;),
        mod2_ui(&quot;mod2&quot;)
      )
    )
    
    server &lt;- function(input, output, session) {
      common &lt;- reactiveValues(df = data.frame(A = 1:2, B = 3:4))
      output$table &lt;- renderDT({datatable(common$df)})
      common$svc &lt;- reactive(input$svc)
      mod1_server(&quot;mod1&quot;, common)
      mod2_server(&quot;mod2&quot;, common)
      
      oe1 &lt;- reactive({common})
      observeEvent(oe1(),{common.R &lt;&lt;- oe1()})
      
    }
    
    shinyApp(ui, server)
英文:

The below example code uses a module structure to pass values from the main server to two modules mod1 and mod2 where the values are manipulated and passed back and forth between the modules. This is for learning purposes.

I use common &lt;- reactiveValues() in the main server and then assign values to common$xyz inside the modules, which is then accessible inside all of the modules. The code works as intended: when running, the top of the Shiny window shows a base dataframe df, the user uses a slider input to specify the value to multiply the base df by with results rendered in the 2nd table, the 3rd table adds 10 to each of the second table's values and sends it's column A back to the 2nd table to be appended to the end of the 2nd table, and then the 2nd table's last column is multiplied by 100 and sent back to the 3rd table to be appended to its end. This is for practicing sending data back and forth between modules.

My question: how can I send the complete common reactive object to the global environment for testing and review purposes? As I build out this code I need to have a complete view into how this common object is evolving.

In the below code I tried this using: oe1 &lt;- reactive({common}) and observeEvent(oe1(),{common.R &lt;&lt;- oe1()}) in the main server section, but all I get back is:

&gt; common.R
&lt;ReactiveValues&gt; 
Values:    colA_mod2, df, mod1_dat, mod2_table, svc 
Readonly:  FALSE  

which doesn't tell me much. I would like to see the entire common object with all values and elements that are housed in it. I would rather retrieve the object in the manner I just described rather than seeing it scroll by the R Studio console when using a print() statement, because the common object I am working towards will be very large.

Code:

library(shiny)
library(DT)
mod1_ui &lt;- function(id) {
ns &lt;- NS(id)
DTOutput(ns(&quot;tbl&quot;))
}
mod1_server &lt;- function(id, common) {
moduleServer(id, function(input, output, session) {
new_dat &lt;- reactive({
df &lt;- common$df
svc &lt;- common$svc()
df * as.numeric(svc)
})
observe({
common$mod1_dat &lt;- new_dat()
common$colA_mod2 &lt;- common$mod2_table$A
})
output$tbl &lt;- renderDT({
dat &lt;- new_dat()
dat$colA_mod2 &lt;- common$colA_mod2 
dat
})
})
}
mod2_ui &lt;- function(id) {
ns &lt;- NS(id)
DTOutput(ns(&quot;tbl&quot;))
}
mod2_server &lt;- function(id, common) {
moduleServer(id, function(input, output, session) {
output$tbl &lt;- renderDT({
mod1_dat &lt;- common$mod1_dat
dat &lt;- data.frame(mod1_dat + 10) 
if (!is.null(common$colA_mod2)) {
dat$colA_mod2_mod1 &lt;- common$colA_mod2 * 100
}
common$mod2_table &lt;- dat
dat
})
})
}
ui &lt;- fluidPage(
mainPanel(
DTOutput(&quot;table&quot;),
sliderInput(&quot;svc&quot;, &quot;&quot;, min = 0, max = 10, value = 1),
mod1_ui(&quot;mod1&quot;),
mod2_ui(&quot;mod2&quot;)
)
)
server &lt;- function(input, output, session) {
common &lt;- reactiveValues(df = data.frame(A = 1:2, B = 3:4))
output$table &lt;- renderDT({datatable(common$df)})
common$svc &lt;- reactive(input$svc)
mod1_server(&quot;mod1&quot;, common)
mod2_server(&quot;mod2&quot;, common)
oe1 &lt;- reactive({common})
observeEvent(oe1(),{common.R &lt;&lt;- oe1()})
}
shinyApp(ui, server)

答案1

得分: 1

你尝试过使用 browser() 吗?如果没有的话,它的作用是在你在RStudio上运行Shiny应用程序时,在你放置browser()函数的地方暂停你的Shiny应用程序,然后让你访问当前环境中的控制台,该控制台位于你的Shiny应用程序正在运行的环境内,从而允许你直接检查你需要的对象。然后,你可以使用控制台上方的控件来恢复应用程序。我经常在reactive({})调用的开头放置browser(),以在绘图或进一步处理之前检查数据是否正确,或者使用输入值快速测试绘图。

英文:

Have you tried using browser()? If you haven't, what it does is that, when you run your Shiny app on RStudio, it pauses your Shiny app at the place you put the browser() function, then gives you access to the console inside the current environment in which your Shiny app is running, thus allowing you to directly check the objects you need. Then, you can resume the app using the controls above the console. I use this all the time by placing browser() at the beginning of reactive({}) calls to check if data is correct before plotting or further processing, or to quickly test plots using values from inputs.

huangapple
  • 本文由 发表于 2023年8月11日 03:14:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878722.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定