【问题标题】:Shiny Module that calls a reactive data set in parent Shiny server调用父 Shiny 服务器中的反应数据集的 Shiny 模块
【发布时间】:2016-08-10 06:50:51
【问题描述】:

我希望移植一些较旧的 Shiny 应用程序以使用 Shiny 模块,但在尝试移植我的反应式表达式时遇到了麻烦。

根据documentation

目标不是阻止模块与其交互 包含应用程序,而是使这些交互明确。如果一个 模块需要使用响应式表达式,取响应式 表达式作为函数参数。

我有现有的反应式表达式,可以从我想传入的 API 等导入数据,但似乎找不到语法。如果我修改下面给定的Shiny module example,我会遇到同样的问题。

任何人都可以修改以下内容,以便您可以将car_data() 反应数据传递到模块中吗?我已经尝试了isolatecar_data/car_data() 的几乎所有组合,我能想到并且很难过:)

我宁愿不需要在模块本身中调用数据,因为在我的例子中,我试图概括适用于大量数据集的 ETL 函数。

library(shiny)
library(ggplot2)

linkedScatterUI <- function(id) {
  ns <- NS(id)

  fluidRow(
    column(6, plotOutput(ns("plot1"), brush = ns("brush"))),
    column(6, plotOutput(ns("plot2"), brush = ns("brush")))
  )
}

linkedScatter <- function(input, output, session, data, left, right) {
  # Yields the data frame with an additional column "selected_"
  # that indicates whether that observation is brushed
  dataWithSelection <- reactive({
    brushedPoints(data(), input$brush, allRows = TRUE)
  })

  output$plot1 <- renderPlot({
    scatterPlot(dataWithSelection(), left())
  })

  output$plot2 <- renderPlot({
    scatterPlot(dataWithSelection(), right())
  })

  return(dataWithSelection)
}

scatterPlot <- function(data, cols) {
  ggplot(data, aes_string(x = cols[1], y = cols[2])) +
    geom_point(aes(color = selected_)) +
    scale_color_manual(values = c("black", "#66D65C"), guide = FALSE)
}

ui <- fixedPage(
  h2("Module example"),
  linkedScatterUI("scatters"),
  textOutput("summary")
)

server <- function(input, output, session) {

  ### My modification 
  ### making the reactive outside of module call
  car_data <- reactive({
    mpg
    })

  ## This doesn't work
  ## What is the syntax for being able to call car_data()?
  df <- callModule(linkedScatter, "scatters", car_data(),
                   left = reactive(c("cty", "hwy")),
                   right = reactive(c("drv", "hwy"))
  )

  output$summary <- renderText({
    sprintf("%d observation(s) selected", nrow(dplyr::filter(df(), selected_)))
  })
}

shinyApp(ui, server)

【问题讨论】:

  • 这可能会有所帮助:stackoverflow.com/a/36517069/4222792 为什么必须进行反应性外部模块调用?它不能是你的一些模块的输出吗?您的 dataImportApi 可能是一个模块?
  • 谢谢米凯尔。它的外部原因是它用于包中的通用模块,我想将任何反应数据帧传递给它,而不仅仅是一个特定的 API 调用。

标签: r module shiny


【解决方案1】:

在 car_data 之后删除括号:

df <- callModule(linkedScatter, "scatters", car_data,
                   left = reactive(c("cty", "hwy")),
                   right = reactive(c("drv", "hwy"))
  )

该模块似乎需要“未解决”的反应。括号“解决”它们。

【讨论】:

    【解决方案2】:

    如果您想传递不属于模块的输入,只需将其包裹在reactive() 周围,如tutorial 中所述。

    如果模块需要访问不属于模块的输入, 包含的应用程序应该传递包装在反应式中的输入值 表达式(即反应式(...)): callModule(myModule, "myModule1", reactive(input$checkbox1))

    更新: 正如另一个答案中正确说明的那样,Joe Cheng 传递反应式表达式的正确方法是不带括号 ()

    callModule(linkedScatter, "scatters", car_data)

    还有一个选择是模块化您的 API 输入函数,这样您就不需要在模块外部定义反应式表达式。可以从此answer 找到模块化输入的示例。 在您的代码下方有正确答案。

    library(shiny)
    library(ggplot2)
    
    linkedScatterUI <- function(id) {
      ns <- NS(id)
    
      fluidRow(
        column(6, plotOutput(ns("plot1"), brush = ns("brush"))),
        column(6, plotOutput(ns("plot2"), brush = ns("brush")))
      )
    }
    
    linkedScatter <- function(input, output, session, data, left, right) {
      # Yields the data frame with an additional column "selected_"
      # that indicates whether that observation is brushed
      dataWithSelection <- reactive({
        brushedPoints(data(), input$brush, allRows = TRUE)
      })
    
      output$plot1 <- renderPlot({
        scatterPlot(dataWithSelection(), left())
      })
    
      output$plot2 <- renderPlot({
        scatterPlot(dataWithSelection(), right())
      })
    
      return(dataWithSelection)
    }
    
    scatterPlot <- function(data, cols) {
      ggplot(data, aes_string(x = cols[1], y = cols[2])) +
        geom_point(aes(color = selected_)) +
        scale_color_manual(values = c("black", "#66D65C"), guide = FALSE)
    }
    
    ui <- fixedPage(
      h2("Module example"),
      linkedScatterUI("scatters"),
      textOutput("summary")
    )
    
    server <- function(input, output, session) {
    data(mpg)
      ### My modification 
      ### making the reactive outside of module call
      car_data <- reactive({
        mpg
        })
    
      ## Fix This doesn't work by reactive (var) no brackets()
      ## What is the syntax for being able to call car_data()?
      df <- callModule(linkedScatter, "scatters", reactive(car_data),
                       left = reactive(c("cty", "hwy")),
                       right = reactive(c("drv", "hwy"))
      )
    
      output$summary <- renderText({
        sprintf("%d observation(s) selected", nrow(dplyr::filter(df(), selected_)))
      })
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 谢谢,这行得通,但正如 Joe Cheng 自己确认的那样,接受的答案是“路”。
    • @MarkeD 哦,是的。是的,它必须是这样的。 car_data 已经是被动的。我也会修复这个答案。
    猜你喜欢
    • 2018-12-18
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 2019-12-02
    • 2014-04-14
    相关资源
    最近更新 更多