闪亮:从一个模块获取(反应式)值,并将其(作为反应式)传递给另一模块的callModule()函数

时间:2018-08-21 14:05:11

标签: r shiny

我想做的是将一个模块的值(封装在单选按钮中的选择)传递给另一个模块(该选择将其吐出并显示适合它的图形)。

我已经阅读了很多有关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 <- callModule(mainPanel, "main", data=sounds_trimmed, selected_graph=sidePanel)match.fun(selected_graph())(data)的尝试;图形会打印出来(和以前一样,但是在更改按钮时不会改变)。

1 个答案:

答案 0 :(得分:0)

我不得不做出一些猜测,才能开发出一个希望能说明如何解决问题的应用程序。我将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)