简体   繁体   中英

How do I break a R shiny app into modules?

So in one of my previous question I had an issue on how to restore bookmark and run the model. This is just a reproducible example but as an app, I would like to modularize it as the size of the app keeps on increasing. I have the code below. In module 1 I want to call to render the datatable and call module 2 when the user clicks on the bookmark.As of now I have the code in module 1 which isnt working . The code for module 2 is in the server section. How can I modularize this app.

" Use case for a shiny app where the users can enter some value and when clicked on run it would run a model and show the values in the table. Now when I click on bookmark it captures the input values. And when I click on the restore bookmark it does populate the input values. What I want to do is after it restores the input values it should also run the model again and populate the values in the table. In short restore bookmark should populate the values and click on the run button to run the model. "

library(shiny)
library(RSQLite)
library(data.table)
library(DT)
library(dplyr)

#### Module 1 renders the first table
opFunc <- function(input, output, session, modelRun,modelData,budget){

  output$x1 <- DT::renderDataTable({
    modelRun()

      datatable(
        df %>% mutate(Current  = as.numeric(Current)*(budget())), selection = 'none', editable = TRUE
      )

  })
}
  tableUI <- function(id) {
    ns <- NS(id)
    dataTableOutput(ns("x1"))
  }

#### ideally the second module for bookmarks

opBookmark <- function(){}

ui <- function(request) {
  fluidPage(
    tableUI("opfun"),
    column(12,
      column(3,tags$div(title="forecast", numericInput("budget_input", label = ("Total Forecast"), value = 2))),
      column(2, textInput(inputId = "description", label = "Bookmark description", placeholder = "Data Summary")),
      column(2, bookmarkButton(id="bookmarkBtn"))),
      column(2, actionButton("opt_run", "Run")),
    tags$style(type='text/css', "#bookmarkBtn { width:100%; margin-top: 25px;}")
  )
}

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

  callModule( opFunc,"opfun",modelRun = reactive(input$opt_run),modelData = df,budget = reactive(input$budget_input))

  observeEvent(input$opt_run, {
    cat('HJE')
  })

  observeEvent(input$bookmarkBtn, {
    session$doBookmark()
  })
}
enableBookmarking(store = "url")
shinyApp(ui, server)

Unfortunately the code provided was not fully reproducible nor minimal, so I went ahead and tried stripping out what I thought was non essential and added the df from your other post. I also changed the module server name from opFunc to tableMod because it was confusing for me to try to work with a module that had different UI and server names :)

The following code works as expected.

library(shiny)
library(DT)
library(dplyr)

#### Module 1 renders the first table
tableMod <- function(input, output, session, modelRun,modelData,budget){

  output$x1 <- DT::renderDataTable({
    modelRun()
    isolate(
      datatable(
        modelData %>% 
          mutate(Current  = as.numeric(Current)*(budget())),
        selection = 'none', editable = TRUE
      )
    )
  })
}
tableUI <- function(id) {
  ns <- NS(id)
  dataTableOutput(ns("x1"))
}

ui <- function(request) {
  fluidPage(
    tableUI("opfun"),
    numericInput("budget_input", "Total Forecast", value = 2),
    textInput(inputId = "description", "Bookmark description"),
    bookmarkButton(id="bookmarkBtn"),
    actionButton("opt_run", "Run")
  )
}

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

  df <- data.frame(Channel = c("A", "B","C"),
                   Current = c(2000, 3000, 4000),
                   Modified = c(2500, 3500,3000),
                   New_Membership = c(450, 650,700),
                   stringsAsFactors = FALSE)

  callModule( tableMod,"opfun",
              modelRun = reactive(input$opt_run),
              modelData = df,
              budget = reactive(input$budget_input))

  observeEvent(input$opt_run, {
    cat('HJE')
  })

  setBookmarkExclude("bookmarkBtn")
  observeEvent(input$bookmarkBtn, {
    session$doBookmark()
  })
}

shinyApp(ui, server, enableBookmarking = "url")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM