Last active
August 29, 2015 14:01
-
-
Save trestletech/629d3f2c710db719f89f to your computer and use it in GitHub Desktop.
Slides from RStudio's presentation on Shiny at R/Finance 2014. Hosted version available here: https://trestletech.shinyapps.io/rfinance2014/an-introduction-to-rstudio-shiny.Rmd#1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.Rproj.user | |
.Rhistory | |
.RData |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
title: "An Introduction to RStudio Shiny" | |
author: "R/Finance 2014" | |
date: "Friday, May 16, 2014" | |
output: | |
ioslides_presentation: | |
self_contained: true | |
runtime: shiny | |
--- | |
<style type="text/css"> | |
slides > slide:before { | |
font-size: 12pt; | |
content: 'http://bit.ly/shinyRfin'; | |
position: absolute; | |
text-align: center; | |
bottom: 15px; | |
left: 50%; | |
margin-left: -300px; | |
width: 600px; | |
line-height: 1.9; | |
} | |
div.img-col{ | |
text-align: center; | |
font-size: 14pt; | |
} | |
a { | |
border-bottom: none !important; | |
} | |
.wrapper { | |
margin: 70px auto; | |
position: relative; | |
z-index: 90; | |
} | |
.ribbon-wrapper-green { | |
width: 145px; | |
height: 148px; | |
overflow: hidden; | |
position: absolute; | |
top: -3px; | |
right: -3px; | |
} | |
.ribbon-green { | |
font: bold 15px Sans-Serif; | |
color: #333; | |
text-align: center; | |
text-shadow: rgba(255,255,255,0.5) 0px 1px 0px; | |
-webkit-transform: rotate(45deg); | |
-moz-transform: rotate(45deg); | |
-ms-transform: rotate(45deg); | |
-o-transform: rotate(45deg); | |
position: relative; | |
padding: 7px 0; | |
left: -25px; | |
top: 45px; | |
width: 220px; | |
background-color: #7ADCBF; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#8AACDF), to(#658FBE)); | |
background-image: -webkit-linear-gradient(top, #8AACDF, #658FBE); | |
background-image: -moz-linear-gradient(top, #8AACDF, #658FBE); | |
background-image: -ms-linear-gradient(top, #8AACDF, #658FBE); | |
background-image: -o-linear-gradient(top, #8AACDF, #658FBE); | |
color: #6a6340; | |
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.3); | |
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.3); | |
box-shadow: 0px 0px 3px rgba(0,0,0,0.3); | |
} | |
.ribbon-green:before, .ribbon-green:after { | |
content: ""; | |
border-top: 3px solid #00896e; | |
border-left: 3px solid transparent; | |
border-right: 3px solid transparent; | |
position:absolute; | |
bottom: -3px; | |
} | |
.ribbon-green:before { | |
left: 0; | |
} | |
.ribbon-green:after { | |
right: 0; | |
} | |
</style> | |
Motivation | |
-------------------- | |
<div class="columns-2"> | |
- Analysis must be communicated | |
- Data scientists are modern diviners | |
- We sit between the tools and users | |
- Deliver static reports | |
- Impoverished perspective into analysis | |
<div class="img-col"> | |
![wizaRd](wizard.jpg) | |
<div>Altered CC image courtesy <br /> of <a href="https://www.flickr.com/photos/mcgraths/">mcgraths</a> on flickr</div> | |
</div> | |
</div> | |
## Enter Shiny | |
```{r, echo=FALSE} | |
source("retirement.R") | |
shinyApp(ui=retirementApp$ui, | |
server=retirementApp$server, | |
options=retirementApp$options) | |
``` | |
## About Shiny | |
- Interactive web application framework for R | |
- Create and share applications with others | |
- Open Source (GPL v3) R package | |
- Expects no knowledge of web technologies like HTML, CSS, or JavaScript (but you can leverage them, if you know them) | |
- Can create autonomous webpages, or embedded interactive widgets in rmarkdown | |
- A Shiny app consists of two parts: a user interface (UI) and a server. | |
## Example Shiny App -- `ui.R` | |
```r | |
fluidPage( | |
# Create a select drop-down | |
selectInput("region", "Region:", | |
choices = colnames(WorldPhones)), | |
# A place-holder for a plot to be created | |
plotOutput("phonePlot") | |
) | |
``` | |
<hr> | |
```{r} | |
library(datasets) | |
head(WorldPhones, n=2) | |
``` | |
## Example Shiny App -- `server.R` | |
```r | |
function(input, output) { | |
# Generate a plot named "phonePlot" | |
output$phonePlot <- renderPlot({ | |
# Create a barplot for the selected region | |
barplot(WorldPhones[,input$region]*1000, | |
ylab = "Number of Telephones", xlab = "Year") | |
}) | |
} | |
``` | |
## Example Shiny App | |
```{r, echo=FALSE} | |
shinyApp( | |
ui = fluidPage( | |
selectInput("region", "Region:", | |
choices = colnames(WorldPhones)), | |
plotOutput("phonePlot") | |
), | |
server = function(input, output) { | |
output$phonePlot <- renderPlot({ | |
barplot(WorldPhones[,input$region]*1000, | |
ylab = "Number of Telephones", xlab = "Year", | |
main= paste("Phones in", input$region)) | |
}) | |
}, | |
options = list(height = 500) | |
) | |
``` | |
## Examples -- Powerful UI | |
<a href="http://shiny.rstudio.com/gallery/update-input-demo.html">![widgets](widgets.png)</a> | |
<a href="http://shiny.rstudio.com/gallery/basic-datatable.html">![data tables](datatable.png)</a> | |
<a href="https://jcheng.shinyapps.io/superzip/">![leaflet](leaflet.png)</a> | |
<a href="http://spark.rstudio.com/trestletech/3dscatter/">![rgl](rgl.png)</a> | |
## Examples -- The Full Power of R | |
<div class="columns-2"> | |
<a href="http://shiny.rstudio.com/gallery/kmeans-example.html">![kmeans](kmeans.png)</a> | |
<a href="http://shiny.rstudio.com/gallery/retirement-simulation.html">![retirement](retirement.png)</a> | |
- Simply an R package | |
- Existing R code can be used with Shiny | |
- HPC, parallel, etc. | |
- Can load-balance users across multiple Shiny processes (Pro only) | |
</div> | |
## Examples -- Rich Interactivity | |
<a href="http://shiny.rstudio.com/gallery/google-charts.html">![google vis](googlevis.png)</a> | |
<a href="http://shiny.rstudio.com/gallery/nvd3-line-chart-output.html">![nvd3](nvd3.png)</a> | |
<a href="http://ggvis.rstudio.com/">![ggvis](ggvis.png)</a> | |
## Examples -- Shiny Server Pro | |
<div class="columns-2"> | |
<a href="http://shiny.rstudio.com/gallery/personalized-ui.html">![sales](sales.png)</a> | |
<a href="http://shiny.rstudio.com/gallery/authentication-and-database.html">![hflights](hflights.png)</a> | |
- Shiny Server OS is free and AGPL v3 | |
Shiny Server Pro includes: | |
- Authentication (LDAP, Active Directory, Google, etc.) | |
- Scaling across multiple processes | |
- Administrative dashboard for monitoring | |
- Security with SSL | |
- Priority support | |
</div> | |
<div class="ribbon-wrapper-green"><div class="ribbon-green">RStudio Pro, too!</div></div> | |
## Additional Resources | |
- Shiny Developer Center - http://shiny.rstudio.com | |
- [Stack Overflow - "shiny" tag](http://stackoverflow.com/questions/tagged/shiny) | |
- ["Shiny Discuss" Mailing List](https://groups.google.com/d/forum/shiny-discuss) | |
- ***Come meet us!*** | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(shiny) | |
paramNames <- c("start_capital", "annual_mean_return", "annual_ret_std_dev", | |
"annual_inflation", "annual_inf_std_dev", "monthly_withdrawals", "n_obs", | |
"n_sim") | |
# Define server logic required to generate and plot a random distribution | |
# | |
# Idea and original code by Pierre Chretien | |
# Small updates by Michael Kapler | |
# | |
simulate_nav <- function(start_capital = 2000000, annual_mean_return = 5.0, | |
annual_ret_std_dev = 7.0, annual_inflation = 2.5, | |
annual_inf_std_dev = 1.5, monthly_withdrawals = 1000, | |
n_obs = 20, n_sim = 200) { | |
#------------------------------------- | |
# Inputs | |
#------------------------------------- | |
# Initial capital | |
start.capital = start_capital | |
# Investment | |
annual.mean.return = annual_mean_return / 100 | |
annual.ret.std.dev = annual_ret_std_dev / 100 | |
# Inflation | |
annual.inflation = annual_inflation / 100 | |
annual.inf.std.dev = annual_inf_std_dev / 100 | |
# Withdrawals | |
monthly.withdrawals = monthly_withdrawals | |
# Number of observations (in Years) | |
n.obs = n_obs | |
# Number of simulations | |
n.sim = n_sim | |
#------------------------------------- | |
# Simulation | |
#------------------------------------- | |
# number of months to simulate | |
n.obs = 12 * n.obs | |
# monthly Investment and Inflation assumptions | |
monthly.mean.return = annual.mean.return / 12 | |
monthly.ret.std.dev = annual.ret.std.dev / sqrt(12) | |
monthly.inflation = annual.inflation / 12 | |
monthly.inf.std.dev = annual.inf.std.dev / sqrt(12) | |
# simulate Returns | |
monthly.invest.returns = matrix(0, n.obs, n.sim) | |
monthly.inflation.returns = matrix(0, n.obs, n.sim) | |
monthly.invest.returns[] = rnorm(n.obs * n.sim, mean = monthly.mean.return, sd = monthly.ret.std.dev) | |
monthly.inflation.returns[] = rnorm(n.obs * n.sim, mean = monthly.inflation, sd = monthly.inf.std.dev) | |
# simulate Withdrawals | |
nav = matrix(start.capital, n.obs + 1, n.sim) | |
for (j in 1:n.obs) { | |
nav[j + 1, ] = nav[j, ] * (1 + monthly.invest.returns[j, ] - monthly.inflation.returns[j, ]) - monthly.withdrawals | |
} | |
# once nav is below 0 => run out of money | |
nav[ nav < 0 ] = NA | |
# convert to millions | |
nav = nav / 1000000 | |
return(nav) | |
} | |
plot_nav <- function(nav) { | |
layout(matrix(c(1,2,1,3),2,2)) | |
palette(c("black", "grey50", "grey30", "grey70", "#d9230f")) | |
# plot all scenarios | |
matplot(nav, | |
type = 'l', lwd = 0.5, lty = 1, col = 1:5, | |
xlab = 'Months', ylab = 'Millions', | |
main = 'Projected Value of Initial Capital') | |
# plot % of scenarios that are still paying | |
p.alive = 1 - rowSums(is.na(nav)) / ncol(nav) | |
plot(100 * p.alive, las = 1, xlab = 'Months', ylab = 'Percentage Paying', | |
main = 'Percentage of Paying Scenarios', ylim=c(0,100)) | |
grid() | |
last.period = nrow(nav) | |
# plot distribution of final wealth | |
final.nav = nav[last.period, ] | |
final.nav = final.nav[!is.na(final.nav)] | |
if(length(final.nav) == 0) return() | |
plot(density(final.nav, from=0, to=max(final.nav)), las = 1, xlab = 'Final Capital', | |
main = paste0('Distribution of Final Capital\n', 100 * p.alive[last.period], '% are still paying')) | |
grid() | |
} | |
renderInputs <- function(prefix) { | |
wellPanel( | |
fluidRow( | |
column(6, | |
sliderInput(paste0(prefix, "_", "n_obs"), "Number of observations (in Years):", min = 0, max = 40, value = 20), | |
sliderInput(paste0(prefix, "_", "start_capital"), "Initial capital invested :", min = 100000, max = 10000000, value = 2000000, step = 100000, format="$#,##0", locale="us"), | |
sliderInput(paste0(prefix, "_", "annual_mean_return"), "Annual investment return (in %):", min = 0.0, max = 30.0, value = 5.0, step = 0.5), | |
sliderInput(paste0(prefix, "_", "annual_ret_std_dev"), "Annual investment volatility (in %):", min = 0.0, max = 25.0, value = 7.0, step = 0.1) | |
), | |
column(6, | |
sliderInput(paste0(prefix, "_", "annual_inflation"), "Annual inflation (in %):", min = 0, max = 20, value = 2.5, step = 0.1), | |
sliderInput(paste0(prefix, "_", "annual_inf_std_dev"), "Annual inflation volatility. (in %):", min = 0.0, max = 5.0, value = 1.5, step = 0.05), | |
sliderInput(paste0(prefix, "_", "monthly_withdrawals"), "Monthly capital withdrawals:", min = 1000, max = 100000, value = 10000, step = 1000, format="$#,##0", locale="us",), | |
sliderInput(paste0(prefix, "_", "n_sim"), "Number of simulations:", min = 0, max = 2000, value = 200) | |
) | |
) | |
) | |
} | |
retirementApp <- list( | |
ui = fluidPage(theme="simplex.min.css", | |
tags$style(type="text/css", | |
"label {font-size: 12px;}", | |
".recalculating {opacity: 1.0;}" | |
), | |
fluidRow( | |
column(6, renderInputs("a")), | |
column(6, | |
plotOutput("a_distPlot", height = "400px") | |
) | |
), | |
hr(), | |
p("An adaptation of the", | |
tags$a(href="http://glimmer.rstudio.com/systematicin/retirement.withdrawal/", "retirement app"), | |
"from", | |
tags$a(href="http://systematicinvestor.wordpress.com/", "Systematic Investor"), ".") | |
), | |
server = function(input, output, session) { | |
getParams <- function(prefix) { | |
input[[paste0(prefix, "_recalc")]] | |
params <- lapply(paramNames, function(p) { | |
input[[paste0(prefix, "_", p)]] | |
}) | |
names(params) <- paramNames | |
params | |
} | |
# Function that generates scenarios and computes NAV. The expression | |
# is wrapped in a call to reactive to indicate that: | |
# | |
# 1) It is "reactive" and therefore should be automatically | |
# re-executed when inputs change | |
# | |
navA <- reactive(do.call(simulate_nav, getParams("a"))) | |
navB <- reactive(do.call(simulate_nav, getParams("b"))) | |
# Expression that plot NAV paths. The expression | |
# is wrapped in a call to renderPlot to indicate that: | |
# | |
# 1) It is "reactive" and therefore should be automatically | |
# re-executed when inputs change | |
# 2) Its output type is a plot | |
# | |
output$a_distPlot <- renderPlot({ | |
plot_nav(navA()) | |
}) | |
output$b_distPlot <- renderPlot({ | |
plot_nav(navB()) | |
}) | |
}, | |
options = list(height = 500) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Version: 1.0 | |
RestoreWorkspace: Default | |
SaveWorkspace: Default | |
AlwaysSaveHistory: Default | |
EnableCodeIndexing: Yes | |
UseSpacesForTab: Yes | |
NumSpacesForTab: 2 | |
Encoding: UTF-8 | |
RnwWeave: Sweave | |
LaTeX: pdfLaTeX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style type="text/css"> | |
slides > slide:before { | |
font-size: 12pt; | |
content: 'http://bit.ly/shinyRfin'; | |
position: absolute; | |
text-align: center; | |
bottom: 15px; | |
left: 50%; | |
margin-left: -300px; | |
width: 600px; | |
line-height: 1.9; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment