March 9, 2017
The input$ list stores the current value of each input object under its name
Reactivity automatically occurs when an input value is used to render an output object
# Define server function required to create the scatterplot --------
server <- function(input, output) {
# Create the scatterplot object the plotOutput function is expecting
output$scatterplot <- renderPlot(
ggplot(data = movies, aes_string(x = input$x, y = input$y,
color = input$z)) +
geom_point(alpha = input$alpha)
)
}
movies.Rdata: Data from IMDB and Rotten Tomatoes on random sample of 651 movies released in the US between 1970 and 2014
movies_01.R: Single file app for browsing movies
movies_01.RsliderInput defining the size of points (ranging from 0 to 5), see https://shiny.rstudio.com/reference/shiny/latest/sliderInput.html for help with defining a sliderInputggplot function as the size argumentSee movies_02.R
Suppose you want the option to plot only certain types of movies as well as report how many such movies are plotted:
# Select which types of movies to plot
checkboxGroupInput(inputId = "selected_type",
label = "Select movie type(s):",
choice = c("Documentary", "Feature Film", "TV Movie"),
selected = "Feature Film")
before app:
library(dplyr)
server:
# Create a subset of data filtering for chosen title types
movies_subset <- reactive({
movies %>%
filter(title_type %in% input$selected_type)
})
Note: reactive({}) creates a cached expression that knows it is out of date when input changes
Use new data frame (which is reactive) for plotting
# Create the scatterplot object the plotOutput function is expecting
output$scatterplot <- renderPlot({
ggplot(data = movies_subset(), aes_string(x = input$x, y = input$y,
color = input$z)) +
geom_point(…) +
…
})
Note: Cached - only re-run when inputs change
Use new data frame (which is reactive) also for printing number of observations
ui:
mainPanel( ... # Print number of obs plotted textOutput(outputId = "n"), ... )
server:
# Print number of movies plotted
output$n <- renderText({
counts <- movies_subset() %>%
group_by(title_type) %>%
summarise(count = n()) %>%
select(count) %>%
unlist()
paste("There are", counts, input$selected_type, "movies in this dataset.")
})
See movies_03.R
(also notice the little bit of HTML code, added for visual separation, in the mainPanel)
By using a reactive expression for the subsetted data frame, we were able to get away with subsetting once and then using the result twice
These benefits are similar to what happens when you decompose a large complex R script into a series of small functions that build on each other