将响应式数据集和函数从父应用传递到Shiny中的模块

时间:2018-07-10 09:49:45

标签: r function module shiny reactive

我正在努力将一个反应性数据集和功能传递给闪亮的模块。我在下面做了一个简单的说明:该应用程序仅打印每个cyl值的平均mpg。

library(shiny)

# Module 
textToolUI <- function(id){
  ns <- NS(id)
  textOutput(ns("text"))
} 

textTool <- function(input, output, session, value){
  output$text <- renderText({paste(value)})
}



# App
ui <- basicPage(
  selectInput("carbSelect", "Carburetor Selector", choices = c(1,2,3,4)),
  textToolUI("text1")
)

server <- function(input, output, session){
  data <- reactive(filter(mtcars, carb == input$carbSelect))
  myfunc <- function(x){return(mean(x))}

  callModule(textTool, "text1", value = myfunc(data$mpg))  # This throws up the "object of type closure not subsettable" error
                                                           # Using data()$mpg means it is not reactive
}

shinyApp(ui = ui, server = server) 

由于数据集和函数(myfunc)都需要位于模块外部这一事实而引起问题。在我的实际应用中,使用了多个不同的数据集和函数。

我认为这里的问题是函数是在反应性数据集之前评估的,因此我需要不同的工作流程,但我想不出合适的替代方法。

1 个答案:

答案 0 :(得分:0)

只需向模块传递一个反应性对象,而无需参数。

下面的示例将函数移至模块中,并在mean(mtcars)输出NA时将其转换为表而不是文本

library(shiny)

myfunc <- function(x){colMeans(x)}

myfunc2 <- function(x){colSums(x)}

# Module 
textToolUI <- function(id){
  ns <- NS(id)
  tableOutput(ns("text"))
} 

textTool <- function(input, output, session, value, f){

  output$text <- renderTable({
    req(value())
    paste(f(value()))
    })
}



# App
ui <- basicPage(
  selectInput("carbSelect", "Carburetor Selector", choices = c(1,2,3,4)),
  p("myfunc1 - colMeans"),
  textToolUI("text1"),
  p("myfunc2 - colSums"),
  textToolUI("text2")
)

server <- function(input, output, session){
  data <- reactive(dplyr::filter(mtcars, carb == input$carbSelect))

  callModule(textTool, "text1", value = data, f = myfunc)

  callModule(textTool, "text2", value = data, f = myfunc2)
  # Using data()$mpg means it is not reactive
}

shinyApp(ui = ui, server = server)