In this post, we will look at another example of shiny in action by developing an interactive plot with a download feature. We will use the mtcars dataset to examine the relationship between weight and miles per gallon by filtering by number of gears and miles per gallon range. The explanation is divided into two parts. Part 1 will explain the code for developing the user interface, and part 2 will focus on the server-side code. All code and a visual of the app will be shared after the explanation.
Part 1
We begin by loading the shiny and ggplot2 packages. shiny builds the app, and ggplot2 makes the scatterplot. Next, we create the object ui and use fluidPage() as this function creates the skeleton of our app.
Inside the fluidPage() function are all the functions for creating the ui. The first function you see provides a title and is the h1() function. The next three functions provide all the filters and tools for interaction. The sliderInput() function has a name of mpg and a label of MPG, and it creates a sliding filter based on mpg. We set this filter to have a minimum of 5 miles per gallon and a max of 30. The value argument sets a default initial range for our data. The select input filter allows us to select all gears or certain ones. The name and label of the selectInput are in the code.
The last part of Part 1 is focused on the outputs. The plotOutput() and tableOutput() functions output a plot and a table, respectively
Part 2
Part 2 involves the coding for the server side of the data. The server does the behind-the-scenes work to create the outputs based on the user inputs. There are four subsections to Part 2 as follows.
- Filtering the data
- Table output
- Downloading data output
- Plot output.
We begin by creating a function called server which has three arguments: input, output, and session. The first subsection is filtering the data, and we create a function called filtered_data. Inside this function, we use a reactive function and filter the data within the reactive function. We use the data mtcars and subset it based on the mpg filter in the ui object. We also create an if-then statement based on the gear filter in the ui object, which tells shiny that if the choice “All” is not selected, then filter the data based on the input for gear. We are using a reactive function, so it responds to user inputs dynamically.
The second subsection creates the output for the table. This object uses the renderTable() function and takes the results of filtered_data () from above.
Subsection three allows the user to download the data as the user filtered it. This is done by creating a filename, loading the filtered data, and using the write.csv() function to create the file.
The last subsection is for creating the plot. To do this, we add plot to the output and use the renderPlot() function. Inside this function, we use the filtered_data() function and create a scatterplot using ggplot(). The last step involves using the shinyApp() function to create the app. Below is the code followed by a short video of what the app can do.
#PART 1library(shiny)library(ggplot2)ui <- fluidPage( h1("App"), sliderInput(inputId = "mpg", label = "MPG", min = 5, max = 30, value = c(10, 20)), selectInput("gear", "Gear", choices = c("All", unique(mtcars$gear))), downloadButton(outputId = "download_data", label = "Download"), plotOutput("plot"), tableOutput("table"))server <- function(input, output) { # Create a reactive variable named "filtered_data" filtered_data <- reactive({ # Filter the data (copied from previous exercise) data <- mtcars data <- subset( data, mpg >>= input$mpg[1] & mpg <= input$mpg[2] ) if (input$gear != "All") { data <- subset( data, gear == input$gear ) } data }) output$table <- renderTable({ # Use the filtered_data variable to render the table output data <- filtered_data() data }) output$download_data <- downloadHandler( filename = "mtcars_data.csv", content = function(file) { # Use the filtered_data variable to create the data for # the downloaded file data <- filtered_data() write.csv(data, file, row.names = FALSE) } ) output$plot <- renderPlot({ # Use the filtered_data variable to create the data for # the plot data <- filtered_data() ggplot(data, aes(wt, mpg)) + geom_point() + scale_x_log10() })}shinyApp(ui, server)
Conclusion
This post provides another example of the power and flexibility of shiny. You can make amazing interactive dashboards with only a few lines of code.









































