Es un framework de RStudio para construir aplicaciones web en R.
Características principales:
Ver
Implementación:
Levantar la aplicación/servidor:
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Ejemplo 01"),
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 100,
value = 50)
),
mainPanel(
plotOutput("distPlot")
)
)
))
server.R
library(shiny)
x <- rchisq(100000, df = 4)
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
hist(x,
breaks = seq(min(x), max(x), length.out = input$bins + 1),
col = 'darkgray', border = 'white')
})
})
Ejecutar en local (RStudio como servidor de aplicaciones shiny)
library(shiny)
runApp('C:/Alabern/Material/RShiny/_rugbcn/01_components/01_example01')
library(shiny)
setwd('C:/Alabern/Material/RShiny/_rugbcn')
runApp('./01_components/01_example01')
library(shiny)
setwd('C:/Alabern/Material/RShiny/_rugbcn/01_components/01_example01')
runApp('.', port=8200, display.mode = "showcase")
Tipos de componentes:
| server.R | ui.R |
|---|---|
| renderPlot | plotOutput |
| renderImage | imageOutput |
| renderText | textOutput |
| renderPrint | verbatimTextOutput, htmlOutput |
| renderTable | tableOutput |
| renderDataTable | dataTableOutput |
| renderUI | uiOutput |
| downloadHandler | downloadButton, downloadLink |
selectizeInput (relativamente nuevo):
Deprecated| server.R |
|---|
| reactivePlot |
| reactivePrint |
| reactiveTable |
| reactiveText |
| reactiveUI |
Link search deprecated en Shiny reference
Composición principal:
library(shiny)
shinyUI(fluidPage(
...
))
library(shiny)
shinyUI(fixedlayout(
...
))
fluidPage: A fluid page layout consists of rows which in turn include columns. Rows exist for the purpose of making sure their elements appear on the same line (if the browser has adequate width). Columns exist for the purpose of defining how much horizontal space within a 12-unit wide grid it’s elements should occupy. Fluid pages scale their components in realtime to fill all available browser width. Link reference
fixedlayout: A fixed page layout consists of rows which in turn include columns. Rows exist for the purpose of making sure their elements appear on the same line (if the browser has adequate width). Columns exist for the purpose of defining how much horizontal space within a 12-unit wide grid it’s elements should occupy. Fixed pages limit their width to 940 pixels on a typical display, and 724px or 1170px on smaller and larger displays respectively. Link reference
Comentarios:
Link Ejemplo 01 - pageWithSidebar (deprecated)
Funciones:
| Componente | Subcomponente | Link |
|---|---|---|
| navbarPage() | tabPanel(), navbarMenu() | Link reference |
| navbarMenu() | tabPanel() | Link reference |
| navlistPanel() | tabPanel() | Link reference |
| titlePanel() | Link reference | |
| sidebarLayout() | sidebarPanel() & mainPanel() (obligatorio) | Link reference |
| sidebarPanel() | Link reference | |
| mainPanel() | Link reference | |
| tabsetPanel() | Link reference | |
| tabPanel() | Link reference |
Otras funciones:
Nuevas funciones Shiny 0.10:
Link realease notes shiny 0.10
ui.r
...
uiOutput("IDDynamicInput")
...
server.r
...
output$IDDynamicInput = renderUI({
if (input$tabpanels!=2) return()
sliderInput(inputId="maxGraphMovies", label="Numero de nodos", value=maxGraphMovies, min=2, max=50, step=1)
})
...
if (!is.null(input$maxGraphMovies)) maxGraphMovies <<- input$maxGraphMovies
...
Herramientas para controlar el flujo de cálculo:
Otros: observe, flushReact
** Usamos funciones -Output en ui.R para colocar objectos “reactive”. ** Usamos funciones render- en server.R para que Shiny sepa como crear estos objectos “reactive”. ** Las expresiones reactivas van entre {} dentro de las funciones render-. ** Salvamos las render- expressions en el output list. ** Creamos reactividad cada vez que incluymos un input en una expression render-. ** Una “reactive expression” (reactive({})) toma inputs o valores de otra “reactive expression” y retorna nuevos valores. ** Una “reactive expression” guarda sus resultaos, y solo se recalcula si algun input se ha modificado. ** Solo podemos llamar a “reactive expression” dentro de otra “reactive expression” o dentro de funciones render-.
fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))
shinyServer(function(input, output) {
currentFib <- reactive({ fib(as.numeric(input$n)) })
output$nthValue <- renderText({ currentFib() })
output$nthValueInv <- renderText({ 1 / currentFib() })
})
# Separate calls to isolate -------------------------------
x <- isolate({ input$xSlider }) + 100
y <- isolate({ input$ySlider }) * 2
z <- x/y
# Single call to isolate ----------------------------------
isolate({
x <- input$xSlider + 100
y <- input$ySlider * 2
z <- x/y
})
# Single call to isolate, use return value ----------------
z <- isolate({
x <- input$xSlider + 100
y <- input$ySlider * 2
x/y
})
# Compartidas para todas las sessiones
varSharedA <- 1
varSharedB <- 1
shinyServer(function(input, output) {
# Propias de cada sesion
varNonShared <- 1 # Propia de la sesion
varSharedA <<- varSharedA + 1 # Compartida entre sesiones
varSharedB <- varSharedB + 1 # Propia de la sesion pero inicializada con la compartida entre sesiones
...
})
varA <- 1
varB <- 1
listA <- list(X=1, Y=2)
listB <- list(X=1, Y=2)
shinyServer(function(input, output) {
# Create a local variable varA, which will be a copy of the shared variable
# varA plus 1. This local copy of varA is not be visible in other sessions.
varA <- varA + 1
# Modify the shared variable varB. It will be visible in other sessions.
varB <<- varB + 1
# Makes a local copy of listA
listA$X <- 5
# Modify the shared copy of listB
listB$X <<- 5
# ...
})
...
shinyServer(function(input, output, session) {
startTime <- Sys.time()
...
output$urlText <- renderText({
paste(sep = "",
"protocol: ", session$clientData$url_protocol, "\n",
"hostname: ", session$clientData$url_hostname, "\n",
"pathname: ", session$clientData$url_pathname, "\n",
"port: ", session$clientData$url_port, "\n",
"search: ", session$clientData$url_search, "\n",
"startTime: ", startTime, "\n"
)
})
...
})
Passar de ui.R a www/index.html
(Ver ejemplos en local)
(Ver ejemplos en local)
R MarkDown outputs que permiten runtime shiny:
Chunk R
inputPanel(
selectInput("n_breaks", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20),
sliderInput("bw_adjust", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
)
renderPlot({
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust)
lines(dens, col = "blue")
})
Chunk R
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")
})
},
options = list(height = 500)
)
Set up
kmeans_cluster <- function(dataset) {
require(shiny)
shinyApp(
ui = fluidPage(responsive = FALSE,
fluidRow(style = "padding-bottom: 20px;",
column(4, selectInput('xcol', 'X Variable', names(dataset))),
column(4, selectInput('ycol', 'Y Variable', names(dataset),
selected=names(dataset)[[2]])),
column(4, numericInput('clusters', 'Cluster count', 3,
min = 1, max = 9))
),
fluidRow(
plotOutput('kmeans', height = "400px")
)
),
server = function(input, output, session) {
# Combine the selected variables into a new data frame
selectedData <- reactive({
dataset[, c(input$xcol, input$ycol)]
})
clusters <- reactive({
kmeans(selectedData(), input$clusters)
})
output$kmeans <- renderPlot(height = 400, {
par(mar = c(5.1, 4.1, 0, 1))
plot(selectedData(),
col = clusters()$cluster,
pch = 20, cex = 3)
points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
})
},
options = list(height = 500)
)
}
Chunk R
library(rmdexamples)
kmeans_cluster(iris)
Chunk R
shinyAppDir(
system.file("examples/06_tabsets", package="shiny"),
options=list(
width="100%", height=700
)
)
La opción existente antes para incrustar Shiny dentro de documentos html era vía iframe. Esta opción es menos limpia, pero permite separar servidor de aplicaciones shiny de la presentación.
Sin chunk
<iframe src="http://spark.rstudio.com/rocalabern/01_fluidlayout/"
style="width: 940px; height: 600px"></iframe>
Links sobre Documentos interactivos:
Listado de posibilidades para crear aplicaciones web
Shiny:
Not Shiny:
Galleries with source code: