【问题标题】:Shiny: Getting (reactive) value from one module and passing it (as a reactive) to the callModule() function of another moduleShiny:从一个模块获取(反应式)值并将其(作为反应式)传递给另一个模块的 callModule() 函数
【发布时间】:2018-08-21 14:05:10
【问题描述】:

我要做的是将一个模块的值(封装在单选按钮中的选项)传递给另一个模块(接受选项并输出适合它的图表)。

我已经阅读了很多关于reactive() 和相关功能的信息,但仍然不知道如何正确使用该功能。在我看来,在声明某事时应该只需要调用reactive()一次——并且在整个使用过程中,某事将是反应性的。不过,情况似乎并非如此:

第一个模块的服务器功能:

# Return the choice user selects
sidePanel <- function(input, output, session) {
    selected_graph <- reactive({input$selected_graph})
    return(selected_graph)
}

第二个模块的服务器功能:

source('graph_choices.R')
mainPanel <- function(input, output, session, data, choice) {
        output$graph <- renderPlot({
            match.fun(reactive(choice))(data)
        })
}

graph_choices.R

choice_1 <- function(data) {
ggplot(data, aes(x=time, y=score)) + geom_point()

choice_2 <- function(data) {
ggplot(data, aes(x=eyelashes, y=score)) + geom_bar(stat='identity')

应用的服务器功能

server <- function(input, output, session) {
    file_name <- parseQueryString(isolate(session$clientData$url_search))
    sounds <- read.csv(paste('/srv/tmp_data/', file_name, sep=""), encoding='UTF-8')
    sounds_trimmed <- filter(sounds, score != -1)
    sidePanel <- callModule(sidePanel, "side")
    mainPanel <- callModule(mainPanel, "main", data=sounds_trimmed, choice=sidePanel())
}

所以,这里发生的情况是,第一个模块设置了带有两个单选按钮的侧面板——一个值为choice_1,一个值为choice_2。选择按钮后,return 位会吐出选择,并将其传递给第二个模块的服务器功能,该功能会吐出适当的图形。

我知道我的问题在于我对 reactive() 的使用,因为没有它,一切都“正常”(默认情况下选择第一个单选按钮,该选择被赋予第二个模块,并且适当的图表是显示。)但是,当我更改单选按钮时,没有任何反应。

对于将reactive 放在哪里,我有很多不同的排列,有时会得到不同的结果(一旦我用reactive() 封闭了第二个模块的输出,并且似乎发生了一些变化,但仍然没有更新)。

有人愿意帮助我吗?


根据this 问题,我还尝试了mainPanel &lt;- callModule(mainPanel, "main", data=sounds_trimmed, selected_graph=sidePanel)match.fun(selected_graph())(data);图表会打印出来(和以前一样,但在更改按钮时不会改变)。

【问题讨论】:

  • 我认为如果您提供一个可重现的示例(可以运行的 ui+server 的最小示例),您可能会有更多的运气。这里有很多信息,我很难理解。

标签: r shiny


【解决方案1】:

我不得不做出一些猜测,才能想出一个应用程序来说明如何解决您的问题。我将 mainPanel 重命名为 mP 以避免与 shiny::mainPanel 的名称勾结(可能无关紧要)。

关键是从selectInput 给出的选择映射到我使用的绘图功能

plotFun <- switch(choice(), choice_1 = choice_1, 
                  choice_2 = choice_2, stop("invalid choice()"))

我更喜欢使用显式映射,并且确实没有看到很多需要像 base::get 这样的函数的情况。

关于reactive 的使用:您要确保为/来自您的模块的所有“动态”输入和输出都是用shiny::reactive 创建的。然后你在通过后评估它们。还有其他方法可以传递“动态”对象,但鉴于我目前看到的有关模块的所有文档,这是推荐的方法。

library(shiny)

choice_1 <- function(data) 
  plot(factor("choice 1"))
choice_2 <- function(data) 
  plot(factor("choice 2"))

sidePanelUI <- function(id) {selectInput(NS(id, "selected_graph"), "graph", 
                                         c("choice_1", "choice_2"))}  
sidePanel <- function(input, output, session) {
  reactive({input$selected_graph})
}

mPUI <- function(id) {
  plotOutput(NS(id, "graph"))
}
mP <- function(input, output, session, data, choice) {
  output$graph <- renderPlot({
    plotFun <- switch(choice(), choice_1 = choice_1, 
                      choice_2 = choice_2, stop("invalid choice()"))
    plotFun(data)
  })
}

ui <- fluidPage(
  sidePanelUI("side"),
  mPUI("main")
)

server <- function(input, output) {
  sidePanel <- callModule(sidePanel, "side")
  callModule(mP, "main", data = mtcars, choice = sidePanel)
}

shinyApp(ui, server)

【讨论】:

    猜你喜欢
    • 2018-03-22
    • 2020-03-23
    • 1970-01-01
    • 2018-12-18
    • 2017-08-19
    • 1970-01-01
    • 2019-07-18
    • 2016-01-15
    • 2018-03-16
    相关资源
    最近更新 更多