forked from symanzik/MicromapPlotsInR
-
Notifications
You must be signed in to change notification settings - Fork 0
/
07-webBased.Rmd
284 lines (207 loc) · 37.2 KB
/
07-webBased.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# Web-based Linked Micromap Plots Using Shiny {#Ch7}
\chapterauthor{Marcus W. Beck}
Web-based interactive linked micromaps were first developed in the late 1990s. Early examples included visualizing hazardous air pollutant data using the Graphics Production Library [@SACWWW1999] and use of micromaps by the National Cancer Institute to visualize long-term cancer data [@BHPW2006]. These early examples primarily used Java-based web technologies to combine micromap visualization tools with online functionality. Since then, the development of R packages to create web-based applications has allowed new opportunities to visualize and share micromaps online. This chapter will introduce the reader to the creation of linked micromap plots via the R **shiny**\index{R Packages!shiny} package [@CCASSXAMDB2021]. Core concepts of creating shiny applications will be discussed, including an example that demonstrates a minimal working shiny application with the **micromap**\index{R Packages!micromap} package [@PaOl2015; @Beck2022].
## The Need for Web Applications {#Ch7-Introduction}
The ability to develop and host content online has obvious benefits for research and data-intensive applications. Reaching new audiences and creating a more immersive experience with interactive functionality can improve understanding beyond text descriptions in technical reports or research articles. This is especially important when research products have intended applications for non-technical audiences or to simply facilitate sharing of ideas among colleagues, such as for applied environmental (e.g., Chapter \@ref(Ch11)) or medical (e.g., Chapter \@ref(Ch12)) fields. Web-based applications can greatly improve technology transfer from the research community to practitioners, collaborators, or other stakeholders that may not need to fully understand the technical details of an underlying application, but require robust tools built on quality science to make informed decisions.
In this context, a web-based application (web app or dashboard, hereafter) can have two fundamental roles, where the primary goal of each is to increase understanding of concepts or results from research products or data. The first and most common use is creating a web app to support an existing or otherwise finalized research product. Simple examples include developing an application to share results as supplemental information from a research article, creating a web page to synthesize and distill large, publicly available datasets, or using a web application for prioritizing how decisions are made with limited resources. In the latter case, these may also be generically called decision support tools. The second, more under-utilized role of web apps is as intermediate tools that can enhance the research or exploratory analysis process. For many of the reasons that web apps can improve delivery of science to decision-makers or to inform the public, web apps can also benefit the research community by improving collaboration among colleagues. We encourage readers to appreciate and understand how web apps can have benefits at different stages of analysis, not just as a final product.
The concepts and tools presented in this chapter can apply equally well to the two use cases above. In addition to understanding the theory of building web apps with micromaps, additional considerations include how the application is hosted online for access by others and what steps are made to ensure the application is maintained in the future. A detailed discussion of these concepts is beyond the scope of this chapter, but examples and resources are provided to allow the reader to understand their importance and how to further build on the concepts herein. We primarily cover the basics of developing a shiny application, but refer the reader specifically to @Wickham2021 and @Sievert2020 for a more comprehensive introduction to using shiny.
## Existing Examples of Micromap Web Applications {#Ch7-ExistingWebApps}
The first web apps that used micromaps to explore spatial patterns in data were created in the late 1990s. Although R has been in use since this time, the ability to create web apps with shiny was not available until 2012 (the first version on CRAN was uploaded in December 2012). These early applications were similar to shiny in that they utilized functional programming and text markup languages to allow exploration of data within a web browser. Shiny uses similar tools within an R framework, i.e., it uses functions to create HTML and Java-based graphics for the developer, whereas early micromap apps were coded directly with these core tools. This required detailed knowledge of fundamental concepts of web programming that most R users currently do not have. Thus, there are few early examples of micromap web apps.
The first documented web app is described by @SACWWW1999 that used the Graphics Production Library [GPL, @CVR96] to visualize hazardous air pollutant data with micromaps in a web browser. The GPL was developed by the Bureau of Labor Statistics as a standalone software package based on Java to provide metadata access to underlying datasets through clickable metadata icons. Functionally, the GPL is similar to shiny by providing interactive components that allowed a user to access information of interest. @CVR96 state that the GPL addressed a critical need of creating quality graphics in a web-based format, where the latter was especially challenging at a time when access to robust software for creating online content was limited as the internet was gaining popularity as a tool to deliver data resources. The use of GPL with linked micromaps by @SACWWW1999 served a critical need by allowing a user to quickly filter a national-level dataset to regions of interest. Users were able to select a state, then advance to the underlying micromap display and tabular results that summarized air pollutant data by census tracts at the county level. As such, the application was inherently user-driven where the functionality was available to prioritize areas of concern based on location. More contemporary web apps built in shiny often serve similar purposes by allowing a user to determine which subsets of data to view from a larger database.
An additional example is provided by the National Cancer Institute that displayed national-scale state cancer profiles with linked micromaps [@BHPW2006;@PPC2015JSS]. Similar to @SACWWW1999, micromaps were displayed with an interactive interface developed using Java to allow a user to select regions and appropriate summary statistics. However, the cancer profiles were the first example of using the **micromapST**\index{R Packages!micromapST} R package in a web format, which predated the development of shiny by about a decade, demonstrating an early example of the utility of R as a platform to facilitate the creation of web content. These early applications also focused on the importance of communicating public health data in an accurate, clear, and concise manner for consumption by an increasingly interested user base (i.e., policymakers and the public) that was becoming more comfortable using the internet as a valuable tool to support decision-making. Emphasis was placed on tailoring graphics towards the needs of the audience, as well as ensuring confidentiality and displaying uncertainty in results that was true to the underlying data. This use case was especially relevant for linked micromaps that provided a useful format to address these needs. Notable limitations of the web apps were stated as difficulties in graphics display due to sizing issues and an inability to access or modify the underlying data [@PPC2015JSS]. Many of these issues have been addressed in the implementation of shiny and more recent supporting R packages, although micromaps will fundamentally be limited by the spatial units and their groupings chosen by the user.
A common theme of these early web-based tools was the need to deliver relevant summaries of large datasets in a simple and easily navigable format. The use of micromaps provided useful summary statistics in a spatial context, whereas the web-based platforms further advanced the utility of these data by providing user options to select locations or results of interest. However, there are not many examples of these early tools given the required expertise to create them with web programming platforms, such as Java. Subject-matter experts in the fields of public health or the environmental sciences are not conventionally trained to use these tools and the advent of modern tools like shiny has provided additional opportunities to improve how end users engage with data that can support critical decision-making. Moreover, these early tools are not accessible online in their original format, suggesting a need for developers to consider longevity, app maintenance, and permanence as a fundamental objective of app development. The remainder of this chapter describes these modern tools and additional considerations for hosting them online to ensure they are maintained in the future.
## Shiny as an Open Source Tool for Web Applications {#Ch7-Shiny}
### What is Shiny?
The R **shiny**\index{R Packages!shiny} package [@CCASSXAMDB2021;@Wickham2021] allows a developer to create web apps entirely in R. Shiny can expose existing R scripts to a web browser to allow anybody to access underlying features outside of R and the local environment of a personal computer. Shiny is commonly used to 1) communicate complex workflows to a non-technical audience with informative visualizations and interactive components, 2) share analysis output easily with colleagues without having to walk them through details of a script, and 3) help inform understanding of an analysis by creating a user interface to quickly evaluate data. Because linked micromaps can be easily created in R using the **micromap**\index{R Packages!micromap} or **micromapST**\index{R Packages!micromapST} packages, creating web apps with shiny is a simple extension that can greatly improve understanding of data.
There are many advantages to using shiny over other platforms for creating web apps. The primary advantage is the ability to create rich web content entirely using R. There is no need to have a detailed understanding of web programming, such as HTML, CSS, or JavaScript. However, shiny leverages this broader suite of web programming tools so that they are available for use should a developer have the need to expand an application's utilities beyond the core features within shiny. More simply, shiny can be used as a web interface for any R workflow. This means that any custom analysis or graphic created by an R user can be can be fully integrated into a web app, unlike other platforms that may have rigid templates where functionality is sacrificed for ease of use.
Understanding shiny can be challenging at first because it introduces a new way of thinking about code. "Simple" R scripts are run linearly, being read from top to bottom in a conventional analysis workflow. The script is written, the code is sourced to the R console, and results or objects are saved in the environment of the current R session after running the script. A shiny app runs from an R script, but instead of executing code linearly, it uses **reactive** programming that detects when an input is changed on the application, runs the minimal amount of code that uses that input, then updates the output as needed. So, rather than running linearly, the script has interconnected components that share pieces of information that are executed on the fly to produce the results.
Reactivity can be daunting at first because it requires the developer to think about which pieces of code require inputs from other pieces and how that information is used to create output. This is not fundamentally different from writing functions in R and creating a shiny application should be straightforward if a developer is comfortable with functional programming [@Wickham2019]. Reactivity can be conceptualized by the building blocks of a shiny app. Every shiny app has the following:
* __User interface (UI)__: Includes all inputs and outputs, as well as the appearance of the dashboard. In this context, "output" means the final product (e.g., plots, tables, etc.) that are placed in the user interface, but created by processing inputs sent to the server. In web-speak, this is the front end.
* __Server__: The guts or engine of how the inputs are used to create the outputs. This is where the working parts of the analysis are contained. The server can be as simple or as complicated as needed for an application. In web-speak, this is the back end.
The `ui` and `server` components can be contained in an R script, as follows:
```{r, eval = FALSE}
library(shiny)
ui <- fluidPage()
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
```
In RStudio, the application can be run clicking the "Run App" button at the top right of the source window or sending the code to the R console (Figure \@ref(fig:Ch7-shiny-code)).
```{r Ch7-shiny-code, fig.cap = 'A minimal working shiny application in RStudio showing code for the user interface and server. The application can be run in RStudio by selecting "Run App".', echo = FALSE, out.width = '100%'}
knitr::include_graphics(path = "img/Ch7-shiny-code.PNG")
```
The above application will open locally, either through a local port opened by RStudio or in a web browser depending on the user options in `shinyApp()`. In this example, an empty screen appears because the application currently does nothing and it is only accessible to the user in the current R session. Building a more functional shiny application only requires adding code to the server and user interface. Making the application accessible to others is described in section \@ref(Ch7-shiny-online).
The example above can be expanded to demonstrate how code within the server and user interface might look in practice. The application below takes random samples from a normal distribution and creates a histogram showing the density using base R (Figure \@ref(fig:Ch7-shiny-histogram)). The user interface determines how many random samples are used to create the plot. To make a shiny app, the inputs and outputs must be identified by the developer to determine where they are placed in the code. The input is what a user can modify (the sample size) and the output is the plot. Inputs and outputs go in the `ui` object. The `server` takes the inputs, produces the content for the output, and then sends the results back to the `ui`. Placing these components into the template is as follows:
```{r, eval = FALSE}
library(shiny)
ui <- fluidPage(
numericInput(inputId = "n", label = "Sample size", value = 50),
plotOutput(outputId = "myplot")
)
server <- function(input, output) {
output$myplot <- renderPlot({
dat <- rnorm(n = input$n)
hist(x = dat)
})
}
shinyApp(ui = ui, server = server)
```
```{r Ch7-shiny-histogram, fig.cap = 'A minimal working shiny application with additional components in the server and user interface that produces a histogram with options to select the sample size.', echo = FALSE, out.width = '100%'}
knitr::include_graphics(path = "img/Ch7-shiny-histogram.PNG")
```
Evaluating what happens in the application each time a different sample size is selected by a user and how the application functions with the user interface and server components of the code is critical to understanding reactivity. The running application follows these steps (Figure \@ref(fig:Ch7-shiny-flow)) when the web app is initialized in the browser and when a user selects a new sample size:
1. The `input` value `n` selected by the user from the `ui` is sent to the `server`, seen as `input$n`.
1. The `dat` object is created as a random sample with size `n` and then a histogram is created as reactive output with `renderPlot`.
1. The plot output named `myplot` (chosen by the developer) is appended to the `output` list of objects in the `server`.
1. The plot is then rendered on the `ui` using `plotOutput` by referencing the `myplot` name from the `output` object.
```{r Ch7-shiny-flow, fig.cap = 'A representation of reactivity each time the user input is changed to select a different sample size for the histogram.', echo = FALSE, out.width = '100%'}
knitr::include_graphics(path = "img/Ch7-shiny-flow.png")
```
From this simple workflow, some generalized rules and concepts about shiny reactivity can be described that apply to most shiny applications.
* All input objects are defined in the `ui` object, given a name inside the input function and then referenced in the `server` file by `input$name` (`input$n` in the example).
```{r, eval = FALSE}
numericInput(inputId = "n", label = "Sample size", value = 50)
```
* All output objects to use in the `ui` object are created in the `server` object by assigning a "rendered" object to the `output` object by `output$name` (`output$myplot` in this case).
```{r, eval = FALSE}
output$myplot <- renderPlot({
dat <- rnorm(n = input$n)
hist(x = dat)
})
```
* The `ui` object controls where and when the output is rendered, typically using a function named `fooOutput()` (`foo` meaning generic, e.g., `plot`, `table`, etc.) that has a complementary reactive function named `renderFoo()` in the `server` file.
```{r, eval = FALSE}
plotOutput(outputId = "myplot")
```
* The `ui` object can be created with a function (`fluidPage()` here as one type of layout) with at least two inputs (one input, one output) separated by commas.
* The `server` object can be created with the `server()` function, where the input from the `ui` and output to send back to the `ui` is evaluated as an expression inside the curly braces `{}`.
All shiny applications use these concepts to create rich, interactive content that is accessible in a web browser. For example, the user interface can include different types of input selections, or "widgets", depending on how a developer intends a user to change inputs or interact with the data. These widgets can be as simple as entering numeric input, i.e., `numericInput()` as from above, or can be more involved to select items from a predetermined list using a dropdown menu or radio buttons, using a slider to select values, choosing date ranges, uploading files, or even entering custom text. A full description of the available input options included with the shiny package can be found at https://shiny.rstudio.com/gallery/widget-gallery.html. The **shinyWidgets**\index{R Packages!shinyWidgets} package [@PMG2022] also includes additional widgets beyond those provided with shiny.
For shiny output, plots and tables can easily be created with `renderPlot()` and `renderTable()` in the server and their corresponding output functions, `plotOutput()` and `tableOutput()` in the user interface, respectively. Additional output can include images (`renderImage()` in the `server`, `imageOutput()` in the `ui`), text (`renderText()` in the `server`, `textOutput()` in the `ui`), and even dynamic user interface options (`renderUI()` in the `server`, `uiOutput()` in the `ui`), where the user selection depends on input from another component of the web app. The output options in a shiny app can also be greatly expanded using the **htmlwidgets**\index{R Packages!htmlwidgets} package (in this context, "widget" does not refer to a `ui` selection). The **htmlwidgets**\index{R Packages!htmlwidgets} package [@VXACSR2021] creates R bindings for a shiny application to use existing JavaScript libraries, allowing the creation of additional interactive visualizations (e.g., plotly and leaflet). As before, a shiny developer only needs to understand R to use these tools.
The layout of the dashboard as seen from the user's perspective can also be modified by the developer. The template from above uses the standard `fluidPage()` design that organizes the user interface into a simple row/column format. Although the simple histogram template does not have any visual cues as to its organization on the web page, the `fluidPage()` layout has placed the numeric input selection and plot on separate rows defined by standard HTML tags created by shiny. The content is scaled automatically to fill the dimensions of the browser or mobile device of the user. The **flexdashboard**\index{R Packages!flexdashboard} [@IAB2020] and **shinydashboard**\index{R Packages!shinydashboard} [@ChaBor2021] packages can be used to create more flexible dashboard layouts with content placed in specific CSS elements, such as boxes or tabs that are organized logically to improve how a user engages with the web app. The flexdashboard package uses **rmarkdown**\index{R Packages!rmarkdown} [@XDR2021], as compared to an R script used by most shiny apps. In fact, any rmarkdown file can be rendered using shiny with `runtime: shiny` in the YAML code at the top, allowing those already familiar with rmarkdown to easily embed shiny components in a rendered HTML document.
Using the above concepts and packages allows a developer to create more involved and useful applications, such as creating custom micromap plots and options to allow a user to explore patterns more easily than using a conventional R script. In the following section, a simple shiny application is described to demonstrate how it can be used with the **micromap**\index{R Packages!micromap} package.
### Minimal Micromap Example
A simple example of a shiny application using the **micromap**\index{R Packages!micromap} package [@PaOl2015] is described in this section. The application is accessible at https://beckmw.shinyapps.io/micromap_app/ using the RStudio shinyapps.io (https://www.shinyapps.io/) platform. The source code for the application is available on GitHub at https://github.com/fawda123/micromap_app and archived through Zenodo at https://doi.org/10.5281/zenodo.6532271 [@Beck2022]. The services used to host and archive this application and reasons for their use are described in the next section.
The micromap web app is a simple extension of the `server` and `ui` format described in the previous section. The structure is similar with a notable difference that the server and user interface components are in separate .R files, although they can also be placed in a single file as above. The separation into two scripts is a decision made by the developer based on personal preference, rather than a functional difference. For example, a developer may prefer to use two files to simplify working with the code for each component. The application uses the _USstates_\index{Datasets!USstates} dataset as the spatial polygon boundaries and the __state.x77__\index{Datasets!state.x77} dataset from the **datasets**\index{R Packages!datasets} package that is included with the base R installation. The app plots the chosen state data from __state.x77__\index{Datasets!state.x77} (e.g., population, income, etc.) as two dot plots, with the state labels on the left and maps on the right using the `mmplot()` function (see Chapter \@ref(Ch2)). The application allows a user to select which state data to show in the dot plots, the number of perceptual groups, whether a median value is shown, and which dot plot determines the ordering of the rows in the micromap (Figure \@ref(fig:Ch7-shiny-example)).
```{r Ch7-shiny-example, fig.cap = 'A minimal working shiny application using the micromap package.', out.width = '100%', echo = FALSE}
knitr::include_graphics(path = "img/Ch7-shiny-example.PNG")
```
The ui.R file is as follows:
```{r, eval = FALSE}
library(shiny)
library(shinythemes)
library(datasets)
# variables
vrs <- colnames(x = state.x77)
# define ui for application
ui <- fluidPage(
theme = shinytheme(theme = "journal"),
titlePanel(title = "Micromap Shiny Application"),
sidebarLayout(
# side bar
sidebarPanel(
width = 2,
selectInput(
inputId = "vr1",
label = h4("Variable 1"),
choices = vrs,
selected = vrs[1]
),
selectInput(
inputId = "vr2",
label = h4("Variable 2"),
choices = vrs,
selected = vrs[2]
),
numericInput(
inputId = "grps",
label = h4("Groupings"),
value = 10,
min = 1,
max = 50
),
radioButtons(
inputId = "medval",
label = h4("Median value?"),
choices = c(TRUE, FALSE),
selected = c(FALSE),
inline = TRUE
),
radioButtons(
inputId = "ords",
label = h4("Order by"),
choices = c("Variable 1", "Variable 2"),
selected = c("Variable 1"),
inline = TRUE
)
),
# main panel
mainPanel(
plotOutput(outputId = "p1", width = "700px", height = "750px")
)
)
)
```
The ui.R file begins by importing the relevant package dependencies, specifically the **shiny**\index{R Packages!shiny}, **shinythemes**\index{R Packages!shinythemes}, and **datasets**\index{R Packages!datasets} packages. The `vrs` object is created as options to use for selecting variables from the __state.x77__\index{Datasets!state.x77} data for the micromap dot plots with the input widgets. Various components of the web app are created within the `ui` object, specifically the `fluidPage()` layout, a custom CSS theme from the **shinythemes**\index{R Packages!shinythemes} package [@Chang2021], several user inputs that are sent to the server described below, and finally the micromap plot created in the server and defined as output in the user interface by `plotOutput()`. The user inputs include options to select which variables to plot from a menu with `selectInput()`, numeric options for the number of perceptual groups with `numericInput()`, and radio buttons with `radioButtons()` for selecting whether the median is shown on the micromap and which variable in the dot plots is used for the ordering. Other functions define the visual layout, notably the `sidebarLayout()` that places the inputs in a `sidebarPanel()` on the left and the main plot in a `mainPanel()` on the right (Figure \@ref(fig:Ch7-shiny-example)).
The server.R file is as follows:
```{r, eval = FALSE}
library(shiny)
library(micromap)
library(datasets)
# data
statdat <- state.x77
# spatial data
data(USstates)
# define server for the application
server <- function(input, output) {
output$p1 <- renderPlot({
# include median value, groupings
medval <- as.logical(x = input$medval)
grps <- input$grps
# input variables, dates, and order
vr1 <- input$vr1
vr2 <- input$vr2
# name the variable for ordering
ords <- input$ords
ords <- gsub(pattern = "Variable\\s", replacement = "vr", x = ords)
# subset variables and dates, combine
toplo <- statdat[, c(vr1, vr2)]
toplo <- data.frame(toplo)
names(toplo) <- c("vr1", "vr2")
toplo$ST <- row.names(x = toplo)
# create map table for polygons
polys <- create_map_table(tmp.map = USstates, IDcolumn = "ST_NAME")
# plot
mmplot(
stat.data = toplo,
map.data = polys,
panel.types = c("labels", "dot", "dot", "map"),
panel.data = list("ST", "vr1", "vr2", NA),
ord.by = ords,
median.row = medval,
grouping = grps,
map.link = c("ST", "ID"),
panel.att = list(
list(2, header = vr1),
list(3, header = vr2)
)
)
})
}
```
The server components begin by importing the dependencies for the file, specifically the **shiny**\index{R Packages!shiny}, **micromap**\index{R Packages!micromap}, and **datasets**\index{R Packages!datasets} packages. The __state.x77__\index{Datasets!state.x77} data is then assigned to the `statdat` object and the _USstates_\index{Datasets!USstates} spatial polygons data frame are also imported from the **micromap**\index{R Packages!micromap} package. Both of these data objects are used within the server code, which is the remainder of the script.
The code within the `server` object creates a micromap plot object for output (`output$p1`) to the user interface using the `renderPlot()` function from shiny. Within `renderPlot()`, the inputs from the user interface are used to define what data are plotted. Specifically, `input$medval` is a logical argument that determines if the median value is shown in the micromap, `input$grps` is a numeric value for the number of perceptual groups, `input$ords` is used to create a character string that defines the ordering of the dot plot based on the variable name, and `input$vr1` and `input$vr2` are the user selections for which variables in `statdat` are used for the dot plots. The `statdat` object is then subset and renamed based on the variable selections. The rest of the code is the conventional setup for a linked micromap with `mmplot`, i.e., `create_map_table()` is used to create the input for the `map.data` argument in `mmplot` and then `mmplot` is used with the data subset to create the final plot.
The web app is a proof of concept for how a micromap can be used in a shiny framework. It is simple by design to expand on the concepts described earlier in this chapter. In practice, shiny can be used to create more complex and rich web apps for micromaps to improve how users engage with spatial data in different contexts. One contemporary example is provided by the Virginia Department of Environmental Quality (DEQ) and is available at https://evjones.shinyapps.io/FreshwaterProbMonEDA/ (Figure \@ref(fig:Ch7-VDEQ-shiny)). The application is used by Virginia DEQ to support an annual report for their freshwater probabilistic monitoring program (additional examples from Virginia DEQ are in Chapter \@ref(Ch11)). Readers are invited to explore this application to better understand the full potential of shiny as a platform for facilitating the delivery of scientific products.
```{r Ch7-VDEQ-shiny, fig.cap = 'A screenshot of a shiny app with linked micromaps from the Virginia Department of Environmental Quality, available at https://evjones.shinyapps.io/FreshwaterProbMonEDA/.', out.width = '100%', echo = FALSE}
knitr::include_graphics(path = "img/Ch7-VDEQ-shiny.PNG")
```
### Getting Shiny Online {#Ch7-shiny-online}
Using shiny to create web apps includes additional considerations that are equally, if not more, important than the development process. First, shiny allows a developer to create an application that is accessible through a web browser. Exposing the application outside of the local environment (i.e., the developer's personal computer) requires additional steps to make the the app accessible by others through a URL web address. There are several options for hosting a shiny application online and each varies in the ease of use, cost, and options desired by the developer. Some of these options are:
1. Deploy to shinyapps.io (https://www.shinyapps.io/) directly from the RStudio console using the **rsconnect**\index{R Packages!rsconnect} R package [@Atkins2021]. The server is maintained by RStudio and the **rsconnect**\index{R Packages!rsconnect} package identifies all dependencies required for an application on deployment. This option may be preferred for novice shiny developers because knowledge of server management is not required. However, the service uses a tiered pricing plan. The free tier is good for very simple apps, but a larger plan will be needed if a developer expects others to have any meaningful engagement with an app.
1. The open-source Shiny Server (https://rstudio.com/products/shiny/shiny-server/) from RStudio can be used for full ownership of an application. This requires more extensive knowledge of server management, specifically on a Unix operating system. A developer will be responsible for maintaining the Shiny Server, RStudio Server, and any of the application dependencies. However, this may be a more practical option if resources are limited and an organization desires full control of web resources.
1. RStudio Connect (https://rstudio.com/products/connect/) can be used as a commercial solution to hosting shiny applications. RStudio Connect is a business model version of multiple resources provided by RStudio in an online format. The services are marketed for larger organizations with greater enterprising needs, as opposed to an individual developer.
1. Docker (https://www.docker.com/) shiny apps can also be created as an alternative solution that leverages both the open source versions of Shiny Server and RStudio Server. Docker allows a developer to solve portability and versioning problems with software management that is independent of the operating system. Docker takes a "snapshot" of a local software environment (i.e., R version, package dependencies, etc.) and creates a standalone application (or image) that can run on any server that uses Docker. Server maintenance is also greatly simplified because only Docker is required to run a shiny app. However, additional expertise on using Docker is required.
In addition to hosting, a shiny developer must consider how the source code is managed, both during development and for long-term maintenance. Use of version control software, such as Git (https://git-scm.com/), and a web-hosting service for sharing version control projects, such as GitHub (https://github.com/), should be used to create an accessible, long-term record of the development history of an app. This creates a record of changes that a developer can retrieve at any time and allows others to view and reuse code from an existing app. In the latter case, licensing options are available on GitHub so that a developer can define how code can be reused from an existing repository. GitHub is also linked to Zenodo (https://zenodo.org/) to archive versions of a repository as a stand-alone set of files and assign a unique identifier that can be cited and tracked. This service extends the utility of GitHub by establishing a stronger precedent for "FAIR" data practices as a tenet of broader open science principles [@Wilkinsonetal2016;@Mons2018].
## Summary and Further Reading {#Ch7-Summary}
This chapter provided a general overview of how **shiny**\index{R Packages!shiny} can be used to extend the utility of linked micromaps in a web-based framework. Section \@ref(Ch7-Introduction) described the benefits and goals of developing a web app, section \@ref(Ch7-ExistingWebApps) described some early examples of micromap web apps, and section \@ref(Ch7-Shiny) covered the very basics of shiny, a minimal example, and some guidance for hosting an app online. The reader is encouraged to view other chapters in this text for additional details on building micromaps with **micromap**\index{R Packages!micromap} (Chapter \@ref(Ch2)) or **micromapST**\index{R Packages!micromapST} (Chapter \@ref(Ch3)) as a precursor to using these packages with shiny. Further, Chapters \@ref(Ch11) and \@ref(Ch12) provide details on how micromaps have been applied in the environmental and medical fields, respectively, and can serve as additional motivation for using shiny in different disciplines.
The overview of shiny and its reactive principles in section \@ref(Ch7-Shiny) provided only the basics of shiny's functionality and additional resources should be consulted to develop a greater understanding of shiny in practice. @Wickham2021 and @Sievert2020, in particular, cover these principles in greater detail. Modularity is an additional concept that can improve how an app functions, specifically in production [@FRGG2022]. Modules address complexity in an app by creating standalone pieces of code for creating input or output, much like functions in conventional R context, while also addressing labeling conflicts that are common in complex web apps. @SNYPV2022 also provide an excellent overview of best practices for app development in a "ten simple rules" format that caters to the research community that typically has no formal training in these tools. Other important considerations for app development include understanding fundamentals of user interface design (i.e, the `ui` component of an app), which is critical for guiding and improving how a user engages with an app [see Chapter 6 in @FRGG2022]. The best developed code for an app will have minimal value if a user is unable to navigate the front end.
Shiny is also not the the only tool available for developing a web app. As mentioned above, shiny is useful if a developer is already familiar with R and comfortable creating an app with code. Those with web experience may prefer using the core tools, such as Java, HTML, and CSS, although this may create additional challenges when workflows are not entirely within the R environment. Conversely, other platforms provide a graphical user interface (GUI), e.g., ArcGIS StoryMaps (https://storymaps.arcgis.com/), Tableau (https://www.tableau.com/), or Power BI https://powerbi.microsoft.com/), that can be used for app development, eliminating the need for direct coding. For GUI-driven development, functionality may be sacrificed for ease of use because a developer may not have complete control over the server and user interface components. In all cases, shiny is a compromise between directly using web programming languages and more simple development software. Shiny offers a platform that is currently relevant for R users, but it is inevitable that this work space will change as new tools address the evolving needs of the research community and those that need scientific products to make informed decisions. The role of R and shiny in this future environment will necessarily change and paying attention to these dynamics is critical in understanding how web apps can help communicate scientific information.
\printbibliography[segment=\therefsegment,heading=subbibliography]