Exploring Distributions with {shiny} and {TidyDensity}

[This article was first published on Steve's Data Tips and Tricks, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Introduction

Shiny is an R package that allows you to build interactive web applications using R code. TidyDensity is an R package that provides a tidyverse-style interface for working with probability density functions. In this tutorial, we’ll use these two packages to build a Shiny app that allows users to interact with TidyDensity functions.

Example

Required Packages

Before we dive into the code, let’s go over the packages that we’ll be using in this app:

  • Shiny: As mentioned earlier, Shiny is an R package for building interactive web applications. It provides a variety of input controls and output elements that allow you to create user interfaces for your R code.

  • TidyDensity: TidyDensity is an R package that provides a tidyverse-style interface for working with probability density functions. It provides a set of functions for generating density functions, as well as a tidy_autoplot() function for creating visualizations.

  • tidyverse: Tidyverse is a collection of R packages designed for data science. It includes many popular packages such as ggplot2, dplyr, and tidyr. We’ll be using some functions from the tidyverse packages in our Shiny app.

  • DT: DT is an R package for creating interactive tables in RMarkdown documents, Shiny apps, and RStudio. We’ll be using the DT::datatable() function to create a table of output data in our app.

Load them up!

library(shiny)
library(DT)
library(tidyverse)
library(TidyDensity)

The UI Object

The UI object is the first argument of the shinyApp() function, and it defines the layout and appearance of the app. In our TidyDensity Shiny app, we’ll use a sidebar layout with two input controls and two output elements:

  • Select Function Input: A selectInput() control that allows users to select one of four TidyDensity functions: tidy_normal(), tidy_bernoulli(), tidy_beta(), and tidy_gamma().

  • Number of Simulations Input: A numericInput() control that allows users to specify the number of simulations to use in the TidyDensity function.

  • Sample Size Input: A numericInput() control that allows users to specify the sample size to use in the TidyDensity function.

  • Density Plot Output: A plotOutput() element that displays the density plot generated by tidy_autoplot().

  • Data Table Output: A dataTableOutput() element that displays the output data from the TidyDensity function.

Here’s the code for the UI object:

# Define UI
ui <- fluidPage(
  titlePanel("TidyDensity App"),
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "function",
                  label = "Select Function",
                  choices = c(
                    "tidy_normal", 
                    "tidy_bernoulli", 
                    "tidy_beta", 
                    "tidy_gamma"
                    )
                  ),
      numericInput(inputId = "num_sims",
                   label = "Number of simulations:",
                   value = 1,
                   min = 1,
                   max = 15),
      numericInput(inputId = "n",
                   label = "Sample size:",
                   value = 50,
                   min = 30,
                   max = 200)
    ),
    mainPanel(
      plotOutput("density_plot"),
      dataTableOutput("data_table")
    )
  )
)

The Server Object

The server object is the second argument of the shinyApp() function, and it defines the behavior and output of the app. In our TidyDensity Shiny app, the server object consists of two reactive expressions that generate the output elements based on the user inputs:

  • Data Reactive Expression: A reactive expression that generates the output data for the selected TidyDensity function based on the user inputs. We use match.fun() to convert the selected function name into an R function, and we pass the num_sims and n arguments from the input controls.

  • Density Plot Reactive Expression: A reactive expression that generates the density plot using tidy_autoplot() and the output data from the data reactive expression.

  • Data Table Output: We use DT::renderDataTable() to generate the data table output element based on the output data from the data reactive expression.

Here’s the code for the server object:

# Define server
server <- function(input, output) {
  
  # Create reactive data
  data <- reactive({
    # Call selected function with user input
    match.fun(input$function)(.num_sims = input$num_sims, .n = input$n)
  })
  
  # Create density plot
  output$density_plot <- renderPlot({
    # Call autoplot on reactive data
    p <- data() %>%
      tidy_autoplot()
    
    print(p)
  })
  
  # Create data table
  output$data_table <- DT::renderDataTable({
    # Return reactive data as a data table
    DT::datatable(data())
  })
  
}

Conclusion

In this tutorial, we used Shiny and TidyDensity to build an interactive web application that allows users to generate and visualize probability density functions. We learned how to use the selectInput() and numericInput() controls to allow users to specify the function and input parameters, and we used the plotOutput() and dataTableOutput() elements to display the output data and visualizations. We also used the reactive() function to create reactive expressions that automatically update the output elements based on the user inputs.

Most importantly, steal the code below and see what you can do with it!

library(shiny)
library(TidyDensity)
library(tidyverse)
library(DT)

# Define UI
ui <- fluidPage(
  titlePanel("TidyDensity App"),
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "functions",
                  label = "Select Function",
                  choices = c(
                    "tidy_normal", 
                    "tidy_bernoulli", 
                    "tidy_beta", 
                    "tidy_gamma"
                    )
                  ),
      numericInput(inputId = "num_sims",
                   label = "Number of simulations:",
                   value = 1,
                   min = 1,
                   max = 15),
      numericInput(inputId = "n",
                   label = "Sample size:",
                   value = 50,
                   min = 30,
                   max = 200)
    ),
    mainPanel(
      plotOutput("density_plot"),
      DT::dataTableOutput("data_table")
    )
  )
)

# Define server
server <- function(input, output) {
  
  # Create reactive data
  data <- reactive({
    # Call selected function with user input
    match.fun(input$functions)(.num_sims = input$num_sims, .n = input$n)
  })
  
  # Create density plot
  output$density_plot <- renderPlot({
    # Call autoplot on reactive data
    p <- data() |>
      tidy_autoplot()
    
    print(p)
  })
  
  # Create data table
  output$data_table <- DT::renderDataTable({
    # Return reactive data as a data table
    DT::datatable(data())
  })
  
}

# Run the app
shinyApp(ui = ui, server = server)

Voila!

To leave a comment for the author, please follow the link and comment on their blog: Steve's Data Tips and Tricks.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)