SkillAgentSearch skills...

ShinyForEcologistsPart1

The first installment in a series of tutorials on the R Shiny framework

Install / Use

/learn @lsw5077/ShinyForEcologistsPart1
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Break This App: an Ecologist's Intro to Shiny

Hello and welcome to my first Shiny tutorial! Shiny is a framework for building interactive webpages using the R programming language. That means you can build powerful, customizable online tools to engage stakeholders in research communication using code and analyses you've already developed. In this tutorial, we'll learn how to build a Shiny app that shows temporal trends in Stellar sealion pup counts at a user-specified count site over time. If you'd prefer, you can also follow the tutorial using the ShinyForEcologistsPart1Tutorial.pdf, which can be found in the files above. This tutorial is meant to be an absolute basic intro to Shiny, so if you're already making Shiny apps it might be a bit too basic for you. If you're getting ready to build your first app, you're in the right place!

What do I need to make a Shiny app?

To get started, you'll need to have R and RStudio installed on your computer. The main coding prerequisite to building our sealion Shiny app is a basic understanding of the Tidyverse, a collection of R packages for data science. If you're new to the Tidyverse, I highly recommend the book R for Data Science, as well as the unofficial solutions manual. If you haven't used Tidyverse before, no worries! We'll go over each function we use in detail.

Ready to get started? Awesome! Let's open RStudio and make sure our required packages are installed if you don't have them already:


install.packages("tidyverse")
install.packages("shiny")

Getting started

To start a new shiny app, we would click File>New File>Shiny Web App, which would create a new app directory for us. Since we already have an app to work with, we'll instead download or clone this repository if you haven't already ("Download or clone" is just github speak for make a copy of this whole big folder on your computer!). We'll follow along with the "app.R file" in the SeaLionApp folder. When you open app.R, you'll see some code at the top that sets up our workspace. We put these lines outside the main app code because that way they're run and loaded into the environment just once, which reduces memory needs and run time. The first lines load our required package libraries, shiny and tidyverse:

library(shiny)
library(tidyverse)

In the next lines, we set up a custom ggplot theme, which we'll call "simpleTheme" so we can easily control the way our plot looks later:

simpleTheme <- theme_bw()+
    theme(panel.grid = element_blank(),
          axis.text = element_text(size = 20, color = "black"),
          axis.title = element_text(size = 24, color = "black"))

Now we're ready to load our data! The purpose of the app is to show trends in pup count data at different sites, so we need a list of sites. The following line loads an R data object containing a named list of the different count sites.

siteChoices <- read_rds("data/siteChoices.rds")

A Note on directories:

Sometimes directories can be a little tricky. You'll notice that the lines above use the path "data/" because a published Shiny app needs all the data to be in a folder called "data," which it automatically looks for in the app directory. However, if you download and modify this app, sometimes your paths may end up a little different. When you're running the app locally on your computer, it may be easier to use the commented out lines, which will help the app find the right paths to run on your computer:


# appPath <- dirname(rstudioapi::getSourceEditorContext()$path)
# siteChoices <- read_rds(paste0(appPath, "/data/siteChoices.rds"))

In that case, you could comment out

siteChoices <- read_rds("data/siteChoices.rds")

A Note on data preparation:

This app need two pieces of data: the main dataframe containing sites, dates, and mean pup counts, and a named list of sites for users to choose from. The focus of this tutorial is on getting an app off the ground, so I prepared the data ahead of time as .rds files. The .rds file format saves a single R object, like a list or dataframe, to file. This lets us restore the data object with traits like factor levels intact. I like .rds files because they let us do our data cleaning outside the scope of the app. This keeps our app code tidy and prevents us from wasting memory on processing data that will always need to be in the same format. BUT, you absolutely don't need to put your data in .rds files when you're making your own apps. You can use whatever data format (e.g., .csv's, .tif) you like! You can even type lists and other vectors right into the server or ui file. If you want to check out how I processed the data for this app, check out the dataProcessing.R file in this repo.

Basic app structure

Shiny apps are built in two pieces: the user interface and server. The user interface (ui), as the name suggests, creates all the elements that the user engages with. It contains all the static text and defines the appearence of interactive widgets like dropdowns and sliders, as well as page layouts. We define the user interface using the shinyUI function:


ui <- shinyUI()

The second fundamental element, the server, does all the background work to run the app. The "magic" of a Shiny app is reactivity, the feedback between server and ui: the user manipulates the interactive elements in the ui, then the server process user input and returns dynamic data and graphics elements. We define the server using the shinyServer() function:

server <- shinyServer(function(input, output, session){

})

Shiny assembles the server and ui into a cohesive unit using the shinyApp() function:

shinyApp(ui = ui, server = server)

Now that we have a handle on the basic structure of the app, let's dive into our sealion visualization! In each step, we will build on the previous step, until we build all the code we need to run the app.

UI

The first thing we need to decide for our new app's ui is how we want the text and visualization to be organized on the pages. Remember that Shiny apps make websites, so we have to plan out both the overall structure of the app's pages and how they relate, as well as the layout and organization of each page. The organization of the user interface code is consequently hierarchical, with each page's elements nested in a page layout, which is in turn nested in the whole app's layout.

We'll start out with an app layout that creates clickable tabs across the top, called a "navbarPage." I like navbarPage because it looks clean and professional, but there are lots of other options. We define this structure using the navbarPage(). We'll define the title of our navbarPage, which will show up in the top left, by typing it in quotes: "Stellar Sealion Pup Count Trends." So we've updated our empty shinyUI function from above to read:


ui <- shinyUI(navbarPage("Stellar Sealion Pup Count Trends"))

Now we need to choose the layout of our first page, which we initiate using the tabPanel() function and assign it a title that will appear in the navbar at the top of the page. We're going to use a sidebarLayout, which creates a shaded a side panel and a main panel. The side panel and main panel can both hold text, plots, maps, user input widgets, videos, and whatever else we need them to hold. The advantage of using a sidebarPanel() is that it draws the user's eye, so it's a great structure for communicating instructions and introductory material. Our sidepanel will hold a brief welcome for the user, made large using the h2() function, and a user input widget that prompts users to select a pup count site from a dropdown menu.

We define the dropdown menu using the selectInput() function, which allows users to select one site option. We give the drop-down widget a name, "site," which will pass to the server, and give it some human-friendly text to display to the reader: "Choose a site to display the time series of mean pup counts at that site.". We then specify the site choices to display to the reader. The choices come from the siteChoices object we loaded at the beginning. siteChoices is a named list, which means that it's a list of the factor levels of site, and the site names for those levels. The numeric indexing is important for helping R find the right site name from user input, and adding the site names creates a quick way for us to ensure that we can find both the correct level and its name with concise coding. For example, our selectInput statement sets the default selection to 1, the first index. The name of the first item in the list is "All," and it is a summary of all the sites. When the user selects an option from the selectInput() function, the selection is passed to server via input as the list index of the site chosen.

In addition, we'll add a main panel, using the mainPanel() function, to the right of our sidebarPanel to hold our dynamically updating graph of pup trends. Inside the mainPanel, we just have our sealion plot, which we print using the plotOutput() function and the name of the plot, "trendPlot" (more on that later). So altogether, our user interface now looks like:

ui <- shinyUI(navbarPage("Stellar Sealion Pup Count trends", # page title
              tabPanel("Graphing pup counts", # Tab panel title
               sidebarLayout( # give us a nice data selection si
View on GitHub
GitHub Stars8
CategoryDevelopment
Updated5y ago
Forks2

Languages

R

Security Score

55/100

Audited on Dec 31, 2020

No findings