Developing a R Tutorial shiny dashboard app

[This article was first published on DataScience+, 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.

Through this post, I would like to describe a R Tutorial Shiny app that I recently developed. You can access the app here. (Please open the app on Chrome as some of the features may not work on IE. The app also includes a “ReadMe” introduction which provides a quick overview on how to use the app)

The App provides a set of most commonly performed data manipulation tasks & use cases and the R code/syntax for these use cases, in a structured and easily navigable format. For people just starting off with R, this will hopefully be a useful tool to quickly figure out the code and syntax for their routine data analysis task.

In this post, I would not be getting into the basics of how to develop a Shiny app since it’s fairly well documented elsewhere, including an article in DataScience+. What I will be doing however, is to focus on how this Tutorial app was developed specifically emphasizing on some of it’s key components and features.

High Level App Overview

The basic structure of the app is fairly straight forward. For each topic a separate dataframe is created (I initially wrote the content in an excel file, which I then imported as a dataframe in R). Individual topic datasets are then included in a list object.

The relevant R code for this is:

tutorial_set <- list(basic_operations = basic_operations,dplyr_tutorial = dplyr_tutorial,
                       loops_tutorial = loops_tutorial,model_tutorial = model_tutorial)

Depending on the user selection on the “Choose Topic” dropdown box, the relevant dataframe is extracted from the list object, with the following code:

selected_topic <- tutorial_set[[input$topic_select]]
# where topic_select is the inputId of the dropdown box with values similar to topic dataset names

Each dataset incorporates the relevant set of tasks, associated use cases and the underlying code and comments.

Enhance the app’s visual appeal using shinydashboard package

If you like shiny, you would love it even more once you start using the shinydashboard package. This package which is built on top of Shiny can help you design visually stunning apps & dashboard. The tutorial app was not really meant to be a visual dashboard rather the emphasis was on functionality – Hence I haven’t explored all the various themes, layouts, widgets etc. that this package provides. However, you can read an excellent overview of this package in R Studio’s posts here.) Also if you are familiar with Shiny, picking up shinydashbaord should be a cakewalk. All that is required are some minor modifications to ui side of your code and then you are ready to go!

Interactive and dynamic datatables using the DT package

Rendering a dataset as an output is a fairly standard requirement, while building an app. I have been using the default shiny functions to render a datatable, till i came across the DT package. The package is basically a R interface to the Java script Data Table library and you can read more about it here. Rendering datatables using the DT package can help provide a whole new level of interactivity to your app.

Datatables rendered using this package, not only looks better but provides ways to capture user actions as they interact with the table. You can then program specific tasks that can be triggered, basis these user actions.

There is a whole range of different functionalities that DT offers, but for the purpose of the tutorial app, I only needed to know which row the user clicks on (on the “use case” dataset). This can be done quite easily using the following code:

selected_index <- input$use_cases_row_last_clicked
# where use_cases is the inputId of the use case datatable and row_last_clicked returns the index of the selected row

Executing the underlying code and displaying the output

Once the index of the dataset row that the user clicks on is captured, we need to extract the relevant code from the tutorial data set (which is fairly straightforward) and then execute the code (which requires a few, relatively less often used functions). The code for this section is given below:

#code_out is the output_id of the "Code Output" box on the app
output$code_out <- DT::renderDataTable({
     
    # Extract the formula from the dataset of the selected topic; the Col name is titled "formula"
    formula <- as.character(selected_topic[selected_index,"formula"])
    
    # parse parses the formula string as an expression which is then evaluated using eval
    # by default, parse expects the input to be in a file format, so text = form specifies that the input is text
    code_output <- eval(parse(text = form))

     
   # code output is then displayed as a datatable
   # The prefix "DT::" specifies that datatable function in DT package should be considered rather than the deprecated Shiny versions
   # selection = "single" specifies that user can select only 1 row at a time
   # In options; scroolX = TRUE implies that scroll bar should be displayed and rownames = FALSE hides the rownames from displayed output
   DT::datatable(data = code_output, selection = 'single',
                      options = list(scrollX = TRUE, rownames= FALSE))

      })

Rendering output using R Markdown

Once the index of the user selected row is extracted, and the underlying code is executed, the final step is to render the code and comments as a html output (The output is displayed in the “Code and Comments” box of the app).
We use the R Markdown package to render the “code & comments” output in a html format (Getting up to speed on R Markdown, if you are not familiar with it, should not be a challenge at all. You can read about R Markdown here and you can also refer to the cheat sheet which provides a quick overview of the various formatting tags that you may need)

For the purpose of the Tutorial app, this is what was needed – Generate a R Markdown document on the fly (depending on the user selection) and render the output in a html format, which can then be displayed on the app.

I had come across this app some time back, where the author had attempted something very similar, which I suitably modified for my tutorial app. Given below is the code for this section:

output$comment <- reactive({

        # Initialize a temp file
        t <- tempfile()
        selected_index <- as.numeric(input$use_cases_row_last_clicked)
 
        #Extract the comment from the selected topic dataset
        comment <- as.character(selected_topic[index,"comment"])

        #cat command concatenates the output and prints the output to the temp file created
        cat(comment, file = t)
       
        # Use the R Markdown package's render function to render the file as an html document
        t <- render(
          input         = t,
          output_format = 'html_document')
 
        ## read the results, delete the temp file and return the output
        comment_html <- readLines(t)
        unlink(sub('.html$', '*', t))
        paste(comment_html, collapse = 'n')

      })

Hope you found the post useful. If you have any queries or questions, please feel free to comment below.

    Related Post

    1. Strategies to Speedup R Code
    2. Sentiment analysis with machine learning in R
    3. Sentiment Analysis on Donald Trump using R and Tableau
    4. Google scholar scraping with rvest package
    5. PubMed search Shiny App using RISmed

    To leave a comment for the author, please follow the link and comment on their blog: DataScience+.

    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)