An overview of simple examples

The Shiny package includes several examples. The runExample() command, with no arguments passed, displays the available examples as follows:

> runExample()
Valid examples are "01_hello", "02_text", "03_reactivity", "04_mpg", "05_sliders", "06_tabsets", "07_widgets", "08_html", "09_upload", "10_download", "11_timer"

To see the examples running, the name of the example must be passed as shown here:

> runExample("01_hello")

The examples are displayed in a separate window that includes the application and both server.R and UI.R, which generate them. The scripts are very well described so that it is easy to understand what each piece of code does:

An overview of simple examples

Some additional examples will be found in the following sections. The scripts for this application are available at Packt Publishing's website, where you can download all the examples in this book. To run it you have to either execute runApp("folder path"), pointing at the application's directory or, in the newest versions of RStudio, the program enables a button in the Shiny-related scripts to easily run the application.

An overview of simple examples

Example 1 – a general example of how render-like functions work

This first example consists of a very basic application where a number is passed, and a plot with the 1/x series, where x are the numbers between 1 and the passed number, is displayed. The following is the code for UI.R:

library(shiny)

# Starting line
shinyUI(fluidPage(
  
  # Application title
  titlePanel("Example 1"),
  
  sidebarLayout(
  
  # Sidebar with a numeric input
    sidebarPanel(
      numericInput("number",
                  "Insert a number:",
                  value = 30,
                  min = 1,
                  max = 50)
    ),
    
    
  #The plot created in server.R is displayed
    mainPanel(
      plotOutput("plot")
    )
  )
))

The following is the code for the server.R file:

library(shiny)

#Starting line of server.R
shinyServer(function(input, output) {

  #Plot generation
  output$plot <- renderPlot({
    plot(1/1:input$number)
  })

})

Keeping in mind the preceding diagram (in the An introduction to server.R and UI.R section), the logic applied to this example would be as follows:

  1. The user inserts a number, and the number is stored in input$number. All the functions that draw widgets to pass inputs in UI.R have id as their first argument. Basically, they generate a JavaScript form with the id passed. They can be accessed afterwards by input$(id).
  2. The input is passed to server.R.
  3. Due to its reactivity nature, renderPlot() in server.R is re-executed whenever a change in an input occurs.
  4. The object created by renderPlot() is saved within the output list with the output$(object_name) form. This special object naming is necessary to be able to display the output in UI.R. Of course, when using render functions, output elements must match the type of the object that is being created. For example, returning a text in renderPlot() will not display any result in the application.
  5. As there is a plotOutput() statement that calls the object generated in step 4, the Shiny framework passes that corresponding output to the browser.
  6. Due to the specifications in UI.R, the object generated in step 4 is displayed. It is important to keep in mind that the displaying function (in this case, plotOutput()) must be compatible with the object that has to be displayed, that is, if the output object is of the plot type, it can only be called successfully by plotOutput(). If another function is selected, probably outputs that are not desired or no output will be displayed.

Usually, reactive objects are enclosed by both parentheses and braces. The braces in R denote an expression. An expression is basically a piece of code where even objects can be created. In this case, the objects created are only accessible inside the function they are in (in this case, renderPlot()). Back to the example, renderPlot() could also be written as follows:

renderPlot({
  numbers.to.plot <- 1/1:input$number
  plot(numbers.to.plot)
})

The numbers.to.plot object in this case is not accessible outside this call of renderPlot(). Although in this example the use of an intermediate object is absolutely trivial, it can be very useful if more complex scripts are required.

Example 2 – using reactive objects

As it was previously explained, R provides the possibility of creating intermediate reactive objects that can be used by other reactive functions, including those that effectively produce outputs. This is how UI.R looks like for the second situation explained in the The concept of reactivity section:

library(shiny)

# Starting line
shinyUI(fluidPage(
  
  # Application title
  titlePanel("Example 2"),
  
  # Sidebar with a numeric input
      textInput("text",
      "Insert a text:",
      value = "The cat is brown"),
    
  #The plot created in server.R is displayed
      textOutput("text.words"),
      textOutput("text.longest")
  )
)

The following is the server.R file:

library(shiny)

#initialization of server.R
shinyServer(function(input, output) {

    #Plot generation
  output$text.words <- renderText({
  words <- unlist(strsplit(input$text, split = " "))
    paste0("This phrase has ",length(words)," words in total")
    
  })
  
  output$text.longest <- renderText({
    words <- unlist(strsplit(input$text, split = " "))
    word.chars <- nchar(words)
    max.len <- max(word.chars)
    longest.word <- words[which.max(word.chars)]
    
    paste0(longest.word, " is the longest word and has ",max.len," characters")
    
  })
  
})

As it can be seen, the unlist(strsplit(input$text, split = " ")) expression is repeated. In this case, as there is not much processing required, an execution time difference cannot be practically appreciated. However, when it comes to larger amounts of data, doing the same process twice can be a real waste of resources. In order to avoid this, a reactive object can be created, which will then be used by both the render() functions. In this case, server.R would be as follows:

library(shiny)

#initialization of server.R
shinyServer(function(input, output) {

  words <- reactive(unlist(strsplit(input$text, split = " ")))
  
  #Plot generation
  output$text.words <- renderText(
    paste0("This phrase has ",length(words())," words in total")
    
  )
  
  output$text.longest <- renderText({
    word.chars <- nchar(words())
    max.len <- max(word.chars)
    longest.word <- words()[which.max(word.chars)]
    
    paste0(longest.word, " is the longest word and has ",max.len," characters")
    
  })
  
})

The repeated structure is called only once in a separate reactive expression and stored in the iris.sset object. As it is actually a function, the call of this object shall be done with the inclusion of parentheses. In this case, the subsetting is done only once and then used in both the render functions.

Example 3 – Loading data outside reactive context

This example is based on the iris dataset. It basically displays a summary of the variables based on the species selected. For this case, it is wise to call the dataset prior to launching the application, and this can be done by loading the data before the initialization of the Shiny server in the server.R script. UI.R and would look as follows:

library(shiny)

    # Starting line
  shinyUI(fluidPage(
    
    # Application title
    titlePanel("Example 3"),
    
    sidebarLayout(
    
    # Sidebar
    sidebarPanel(
      #Species selection
      selectInput("species","Select a species:",
                  c("setosa","versicolor", "virginica"))),
    
    
    mainPanel(
      #The summary table created in server.R is displayed
      tableOutput("table")

    )
  )
  ))

The following would be server.R:

library(shiny)

data(iris)

#initialization of server.R
shinyServer(function(input, output) {

  #Table generation where the summary is displayed
  output$table <- renderTable(
    summary(subset(iris, Species == input$species)[,-5])
  )

})

Note

The fifth column of this dataset corresponds to the Species object. It has been taken out because, firstly, it is the subsetting condition (the nonselected species will have a frequency of 0) and secondly, the object type is not numeric (as the other variables are).

This is a good example of the usefulness of pre-loading processing. To produce an equivalent result without this, either renderTable() should include the call to the data or the data should be loaded in a reactive object. Both the options have a huge drawback that they imply inserting the same data load in a reactive process, that is, the same action will be repeated with no difference whenever an input changes.

The example with the data call in renderTable() would be as follows:

output$table <- renderTable({
  data(iris)
  summary(subset(iris, Species == input$species)[,-5])
})

Example 4 – using global.R

Looking at the same previous example, instead of hard coding the options in the species input widget, they could be taken directly from the Species variable of the dataset. To do this, the dataset must be loaded prior to the application load using global.R. This is how the different files would look like:

global.R will be a one-command file where only the dataset is loaded:

data(iris)

The following is the code for UI.R. Notice that the input options of species are not hard coded any more but are defined as the levels of the Species variable in the iris dataset:

library(shiny)

    # Starting line
  shinyUI(pageWithSidebar(
    
    # Application title
    titlePanel("Example 4"),
    
    # Sidebar
    sidebarPanel(
      #Species selection
      selectInput("species","Select a species:",
                  levels(iris$Species))),
    
    #The plot created in server.R is displayed
    mainPanel(
      #Table display
      tableOutput("table"),
      #Plot display
      plotOutput("plot")
    )
  )
  )

Finally, server.R differs from the previous example only in the fact that there is no need to load the data prior to initializing shinyServer():

library(shiny)

#initialization of server.R
shinyServer(function(input, output) {
  
  iris.sset <- reactive({subset(iris, Species == input$species)[,-5]})
  
  #Table generation where the summary is displayed
  output$table <- renderTable({
    summary(iris.sset())
  })
  
  #Plot generation where the summary is displayed
  output$plot <- renderPlot({
    plot(iris.sset())
  })
  
})

The changes made in this example with respect to the previous one are only from the back end. From the end user's point of view, both applications will be identical.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset