class: center, middle, inverse, title-slide # Shiny for R: Making your apps more efficient and more effective ## EcoDataScience Lunch Session ### Kat Millage ### UCSB - emLab ### 2021/02/16 --- class: center, middle # Why? ### To provide general tips and suggestions to help you get started with Shiny (efficiently) ### To demonstrate cool functionalities that will help make your Shiny apps more effective communication tools --- # Outline - The Basics: Brief review of essential Shiny functions and some tips to make your reactive programming more efficient; - Appearance & Organization (`shinydashboard` + more): Keeping things organized; - (gg)`plotly`: Making your (already awesome) `ggplot` figures more awesome; - `leaflet`: Interactive maps! --- class: inverse, center, middle # Section 1: The Basics --- # Getting started with Shiny Using the [RStudio IDE](https://www.rstudio.com/products/rstudio/) you can create a basic Shiny app from the menu `File -> New File -> Shiny Web App`. You will then be asked to name your app, determine whether the app should be built using a single file (**app.R**) or two files (**ui.R/server.R**), and select the directory where the app will live (if you're using Projects, it should be already be set to your project location). -- **Does the file format matter?** > Ultimately, no. They both yield the same outcome. -- **Why would I pick one over the other?** > Ease of code management (and debugging). *Unless the app is going to be limited to a single figure and 1 or 2 widgets, **the two file format is going to be easier to manage***. --- class: inverse, center, middle # The Basics ## Example: basic-app --- background-image: url(https://comic.browserling.com/extra-front-end-back-end.png) background-position: 50% 75% # `ui.R` / `server.R` --- # `ui.R` / `server.R` The `ui.R` file defines the user-interface (UI) for your app. This is the part of you see and interact with. > This file returns a call to the `shinyUI()` function. *In order for something to appear in your app, it needs to be defined somewhere within the `ui.R` file.* -- ***** The `server.R` file defines the server logic for your app. This is the place for all of the "behind the scenes" action. > This file returns a call to the `shinyServer()` function. *In order for your app to do anything interactive, those actions need to be defined somewhere within the `server.R` file.* --- # `ui.R` / `server.R` Great videos on the basics of reactive programming: - [Reactivity, Pt. 1](https://rstudio.com/resources/shiny-dev-con/reactivity-pt-1-joe-cheng/): Joe Cheng, Shiny Dev Con 2016 - [Reactivity, Pt. 2](https://rstudio.com/resources/shiny-dev-con/reactivity-pt-2/): Joe Cheng, Shiny Dev Con 2016 Other helpful resources: - [RStudio](https://shiny.rstudio.com/articles/basics.html) - [Mastering Shiny](https://mastering-shiny.org/) --- # **`ui.R`** / `server.R` You'll predominately use three types of functions to define your user-interface: - Structural UI functions (layout & containers); - Widgets (input functions); - Output functions. --- # **`ui.R`** / `server.R` ## Structural UI Functions -- The highest layer of UI construction is dictated by the behavior of the page. The basic `shiny` package includes three main page functions: `basicPage()`, `fixedPage()`, **`fluidPage()`** -- The second highest level of UI construction defines the layout of objects on the page. There are four layout functions in the basic `shiny` package: `verticalLayout()`, `flowLayout()`, `splitLayout()`, **`sidebarLayout()`** -- There are also a number of lower level UI construction functions. These create panels, rows, and columns within your specified layout. Some of these can be used within any layout function (e.g., `tabsetPanel()`, `wellPanel()`, `titlePanel()`, `conditionalPanel()`, `aboslutePanel()`, `column()`), while others are specific to a particular layout function (e.g., `sidebarPanel()`, `mainPanel()`, `inputPanel()`, `fluidRow()`). -- More info on the basic Shiny layouts can be found [here](https://shiny.rstudio.com/articles/layout-guide.html). --- # **`ui.R`** / `server.R` ## Widgets -- These are the functions that create the fun little buttons and sliders that your user gets to click on and drag. The values returned by these functions make up the `input` object that is passed to your `server.R` file. -- There are a lot of them. They are all defined as `[xxx]Input()`. The [Shiny Widget Gallery](https://shiny.rstudio.com/gallery/widget-gallery.html) does a nice job of displaying all of the basic widgets and the values they return. -- Each widget is assigned an `inputId` - this is how your widgets will be identified in the server logic. *Knowing the format of the value returned by your widgets is important!* --- # **`ui.R`** / `server.R` ## Output Functions -- These are the functions that define the outputs that should be visible in your app. Think of these as placeholders for the things you want to display. These can be plots, value, text, images, tables, or really anything you can define with HTML. The basic output functions are as follows: - `plotOutput()` - `textOutput()` - `uiOutput()` - `htmlOutput()` - `imageOutput()` - `tableOutput()` - `dataTableOutput()` -- Each output function is assigned an `outputId` - this is how your function knows which variable from the `output` object to include here. --- # **`ui.R`** / `server.R` ```r # ui.R shinyUI(fluidPage( titlePanel("Old Faithful Geyser Data"), sidebarLayout( sidebarPanel( sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30) ), mainPanel( plotOutput("distPlot") ) ) )) ``` --- # `ui.R` / **`server.R`** You'll predominately use four types of functions to define your server logic: - Reactive values; - Reactive expressions; - Observers; - Rendering functions. ** The key differences between these functions are their execution strategies (eager or lazy) and whether they yield a result or have a value ** --- # `ui.R` / **`server.R`** ## Reactive Values -- `reactiveValues()` This function returns an object for storing reactive values - think of this as a fancy `list()`. The "reactive" piece is that whenever a reactive value changes, any reactive expressions that depend on it are marked as "invalidated" and will automatically re-execute. --- # `ui.R` / **`server.R`** ## Reactive Expressions -- `reactive()` and `eventReactive()` These two functions create expressions whose results will change over time. Similar to the previous class, whenever the result of a reactive expression changes, any other reactive expressions that recently called it are marked as "invalidated". --- # `ui.R` / **`server.R`** ## Observers -- `observe()` and `observeEvent()` These two functions can read reactive values and call reactive expressions, and will automatically re-execute when their dependencies change. However, they do not yield a result, and therefore only useful for their side effects. --- # `ui.R` / **`server.R`** ## Rendering Functions -- `renderPlot()`, `renderText()`, `renderUI()`, `renderPrint()`, `renderImage()`, `renderTable()`, `renderDataTable()` These functions create reactive versions of their namesakes that are suitable for assigning to an `output` slot. They have corresponding output functions in the UI that are used to display those items. --- # `ui.R` / **`server.R`** .pull-left[ **Reactive Values** - Neither eager or lazy - Returns a value **Reactive Expressions** - Lazy - Returns a value ] .pull-right[ **Observers** - Eager - No value **Rendering Functions** - Lazy - Can be assigned to an `output` value ] --- # `ui.R` / **`server.R`** ```r # server.R shinyServer(function(input, output) { output$distPlot <- renderPlot({ x <- faithful[, 2] bins <- seq(min(x), max(x), length.out = input$bins + 1) hist(x, breaks = bins, col = 'darkgray', border = 'white') }) }) ``` --- class: center, middle # Example: 01-basics --- class: inverse, center, middle # Section 2: Appearance & Organization (`shinydashboard` + more) --- # Why? Let's face it - the basic `shiny` layouts are boring and they don't look very nice. They're great if you just want to build a quick Shiny app to explore some data or results, but they don't really cut it for most applications.<sup>1</sup> .footnote[ [1] Unless you want to learn `HTML`, `CSS`, and `JavaScript` ] -- Luckily, there are some nice packages that will make your Shiny apps look nicer and be easier to use without having to learn more coding languages. There are MANY packages out there for shiny, but I've found a lot of them to be underwhelming. However, I want to highlight the three that I find myself using in almost every app I make. - `shinydashboard` - `shinyjs` - `shinyWidgets` --- # `shinydashboard` As the name implies, this package is intended to allow you to turn your Shiny apps into dashboards. However, I've found the base `shinydashboard` layout to be functional for almost any context. The website for [`shinydashboard`](https://rstudio.github.io/shinydashboard/index.html) provides a nice guide if you're just getting started. The two main classes of functions from this package I want to highlight: - Structural UI functions (`dashboardPage()`, `dashboardHeader()`, `dashboardSidebar()`, `dashboardBody()`) - Boxes (`box()`, `tabBox()`, `infoBox()`/`infoBoxOutput()`, `valueBox`/`valueBoxOutput()`) --- # `shinyjs` This package was designed to allow users to easily implement common `JavaScript` operations in their Shiny apps without having to learn `JavaScript`. The website for [`shinyjs`](https://deanattali.com/shinyjs/) provides a nice guide if you're just getting started. Cool things `shinyjs` allows you to do: - Hide (or show) elements - Disable (or enable) inputs - Reset inputs back to their original values --- # `shinyWidgets` Who doesn't want more widget options!? There are other packages out there offering additional widgets for `shiny`, but (in my opinion), this one is the best. Definitely check out the gallery of [`shinyWidgets`](http://shinyapps.dreamrs.fr/shinyWidgets/) to see all of the widgets available with this package (and to see a good example of an app built using `shinydashboard`!). Some favorite widgets of mine: - `switchInput()` - `materialSwitch()` - `radioGroupButtons()` --- # Custom Stylesheets & More If you really want to change up the appearance of your Shiny app, you can use CSS to build custom stylesheets. [Rstudio](https://shiny.rstudio.com/articles/css.html) and [R-bloggers](https://www.r-bloggers.com/2019/08/how-to-use-css-to-style-your-r-shiny-projects/) have good articles on how to add custom CSS to your app. Another cool (but somewhat more advanced) package: - [`googlesheets`](https://cran.r-project.org/web/packages/googlesheets/vignettes/basic-usage.html): Allows you to embed Google Sheets into your apps. --- class: center, middle # Example: 02-layouts --- class: inverse, center, middle # Section 3: (gg)`plotly` --- # What is `plotly`? Plotly for R allows you to to make interactive web-based graphs via the open source JavaScript graphing library `plotly.js`. By default, Plotly's main plotting function `plot_ly()` behaves much like `base::plot()`. However, they've also created another function `ggplotly()` that integrates nicely with `ggplot2` to make your `ggplot()` figures interactive. There is some reference material for using the `plotly` package in R [here](https://plotly.com/r/), *but* documentation for `ggplotly()` specifically is more limited. --- # A simple `ggplotly()` figure ```r p <- ggplot(data = dat, aes(x = State, y = Rate, fill = Crime))+ geom_bar(stat = "identity")+ theme_bw()+coord_flip()+theme(legend.position = "none") ggplotly(p) ```
--- class: center, middle # Example: 03-ggplotly --- class: inverse, center, middle # Section 4: `leaflet` --- # What is `leaflet`? Leaflet is an open-source JavaScript library that makes mobile-friendly interactive maps. The R package makes it easy to integrate these maps in R, and they work particularly well embedded in R Markdown documents or in Shiny apps. Rstudio has created some great basic reference material for using the `leaflet` package in R - [Leaflet for R](https://rstudio.github.io/leaflet/) --- # A simple `leaflet` map ```r library(leaflet) leaflet() %>% addTiles() %>% setView(-119.848965, 34.413489, zoom = 15) %>% addMarkers(-119.84230, 34.41251, popup = "Marine Science") ```
--- class: center, middle # Example: 04-leaflet --- # Questions? ### Contact email: [kmillage@ucsb.edu](mailto:kmillage@ucsb.edu) GitHub: [kmillage](https://github.com/kmillage) ### Some of my Shiny apps! [SubsidyExplorer](http://www.subsidyexplorer.org/) [Nutricast](https://emlab-ucsb.shinyapps.io/nutricast/) [ACP Atlas of Distant Water Fishing](https://emlab-ucsb.shinyapps.io/SubsidyAtlasACP/)