Search code examples
rshinyrefactoringr-markdownflexdashboard

How to refactor server part of Shiny code from Rmarkdown sections


I have the following fully running Shiny-dashboard App:

---
title: "Test"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    theme: bootstrap
    vertical_layout: scroll
---
```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
```

Basic 
===================================== 

Inputs_basic {.sidebar}
-------------------------------------

```{r io_processes}
 selectInput("mpg_thres", label = "MPG threshold",
              choices = c(10,20,30,40), selected = 10)
 selectInput("cyl_thres", label = "CYL threshold",
              choices = c(4,5,6,7,8), selected = 4)
```

Rows {data-height=500}
-------------------------------------


### Scatter Plot

```{r show_scattr}
mainPanel(

  renderPlot( {
     dat <- as.tibble(mtcars) %>%
            select(mpg, cyl) %>%
            filter(mpg > input$mpg_thres & cyl > input$cyl_thres)
     ggplot(dat, aes(mpg, cyl)) + 
       geom_point()

  })

)
```


Rows  {data-height=500}
-------------------------------------

###  Show verbatim
```{r show_verbatim}
mainPanel(

  renderPrint( {
     dat <- as.tibble(mtcars) %>%
            select(mpg, cyl) %>%
            filter(mpg > input$mpg_thres & cyl > input$cyl_thres)
     dat
  })

)
```

Notice that the following part of the code is redundant among two different Rmarkdown sections Scatter Plot and Show verbatim.

 dat <- as.tibble(mtcars) %>%
        select(mpg, cyl) %>%
        filter(mpg > input$mpg_thres & cyl > input$cyl_thres)

How can I factorize it?


For completeness the screen shot of the app is this:

enter image description here


Solution

  • Use a reactive data expression, change your output chunks to:

    ### Scatter Plot
    
    ```{r show_scattr}
    dat <- reactive( {
      as.tibble(mtcars) %>%
        select(mpg, cyl) %>%
        filter(mpg > input$mpg_thres & cyl > input$cyl_thres)
    } )
    
    mainPanel(
      renderPlot( {
         ggplot(dat(), aes(mpg, cyl)) + 
           geom_point()
      })
    )
    ```
    
    ###  Show verbatim
    ```{r show_verbatim}
    mainPanel(
      renderPrint( {
         dat()
      })
    )
    ```
    

    Note the use of reactive as well as calling dat as a function (dat()).

    reactive makes sure that each time the inputs are changed, dat is recalculated.