S3729C Wellness and Health Management - Lesson 13
Class Date : 17 September 2022
At the end of this lesson, students will be able to:
Pacman will be used again to unpack all packages required in this lesson. Please copy, paste and run the code in your R Studio Cloud workspace.
These are the main packages required for this lesson
We will again be using the movies dataset, which combines data from two websites: the Internet Movie Database, commonly known as IMDB, and Rotten Tomatoes. The observations are a random sample of 651 movies released in the US between 1970 and 2014.
GitHub Link for Movies Dataset (in csv) : https://raw.githubusercontent.com/aaron-chen-angus/S3729C-Lesson-Files/6a58d56d3d42231fb011af462db7efc01537e515/movies.csv
We will also be using a subset of this dataset for some applications in this lesson, this will contain the genre of movies by release year.
GitHub Link for Subset (in csv) : https://raw.githubusercontent.com/aaron-chen-angus/S3729C-Lesson-Files/main/genre.year.csv
In the first section, we will also be making use of the following datasets.
WorldPhones
Link to documentation of this dataset : https://www.rdocumentation.org/packages/datasets/versions/3.6.2/topics/WorldPhones
mtcars
Link to documentation of this dataset : https://www.rdocumentation.org/packages/datasets/versions/3.6.2/topics/mtcars
This code can be used for the generation of a Bar Plot | Histogram where you can specify the subset of data to be viewed via a reactive dropdown list. Take note of the use of reactive expressions to select the data subset.
# Load packages ----------------------------------------------------------------
library(shiny)
library(ggplot2)
library(RColorBrewer)
coul <- brewer.pal(8, "Dark2") #this is to set the colour palette to a set from the RColorBrewer package in the plot
# Load data --------------------------------------------------------------------
library(datasets)
# Define UI --------------------------------------------------------------------
ui <- fluidPage(
# Give the page a title
titlePanel("Telephones by region"),
# Generate a row with a sidebar
sidebarLayout(
# Define the sidebar with one input
sidebarPanel(
selectInput("region", "Region:",
choices=colnames(WorldPhones)),
hr(),
helpText("Data from AT&T (1961) The World's Telephones.")
),
# Create a spot for the barplot
mainPanel(
plotOutput("phonePlot")
)
)
)
# Define server ----------------------------------------------------------------
server <- function(input, output) {
# Fill in the spot we created for a plot
output$phonePlot <- renderPlot({
# Render a barplot
barplot(WorldPhones[,input$region]*1000,
main=input$region,
ylab="Number of Telephones",
xlab="Year",
border="#69b3a2", col = coul)
})
}
# Create a Shiny app object ----------------------------------------------------
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:5325
This code will show you how to customise elements of your ggplot2 output, such as fill colour, by including these options as reactive elements in your R Shiny App. Note that in the code, we spell colour as “color”, because the code typically adopts American conventions.
# Load packages ----------------------------------------------------------------
library(shiny)
library(shinyjs)
library(colourpicker)
library(gridExtra)
library(ggplot2)
# Define UI --------------------------------------------------------------------
ui <-
fluidPage(
useShinyjs(),
column(
tags$title("R Color Picker and Visualizer"),
h3("R Color Picker and Visualizer"),
p("The applications on this page allow you to select colours for use in data visualization, such as the", code("ggplot2"), "package in R."),
p("Pick how many colours you would like to plot, and then click in the coloured field below \"Select color\" to open the color picker tool."),
p("In the color picker tool, the square on the left allows you to adjust the lightness and darkness of the colour, the middle slider is for selecting the colour (technically, the \"hue\"), and the rightmost slider allows you to select the alpha level (transparency) of the color."),
p("The plots visualize data from the", code("mtcars"), "dataset, and they will update as you change the colour"),
p("Some combinations of colours work better than others for aesthetic or distinguishability purposes. The application below lets you set one to three colours, which are then mapped to an appropriate variable from", code("mtcars"), "."),
sidebarLayout(
sidebarPanel(
radioButtons("n", "Number of colors:", c("1", "2", "3")),
colourInput("col1", "Select color", "#555599", allowTransparent = T),
conditionalPanel("input.n >= '2'",
colourInput("col2", "Select color", "#66BBBB", allowTransparent = T)),
conditionalPanel("input.n == '3'",
colourInput("col3", "Select color", "#DD4444", allowTransparent = T))
),
mainPanel(
plotOutput("plot")
)
),
h4("Modifying Colors in ggplot2"),
p("Once you have selected your color(s), copy the hex code including ", code("#"), "( e.g., ", code("#555599"), "). Surround this with quotes and provide it as a function argument in ggplot. For example,"),
pre("ggplot(mtcars, aes(wt, mpg)) +
geom_point(color = \"#555599\", size = 3)"),
p("For more on using ggplot, please refer to ", a("S3729C Lesson 11", href = "https://rpubs.com/aaron_chen_angus/S3729C_Lesson_11")),
width = 8, offset = 2
)
)
# Define server ----------------------------------------------------------------
server <-
function(input, output) {
output$plot <- renderPlot({
runjs("toggleCodePosition();")
cols <- c(input$col1, input$col2, input$col3)
colvar <- ifelse(input$n == 1, "vs", ifelse(input$n == 2, "am", "gear"))
if (input$n == 1) {
grid.arrange(ggplot(mtcars, aes(wt, mpg)) +
geom_point(size = 3, color = input$col1),
ggplot(mtcars, aes(as.factor(cyl))) +
geom_bar(fill = input$col1),
ncol = 1)
} else {
grid.arrange(ggplot(mtcars, aes(wt, mpg, color = as.factor(!!sym(colvar)))) +
geom_point(size = 3) +
scale_color_manual(values = cols, name = colvar),
ggplot(mtcars, aes(as.factor(cyl), fill = as.factor(!!sym(colvar)))) +
geom_bar() +
scale_fill_manual(values = cols, name = colvar),
ncol = 1)
}
})
}
# Create a Shiny app object ----------------------------------------------------
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:5474
Earlier on we mentioned that the UI is ultimately built with HTML. We actually use R functions to make the UI, but they get translated to HTML.
In this lesson we build on this idea to develop more complex app interfaces. More specifically, we discuss tags.
Shiny comes with a list of functions saved under tags that allow us to access HTML tags and use them to add static (as opposed to reactive) content to our apps.
The tags object in shiny is a list of 100+ simple functions for constructing HTML documents. Each of the elements in this list is a function that maps to an HTML tag.
## [1] "a" "abbr" "address"
## [4] "animate" "animateMotion" "animateTransform"
## [7] "area" "article" "aside"
## [10] "audio" "b" "base"
## [13] "bdi" "bdo" "blockquote"
## [16] "body" "br" "button"
## [19] "canvas" "caption" "circle"
## [22] "cite" "clipPath" "code"
## [25] "col" "colgroup" "color-profile"
## [28] "command" "data" "datalist"
## [31] "dd" "defs" "del"
## [34] "desc" "details" "dfn"
## [37] "dialog" "discard" "div"
## [40] "dl" "dt" "ellipse"
## [43] "em" "embed" "eventsource"
## [46] "feBlend" "feColorMatrix" "feComponentTransfer"
## [49] "feComposite" "feConvolveMatrix" "feDiffuseLighting"
## [52] "feDisplacementMap" "feDistantLight" "feDropShadow"
## [55] "feFlood" "feFuncA" "feFuncB"
## [58] "feFuncG" "feFuncR" "feGaussianBlur"
## [61] "feImage" "feMerge" "feMergeNode"
## [64] "feMorphology" "feOffset" "fePointLight"
## [67] "feSpecularLighting" "feSpotLight" "feTile"
## [70] "feTurbulence" "fieldset" "figcaption"
## [73] "figure" "filter" "footer"
## [76] "foreignObject" "form" "g"
## [79] "h1" "h2" "h3"
## [82] "h4" "h5" "h6"
## [85] "hatch" "hatchpath" "head"
## [88] "header" "hgroup" "hr"
## [91] "html" "i" "iframe"
## [94] "image" "img" "input"
## [97] "ins" "kbd" "keygen"
## [100] "label" "legend" "li"
## [103] "line" "linearGradient" "link"
## [106] "main" "map" "mark"
## [109] "marker" "mask" "menu"
## [112] "meta" "metadata" "meter"
## [115] "mpath" "nav" "noscript"
## [118] "object" "ol" "optgroup"
## [121] "option" "output" "p"
## [124] "param" "path" "pattern"
## [127] "picture" "polygon" "polyline"
## [130] "pre" "progress" "q"
## [133] "radialGradient" "rb" "rect"
## [136] "rp" "rt" "rtc"
## [139] "ruby" "s" "samp"
## [142] "script" "section" "select"
## [145] "set" "slot" "small"
## [148] "solidcolor" "source" "span"
## [151] "stop" "strong" "style"
## [154] "sub" "summary" "sup"
## [157] "svg" "switch" "symbol"
## [160] "table" "tbody" "td"
## [163] "template" "text" "textarea"
## [166] "textPath" "tfoot" "th"
## [169] "thead" "time" "title"
## [172] "tr" "track" "tspan"
## [175] "u" "ul" "use"
## [178] "var" "video" "view"
## [181] "wbr"For example, let’s use the b tag, which is used for bolding text in HTML. The function is tags$b().
You can pass a text string, in quotation marks, to this function, like “This is my first app”.
This is my first appThen R translates the text string to HTML:
## [1] "<b>This is my first app</b>"
The HTML is then rendered as bolded text when the user sees it:
This is my first app
So how would you use these tags in building an app?
You might use the various levels of headers if it makes sense for to have subheadings in my app.
For example tags£h1(), tags£h2(), and tags£h3() to create first, second, and third level headings, etc.
library(shiny)
# Define UI with tags
ui <- fluidPage(
tags$h1("First level heading"),
tags$h2("Second level heading"),
tags$h3("Third level heading")
)
# Define server function that does nothing :)
server <- function(input, output, session) {}
# Create the app object
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:5326
You can also nest tags within each other to create something like a new paragraph with the p tag and some text in that paragraph where certain words are italicized with the em tag and certain are bolded with the b tag.
library(shiny)
# Define UI with tags
ui <- fluidPage(
tags$p(
"Lorem ipsum",
tags$em("dolor"),
"sit amet,",
tags$b("consectetur"),
"adipiscing elit."
)
)
# Define server fn that does nothing :)
server <- function(input, output, session) {}
# Create the app object
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:8656
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
In this section we discuss the layout of a Shiny app.
One useful function for customizing the layout of your app is fluidRow(). This function creates horizontal rows where objects can be placed.
You can add as many rows as you want, but you want to be careful about expanding your app too much vertically as your users might not be willing to scroll down to interact with your app in full.
Copy this to a blank R script and press CTRL + Enter to view the output in your R Studio Cloud workspace.
library(shiny)
# Define UI with fluid rows
ui <- fluidPage(
"Side", "by", "side", "text",
fluidRow("Text on row 1"),
fluidRow("Text on row 2"),
fluidRow("Text on row 3")
)
# Define server function that does nothing
server <- function(input, output, session) {}
# Create the app object
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:8324
The column function is also incredibly useful. It adds columns within a row, and it requires that you define a width for each column.
Copy this to a blank R script, highlight and press CTRL + Enter to view the output in your R Studio Cloud workspace.
library(shiny)
# Define UI with fluid rows and columns
ui <- fluidPage(
fluidRow(
column("R1, C1, width = 3", width = 3),
column("R1, C2, width = 9", width = 9)
),
fluidRow(
column("R2, C1, width = 4", width = 4),
column("R2, C2, width = 4", width = 4),
column("R2, C3, width = 4", width = 4)
)
)
# Define server function that does nothing
server <- function(input, output, session) {}
# Create the app object
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:6559
You can use panels to group multiple elements into a single element that has its own properties.
This is especially important and useful for complex apps with a large number of inputs and outputs such that it might not be clear to the user where to get started.
The wellpanel() function groups elements into a grey well, or a box with rounded corners. This is a look you should be used to seeing in shiny apps by now.
Copy this to a blank R script, highlight and press CTRL + Enter to view the output in your R Studio Cloud workspace.
library(shiny)
# Define UI with wellPanels
ui <- fluidPage(
wellPanel( fluidRow("Row 1") ),
wellPanel( fluidRow("Row 2") ),
wellPanel( fluidRow("Row 3") )
)
# Define server function that does nothing
server <- function(input, output, session) {}
# Create the app object
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:6921
We have made heavy use of sidebarPanel() and mainPanel() in our apps in this course. However we mostly stuck with their default widths.
The default width for a sidebarPanel() is 4 and for a mainPanel() is 8.
library(shiny)
# Define UI with default width sidebar
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
strong("Sidebar"),
"Usually inputs go here, width = 4 by default"
),
mainPanel(
strong("Main panel"),
"Usually outputs go here, width = 8 by default"
)
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:5721
If you wanted to make an app where the sidebar and mainPanel are of equal width, so the app is split down the middle, you can specify a width argument to the sidebarPanel() and mainPanel() functions and set each to 6.
library(shiny)
# Define UI with default width sidebar
fluidPage(
sidebarLayout(
sidebarPanel("Sidebar with width = 6", width = 6),
mainPanel("Main panel with width = 6", width = 6)
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:8791
The titlePanel() is used to create a panel containing an application title. Often it makes sense to include this panel outside the sidebarLayout(). But in addition to the title on the page, youmight want to also change the text that shows up on the browser tab for our app, especially if our title is long.
library(shiny)
# Define UI with title panel
ui <- fluidPage(
titlePanel("My awesome app"),
sidebarLayout(
sidebarPanel("Some inputs"),
mainPanel("Some outputs")
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:5932
To customize this text you specify the windowTitle argument in the titlePanel(), which is by default equal to the application title. For example, your application title might be “Movie browser, 1970 to 2014”, but you might just want to make your window title “Movies”.
# Define UI with title panel and window title
ui <- fluidPage(
titlePanel("Movie browser, 1970 to 2014",
windowTitle = "Movies"),
sidebarLayout(
sidebarPanel("Some inputs"),
mainPanel("Some outputs")
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:6108
The last panel we’ll consider is conditionalPanel(), which creates a panel that is visible conditional upon the value of an input or an output.
Here is the code that creates the app with the conditional panel. Under the hood this function evaluates a JavaScript expression once at startup and then whenever Shiny detects a relevant change or input/output. Run it in your R Studio Cloud workspace to see how it works.
library(shiny)
# Define UI with conditionalPanel
ui <- fluidPage(
titlePanel("Random number generator"),
sidebarLayout(
sidebarPanel(
selectInput(
"digit_type", "Number of digits:",
c("any", "selected")
),
conditionalPanel(
condition = "input.digit_type == 'selected'",
sliderInput("digit_count", "How many digits?",
min = 1, max = 10, value = 4
)
),
actionButton("go", "Generate new random number"),
width = 5
),
mainPanel(
br(),
"Your random number is",
h4(textOutput("random_number")),
width = 7
)
)
)
# Define server logic that generates a random number based on user input
server <- function(input, output, session) {
output$random_number <- renderText({
input$go
raw <- runif(1)
digits <- if (input$digit_type == "any") {
sample(1:10, size = 1)
} else {
input$digit_count
}
round(raw * 10^digits)
})
}
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:3482
If the amount of information you want to communicate to your users does not fit well on a page, or there is detailed information, like raw data, that you want to make available to your users but not necessarily feature prominently in your app, you can make use of tabs to distribute this information to stackable tab panels.
Tabsets are created by calling the tabsetPanel() function with a list of tabs created by tabPanel().
Each tab panel has a unique title and a list of output elements which are rendered vertically within the tab.
In this example we display
library(shiny)
ui <- fluidPage(
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel("Plot", plotOutput("plot")),
tabPanel("Summary", tableOutput("summary")),
tabPanel("Data", DT::dataTableOutput("data")),
tabPanel(
"Reference",
tags$p(
"There data were obtained from",
tags$a("IMDB", href = "http://www.imdb.com/"), "and",
tags$a("Rotten Tomatoes", href = "https://www.rottentomatoes.com/"), "."
),
tags$p(
"The data represent", nrow(movies),
"randomly sampled movies released between 1972 to 2014 in the United States."
)
)
)
)
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:7942
Note that in the previous example the user first selected a subset of the data, movies_subset(), then this new sampled data got used in four separate tabs.
Introducing tabs into our user interface underlines the importance of creating reactive expressions for shared data.
If the dataset is expensive to compute, then the user interface could be slow to render if each tab were required to do the computation.
Instead, we calculate the data once in a reactive expression, and then have the result be shared by all of the output tabs.
Another option for laying out tabs is using the navlistpanel(), which lists the tabs vertically down the side, as opposed to horizontally across the screen.
mainPanel(
navlistPanel(
tabPanel("Plot", plotOutput("plot")),
tabPanel("Summary", tableOutput("summary")),
tabPanel("Data", DT::dataTableOutput("data")),
tabPanel(
"Reference",
tags$p(
"There data were obtained from",
tags$a("IMDB", href = "http://www.imdb.com/"), "and",
tags$a("Rotten Tomatoes", href = "https://www.rottentomatoes.com/"), "."
),
tags$p("The data represent", nrow(movies), "randomly sampled movies released between 1972 to 2014 in the United States.")
)
)
)To recap, we use tab panels to create stackable panels, and use tabsetPanel() or navlistPanel() to arrange the tabs with a navigation across the page or down the side of the page.
There are many other ways of customizing the look of your app, including using custom CSS. However one quick and easy way of changing the look is using the prebuilt themes in the shinythemes package.
In order to use one of these themes, you need to load the shinythemes package first. The package website has thumbnail images of each of the themes, but it can be difficult to tell exactly how the theme will look on your app.
Pick a theme and apply to the existing app. See https://rstudio.github.io/shinythemes for more on theme options. Run the code below by changing the theme in the shinythemes line.
Possible options include
# Load packages ----------------------------------------------------------------
library(shiny)
library(ggplot2)
library(tools)
library(shinythemes)## Warning: package 'shinythemes' was built under R version 3.6.3
# Load data --------------------------------------------------------------------
movies <- read.csv(file = "https://raw.githubusercontent.com/aaron-chen-angus/S3729C-Lesson-Files/6a58d56d3d42231fb011af462db7efc01537e515/movies.csv", header = TRUE, sep = ",")
# Define UI --------------------------------------------------------------------
ui <- fluidPage(theme = shinytheme("united"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "y",
label = "Y-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),
selected = "audience_score"
),
selectInput(
inputId = "x",
label = "X-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),
selected = "critics_score"
),
selectInput(
inputId = "z",
label = "Color by:",
choices = c(
"Title Type" = "title_type",
"Genre" = "genre",
"MPAA Rating" = "mpaa_rating",
"Critics Rating" = "critics_rating",
"Audience Rating" = "audience_rating"
),
selected = "mpaa_rating"
),
sliderInput(
inputId = "alpha",
label = "Alpha:",
min = 0, max = 1,
value = 0.5
),
sliderInput(
inputId = "size",
label = "Size:",
min = 0, max = 5,
value = 2
),
textInput(
inputId = "plot_title",
label = "Plot title",
placeholder = "Enter text to be used as plot title"
),
actionButton(
inputId = "update_plot_title",
label = "Update plot title"
)
),
mainPanel(
tags$br(),
tags$p(
"These data were obtained from",
tags$a("IMBD", href = "http://www.imbd.com/"), "and",
tags$a("Rotten Tomatoes", href = "https://www.rottentomatoes.com/"), "."
),
tags$p("The data represent", nrow(movies), "randomly sampled movies released between 1972 to 2014 in the United States."),
plotOutput(outputId = "scatterplot")
)
)
)
# Define server ----------------------------------------------------------------
server <- function(input, output, session) {
new_plot_title <- eventReactive(
eventExpr = input$update_plot_title,
valueExpr = {
toTitleCase(input$plot_title)
}
)
output$scatterplot <- renderPlot({
ggplot(data = movies, aes_string(x = input$x, y = input$y, color = input$z)) +
geom_point(alpha = input$alpha, size = input$size) +
labs(title = new_plot_title())
})
}
# Create the Shiny app object --------------------------------------------------
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:8471
A useful tool for browsing themes is the themeSelector() widget. To use this widget, simply add the widget to your app.
It can be inserted anywhere inside of the application, although if it is put inside a tab, it will be visible only when that tab is showing. I usually place it right underneath the fluidPage() definition.
This widget is to be used in development only. Once you decide on a theme, you should remove the widget and just define the theme you want using the shinytheme() function.
If you want to quickly test out different themes with an application, you can simply add themeSelector() somewhere to the UI. This will add a select box which lets you choose the theme. It will change the theme without having to reload or restart your app. You can see the theme selector in action by running the code below.
# Load packages ----------------------------------------------------------------
library(shiny)
library(ggplot2)
library(tools)
library(shinythemes)
# Load data --------------------------------------------------------------------
movies <- read.csv(file = "https://raw.githubusercontent.com/aaron-chen-angus/S3729C-Lesson-Files/6a58d56d3d42231fb011af462db7efc01537e515/movies.csv", header = TRUE, sep = ",")
# Define UI --------------------------------------------------------------------
ui <- fluidPage(
shinythemes::themeSelector(),
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "y",
label = "Y-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),
selected = "audience_score"
),
selectInput(
inputId = "x",
label = "X-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),
selected = "critics_score"
),
selectInput(
inputId = "z",
label = "Color by:",
choices = c(
"Title Type" = "title_type",
"Genre" = "genre",
"MPAA Rating" = "mpaa_rating",
"Critics Rating" = "critics_rating",
"Audience Rating" = "audience_rating"
),
selected = "mpaa_rating"
),
sliderInput(
inputId = "alpha",
label = "Alpha:",
min = 0, max = 1,
value = 0.5
),
sliderInput(
inputId = "size",
label = "Size:",
min = 0, max = 5,
value = 2
),
textInput(
inputId = "plot_title",
label = "Plot title",
placeholder = "Enter text to be used as plot title"
),
actionButton(
inputId = "update_plot_title",
label = "Update plot title"
)
),
mainPanel(
tags$br(),
tags$p(
"These data were obtained from",
tags$a("IMBD", href = "http://www.imbd.com/"), "and",
tags$a("Rotten Tomatoes", href = "https://www.rottentomatoes.com/"), "."
),
tags$p("The data represent", nrow(movies), "randomly sampled movies released between 1972 to 2014 in the United States."),
plotOutput(outputId = "scatterplot")
)
)
)
# Define server ----------------------------------------------------------------
server <- function(input, output, session) {
new_plot_title <- eventReactive(
eventExpr = input$update_plot_title,
valueExpr = {
toTitleCase(input$plot_title)
}
)
output$scatterplot <- renderPlot({
ggplot(data = movies, aes_string(x = input$x, y = input$y, color = input$z)) +
geom_point(alpha = input$alpha, size = input$size) +
labs(title = new_plot_title())
})
}
# Create the Shiny app object --------------------------------------------------
shinyApp(ui = ui, server = server)##
## Listening on http://127.0.0.1:5311
The bslib package provides tools for customizing Bootstrap themes directly from R, making it much easier to customize the appearance of Shiny apps & R Markdown documents.
The thematic package provides a functionality for simplified theming of ggplot2, lattice, and {base} R graphics as well as automatic theming of these plots within a Shiny app.
You can publish your shiny app on the shinyapps.io website.
This is a free space for hosting your apps. However, the freemium version has several limitations.
Step 1: Open RStudio and create a new Shiny app:
Step 2: Give it a name (without space), choose where to save it and click on the Create button:
Step 3: In the same way as when you open a new R Markdown document, the code for a basic Shiny app is created. Run the app by clicking on the Run App button to see the result:
Step 4: The basic app opens, publish it:
Step 5: If it is your first Shiny app, the box “Publish From Account” should be empty. Click on “Add New Account” to link the shinyapps.io account you just created:
Step 6: Click on the first alternative (ShinyApps.io):
Step 7: Click on the link to your ShinyApps account:
Step 8: Click on the Dashboard button to log in into your account:
Step 9: Click on your name and then on Tokens:
Step 10: If this is your first app, there should be no token already created. Create one by clicking on the Add Token button. Then Click on the Show button:
Step 11: Click on the Show Secret button:
Step 12: Now the code is complete (nothing is hidden anymore). Click on the Copy to clipboard button:
Step 13: Copy the code and click on the OK button:
Step 14: Go back to RStudio, paste the code in the console and run it:
Your computer is now authorized to deploy applications to your shinyapps.io account.
Step 15: Go back to the window where you can publish your app, choose a title (without space) and click on the Publish button:
Step 16: After several seconds (depending on the how complex your app is), the Shiny app should appear in your internet browser:
Step 17: You can now edit the app (or replace the entire code by another of your app), and run the app again by clicking on the Run App button. For this illustration, I just added a link for more information in the side panel:
Step 18: Check that the modifications have been taken into account (the link appears in the side panel as expected) and republish your app:
Step 19: Click on the Publish button:
Step 20: Your app is live! You can now the link in your assignment and with everyone else, and they will be able to access it and interact with it:
by Hadley Wickham
online version : https://mastering-shiny.org/
citation : Wickham, H. (2021). Mastering Shiny: Build Interactive Apps, Reports, and Dashboards Powered by R. (1st ed). O’Reilly