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.
(The code for the app is available on my github account. I have also bundled the app into a package and published it on CRAN (titled “RtutoR”). You can install the package, if you wish to run this app locally.
UPDATE: An updated version of the RtutoR package is available now on CRAN. This updated version includes a plotting app which provides an automated interface for generating plots using ggplot2 package. I have blogged about it here)