1 Introduction

Calculators and computers can be used by teachers to project functions onto a screen as if they were illustrated by skilled artists. Reactive programming can be used as well to aid a teacher’s ability to illustrate changes to functions. Readers are most likely familiar with the type of reactive programming used in spreadsheets where the value of a cell a is determined with a formula of the form a = b + c, such that changes to either b or c or both b and c automatically update the value in a. This article provides an overview of how the R package shiny (Chang, Cheng, Allaire, Xie, & McPherson, 2017) can be used to create a reactive application that shades the area between two points of a normal distribution with parameters \(\mu\) and \(\sigma\), one way of publishing the application on the internet, and links to online references where the reader can learn more about reactive programming and Shiny apps. This article starts by expanding the code given in the R graphics cookbook, written by Chang (2013), for shading the area under a curve using the R package ggplot2 (Wickham & Chang, 2016). Next, a brief discussion follows of how to make the code reactive to user inputs using the shiny package. Finally, the article ends with how to host a Shiny app on the shinyapps server.

2 Prerequisites

To reproduce the graphs in this article, users should have R (R Core Team, 2017) and optionally an integrated development editor (IDE) such as RStudio installed on their computers. Both R (https://cran.r-project.org/) and RStudio (https://www.rstudio.com/) are freely available for installation on Windows, Mac OS X, and Linux variants. This article assumes the reader has some familiarity with R. If the reader needs an introduction to or a refresher on using R, free interactive tutorials are offered by Data Camp (https://www.datacamp.com/).

3 Writing the function

The function areabetweenN() shown below is a modification and compilation of several functions described starting on page 272 of the R graphics cookbook written by Chang (2013).

areabetweenN <- function(mu = 0, sigma = 1, min = -1, max = 1, ALPHA = 0.4, FILL = "PURPLE"){
  abN <- round(pnorm(max, mu, sigma) - pnorm(min, mu, sigma), 4) 
  p <- ggplot(data.frame(x=c(mu - 3.5*sigma, mu + 3.5*sigma)), aes(x = x)) 
  limitRange <- function(min = min, max = max) {
    function(x) {
      y <- dnorm(x, mu, sigma)
      y[x < min | x > max] <- NA
      return(y)
    }
  }
  SDB <- -3:3*sigma + mu
  p + stat_function(fun = dnorm, args = list(mu, sigma)) +
    stat_function(fun = limitRange(min = min, max = max),
                  geom = "area", fill = FILL, alpha = ALPHA, n = 500) + 
    theme_bw(base_size = 8) + 
    labs(x = paste("X ~ N(", mu,",",sigma,")"), y = "", 
         title = paste("The area between", min, "and", max, "is", abN)) +
    scale_x_continuous(breaks=SDB)
}

To show the area between 80 and 120 of a \(N(\mu = 100, \sigma = 10)\) distribution, one should enter the code shown below at the R prompt; and the resulting graph will render as shown in Figure 3.1.

areabetweenN(mu = 100, sigma = 10, min = 80, max = 120)
Shaded area between 80 and 120 of a normal distribution with a mean of 100 and a standard deviation of 10

Figure 3.1: Shaded area between 80 and 120 of a normal distribution with a mean of 100 and a standard deviation of 10

4 Creating a Shiny App

The basic template for a Shiny app has three components: a user interface object, a server object, and the function shinyApp() that combines the user interface object and the server object into a reactive application known as a Shiny app. RStudio has excellent tutorials and documentation for creating Shiny apps available at http://shiny.rstudio.com/. In addition to the tutorials at http://shiny.rstudio.com/, the shiny-cheatsheet available from https://www.rstudio.com/wp-content/uploads/2016/01/shiny-cheatsheet.pdf is a great reference document. The basic template is shown below that creates a valid, albeit empty, web page. It is the responsibility of the programmer to define the user interface and to write valid code for the server object.

# Template for shiny app
library(shiny)

ui <- fluidPage()

server <- function(input, output){}

shinyApp(ui = ui, server = server)

The user interface determines the layout for reactive inputs, while the server object specifies how R will interact with the user inputs. The code below creates a reactive application the reader can use at https://alanarnholt.shinyapps.io/Normal_Area/.

# Normal Distribution Calculator shiny app code 
ui <- fluidPage(
  # Application title
  titlePanel("Area Between Two Values of A Normal Distribution"),
  sidebarLayout(
    sidebarPanel(
      numericInput(inputId = "MU", label = "Mean:", value = 0, min = -Inf, 
                   max = Inf),
      numericInput(inputId = "SIGMA", label = "Standard Deviation:", 
                   value = 1, min = 0.0000001, max = Inf),
      numericInput(inputId = "MIN", label = "Lower:", value = -2, min = -Inf, 
                   max = Inf),
      numericInput(inputId = "MAX", label = "Upper:", value = 2, min = -Inf, 
                   max = Inf),
      textInput(inputId = "COLOR", label = "Color:", value = "hotpink"),
      numericInput(inputId = "ALPHA", label = "Intensity:", value = 0.4, 
                   min = 0.05, max = 1)
    ),
    mainPanel(
      plotOutput("NG", height = "500px", width = "500px")
    )
  ))


server <- function(input, output){
  library(ggplot2)
  output$NG <- renderPlot({
    abN <- round(pnorm(input$MAX, input$MU, input$SIGMA) - 
                   pnorm(input$MIN, input$MU, input$SIGMA),4) 
    p <- ggplot(data.frame(x=c(input$MU - 3.5*input$SIGMA, input$MU + 3.5*input$SIGMA)), 
                aes(x = x)) 
    limitRange <- function(min = input$MIN, max = input$MAX) {
      function(x) {
        y <- dnorm(x, input$MU, input$SIGMA)
        y[x < input$MIN | x > input$MAX] <- NA
        return(y)
      }
    }
    SDB <- -3:3*input$SIGMA + input$MU
    p + stat_function(fun = dnorm, args = list(input$MU, input$SIGMA)) +
      stat_function(fun = limitRange(min = input$MIN, max = input$MAX),
                    geom = "area", fill = input$COLOR, alpha = input$ALPHA, 
                    n = 500) + 
      theme_bw(base_size = 18) + 
      labs(x = paste("X ~ N(", input$MU,",",input$SIGMA,")"), y = "", 
      title = paste("The area between", input$MIN, "and", input$MAX, "is", abN)) +
      scale_x_continuous(breaks=SDB)
  })
}
shinyApp(ui = ui, server = server)

A screen shot of the application is visible in Figure 4.1.

Screen shoot of the Normal Distribution Calculator from https://alanarnholt.shinyapps.io/Normal_Area/

Figure 4.1: Screen shoot of the Normal Distribution Calculator from https://alanarnholt.shinyapps.io/Normal_Area/

The “Normal Distribution Calculator shiny app code” should be saved in its own directory with the name app.R. In this example, the user interface is created with the function sidebarLayout() that creates a sidebar occupying 1/3 of the screen and a main area occupying 2/3 of the screen. The appearance of the sidebar is determined with the sidebarPanel() function. In this example, the sidebar has five numeric inputs and one text input. The output NG created from the renderPlot({}) function in the server object is shown in the main panel with the plotOutput() function. The code inside renderPlot({}) is the function areabetweenN() with the exception that all arguments to the function areabetweenN() are made reactive using the syntax input$par where par is an inputId defined in the user interface. To change the shading color, enter a valid R color name or a hexadecimal color such as #FF000 for red. To see all 657 R colors names, type colors() at the R prompt.

5 Publishing your Shiny App

To publish your own Shiny apps on the shinyapps server, you will need to create a free account at http://www.shinyapps.io/. Once your account is created, follow the directions at http://docs.rstudio.com/shinyapps.io/getting-started.html#deploying-applications to deploy your application on the shinyapps server.

References

Chang, W. (2013). R graphics cookbook: [Practical recipes for visualizing data] (1. ed). Beijing: O’Reilly.

Chang, W., Cheng, J., Allaire, J., Xie, Y., & McPherson, J. (2017). Shiny: Web application framework for r. Retrieved from https://CRAN.R-project.org/package=shiny

R Core Team. (2017). R: A language and environment for statistical computing. Vienna, Austria: R Foundation for Statistical Computing. Retrieved from https://www.R-project.org/

Wickham, H., & Chang, W. (2016). Ggplot2: Create elegant data visualisations using the grammar of graphics. Retrieved from https://CRAN.R-project.org/package=ggplot2