MarkeD MarkeD - 2 months ago 28
R Question

Shiny Module that calls a reactive data set in parent Shiny server

I'm looking to port some older Shiny apps to use Shiny Modules, but running into trouble trying to port over my reactive expressions.

According to the documentation:


The goal is not to prevent modules from interacting with their
containing apps, but rather, to make these interactions explicit. If a
module needs to use a reactive expression, take the reactive
expression as a function parameter.


I have existing reactive expressions that import data from APIs etc. that I would like to pass in, but can't seem to find the syntax. If I modify the given Shiny module example below I can get to the same problem.

Could anyone modify the below so that you can pass in the
car_data()
reactive data into the module? I've tried just about every combination of
isolate
and
car_data/car_data()
I can think of and am stumped :)

I would prefer to not need to call the data within the module itself, as in my case I'm trying to generalise an ETL function applicable to lots of datasets.

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)

Answer

Drop the parens after car_data:

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

The module seems to want "unresolved" reactives. The parentheses "resolves" them.

Comments