Building with Shiny:
Taking R to the Web
https://slides.com/alexpawlowski/building-with-shiny/live/
29 April 2016
Knoxville R Users Group
@alexpawlowski
Alex Pawlowski
- Overview of Shiny
- Github
- Background of Clean Power Plan
- Goal of myCPP
- EIA API
- myCPP Tool v1 Demo
- GitBook
- New!
- Shiny Modules
- Shameless Plugs
Outline
Building with Shiny
taking R to the web
- Framework developed by
- take R code and make a web "app" quickly
- ui.R
- simple input and output setup
- server.R
- reactivity for R
- ui.R
What
- can easily extend/expand
- multiple tabs
- control reactivity
- easy deployment with shinyapps.io, but can run shiny server on web service of choice
1
Capabilities
Building with Shiny
taking R to the web
ui.R
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna odio, aliquam vulputate faucibus id, elementum lobortis felis. Mauris urna dolor, placerat ac sagittis quis.
server.R
# ui.R
## Libraries ----
library(shiny)
library(plotly)
library(leaflet)
library(maps)
shinyUI(fluidPage(theme = "bootstrap.css",
# Google Analytics
tags$head(includeScript("www/google-analytics.js")),
# Application title
HTML('<img src="logo.svg" style = "max-height:130px" width = "100%"/>'),
fluidRow(column(12, align ="center",
h3("A Clean Power Plan Evaluation Tool")
)),
# ...
fluidRow(
selectizeInput("stateInput", #inputID
label = "State", #label
choices = NULL,
selected = "Alabama",
multiple = FALSE,
options = list(placeholder = 'select a state name'))
),
# ...
))
# server.R
## Libraries ----
library(shiny)
library(plotly)
library(leaflet)
library(maps)
## Non-Reactive ---
# ...
### Plant Location Data
geodata <- read.csv("data/plantgeodata.csv")
# ...
## Reactive ---
shinyServer(function(input, output, session) {
updateSelectizeInput(session,
'stateInput',
choices = statenames, #must be a character vector!!! http://shiny.rstudio.com/articles/selectize.html
selected = "Alabama",
server = TRUE)
output$NGCCSlider <- renderUI({
sliderInput("NGCCCap",
"NGCC Average Capacity Factor (%)",
min = 0,
max = 90,
value = generationDataCleaned[input$stateInput, "NGCCcapFactor"] * 100,
step = 1,
width = '1000px')
})
# ...
output$ratePlotly <- renderPlotly({
r <- plot_ly(result(),
type = "bar", # all "bar" attributes: https://plot.ly/r/reference/#bar
orientation = "h",
x = Rate, # more about bar's "x": /r/reference/#bar-x
y = Name, # more about bar's "y": /r/reference/#bar-y
name = "lbsCO2/MWh",
opacity = 0.7, # more about bar's "name": /r/reference/#bar-name
marker = list( # marker is a named list, valid keys: /r/reference/#bar-marker
color=c("517C96","FF8200") # more about marker's "color" attribute: /r/reference/#bar-marker-color
))
r <- add_trace(x = c(result()[1,5],result()[1,5]), type = "line",
marker = list(
color="red",
size = 0
),
line = list( # marker is a named list, valid keys: /r/reference/#bar-marker
color="red",
width = 6
),
name = "Goal"
)
r <- layout(r, # all of layout's properties: /r/reference/#layout
xaxis = list( # layout's xaxis is a named list. List of valid keys: /r/reference/#layout-xaxis
title = "" # xaxis's title: /r/reference/#layout-xaxis-title
),
yaxis = list( # layout's yaxis is a named list. List of valid keys: /r/reference/#layout-yaxis
title = "lbsCO2/MWh" # yaxis's title: /r/reference/#layout-yaxis-title
),
margin = list(
l = 120
)
)
})
}) /end reactive
Building with Shiny
taking R to the web
- Leveraging R with Shiny framework, while collaborating with a team
- opportunity to introduce version control
- introduce team to open source community
Goal
- too many things introduced at a time
- learning R
- using RStudio
- learning Shiny
- learning git, github
- "version control" :: emails
- zip files
- merge was fun...
1
Reality
Building with Shiny
taking R to the web
Clean Power Plan
- Effort to cut US power plant emissions by 32% from 2005 levels in 2030 with state-specific plans
- Implementation begins in 2022
- Provide states flexibility in energy options to meet plan
What is it?
Timeline
Building with Shiny
taking R to the web
- June 2014, proposed
- Aug 2015, announced
- Oct 2015, 24 states sue
- Feb 9, 2016, Supreme Court stayed plan pending review
- June 2016 - suit to be heard in DC District Court
States' Views on Clean Power Plan
Goal of myCPP
- easy to use, intuitive tool for policy stakeholders to understand potential strategies to meet CPP
- use potential strategy to begin more detailed feasibility
- help users visualize current energy sources in production and emissions impacts
Defined
- Costs of power facilities aren't considered
- costs can vary per state, incentives as well
- proprietary concerns
- wrong numbers can be worse than having none
- energy from across states not currently considered
1
Limitations
Building with Shiny
taking R to the web
Data
- REST API
- return JSON or XML
- use plant ID to send request
- Data of interest
- location of plant
- Data not used
- historical energy production
API
- Real data of interest locked away in excel docs (that needed formatting anyhow)
- Form 860 - Generation
- Form 923 - Ops
- Data of interest
- heat rate of combustion plants
- energy use / plant / state
- energy demand
1
Excel forms :(
Building with Shiny
taking R to the web
- idea to initial setup: couple hours
- time to v.1
- a lot of love
- deadlines
moved up
quickly, difficult for best diffusion of work
Speed Development
Open Source Tool built on Open Source Tools
Benefits
Building with Shiny
taking R to the web
Building with Shiny
taking R to the web
- great for documentation
- searchable
- integrates with github (uses Git)
- responsive
- easily hook to custom domain
- Written in Markdown
- customize CSS
Gitbook
Features
Building with Shiny
taking R to the web
The Team
Alex Pawlowski
Justin Knowles
Michelle Halsted
Jessica Velez
Sarah Eichler-Wood
Emilio Ramirez
New!
- Shiny v0.13.0 20 Jan 2016 released a bombshell of updates
- Gadgets
- interactive locally-run data analysis
- Gadgets
Shiny Modules
- Aimed to help us reduce complexity within server.R script - "abstract", as well as easily reuse between projects
Building with Shiny
taking R to the web
library(shiny)
source("linked_scatter.R")
ui <- fixedPage(
h2("Module example"),
linkedScatterUI("scatters"),
textOutput("summary")
)
server <- function(input, output, session) {
df <- callModule(linkedScatter, "scatters", reactive(mpg),
left = reactive(c("cty", "hwy")),
right = reactive(c("drv", "hwy"))
)
output$summary <- renderText({
sprintf("%d observation(s) selected", nrow(dplyr::filter(df(), selected_)))
})
}
shinyApp(ui, server)
example from RStudio
app.R
["helper"].R
library(shiny)
library(ggplot2)
linkedScatterUI <- function(id) {
ns <- NS(id)
fluidRow(
column(6, plotOutput(ns("plot1"), brush = ns("brush"))),
column(6, plotOutput(ns("plot2"), brush = ns("brush")))
)
}
linkedScatter <- function(input, output, session, data, left, right) {
# Yields the data frame with an additional column "selected_"
# that indicates whether that observation is brushed
dataWithSelection <- reactive({
brushedPoints(data(), input$brush, allRows = TRUE)
})
output$plot1 <- renderPlot({
scatterPlot(dataWithSelection(), left())
})
output$plot2 <- renderPlot({
scatterPlot(dataWithSelection(), right())
})
return(dataWithSelection)
}
scatterPlot <- function(data, cols) {
ggplot(data, aes_string(x = cols[1], y = cols[2])) +
geom_point(aes(color = selected_)) +
scale_color_manual(values = c("black", "#66D65C"), guide = FALSE)
}
Building with Shiny
taking R to the web
Building with Shiny
taking R to the web
on
Join 330 Developers in Knoxville
28 April, 2nd Quarterly Meetup!
Links
mycpp.gitbooks.io/mycpp/content/
bccpp.shinyapps.io/mycpp/
mycpp
Copy of Building With Shiny
By Alex Pawlowski
Copy of Building With Shiny
Short talk about lessons learned to lead a team to develop an interactive visualization tool using the Shiny Framework in R.
- 808