Trabajaremos con los siguientes paquetes, les invitamos a instalarlos para seguir la clase:
install.packages(c("shiny","guaguas","dplyr","ggplot2", "calidad","survey","writexl"))library(shiny)library(guaguas)library(dplyr)library(ggplot2)library(calidad)library(survey)library(writexl)#### versión de R 4.2.3 (2023-03-15)
Contenidos de la clase
Contenidos de la clase
I - Motivación
II - Ejemplos de Shiny Apps construidas en el INE
Contenidos de la clase
I - Motivación
II - Ejemplos de Shiny Apps construidas en el INE
III - Principales características de una Shiny App
Contenidos de la clase
I - Motivación
II - Ejemplos de Shiny Apps construidas en el INE
III - Principales características de una Shiny App
IV - ¡A construir una Shiny App!
Contenidos de la clase
I - Motivación
II - Ejemplos de Shiny Apps construidas en el INE
III - Principales características de una Shiny App
IV - ¡A construir una Shiny App!
V - Tips y referencias
Contenidos de la clase
I - Motivación
II - Ejemplos de Shiny Apps construidas en el INE
III - Principales características de una Shiny App
IV - ¡A construir una Shiny App!
V - Tips y referencias
Objetivos de la clase:
Es un paquete de R, que simplifica la construcción de plataformas interactivas para personas que vienen de disciplinas lejanas a la programación web o desde la ciencia y analítica de datos
Shiny es un "wrapper" de html, css y JavaScript, los principales lenguajes para construir aplicaciones web
Interactividad!!!
Clickear, cargar datos, cambiar parámetros...
¿Para qué?
Usuarios finales
Componentes básicos de una Shiny App
Componentes básicos de una Shiny App
Componentes básicos de una Shiny App
ui: (user interface) Este objeto controla el diseño y la apariencia de la aplicación
server: Esta función contiene las instrucciones que R necesita para construir la aplicación
Componentes básicos de una Shiny App
ui: (user interface) Este objeto controla el diseño y la apariencia de la aplicación
server: Esta función contiene las instrucciones que R necesita para construir la aplicación
shinyApp(ui,server): Corre la app uniendo los dos elementos anteriores
Componentes básicos de una Shiny App
ui: (user interface) Este objeto controla el diseño y la apariencia de la aplicación
server: Esta función contiene las instrucciones que R necesita para construir la aplicación
shinyApp(ui,server): Corre la app uniendo los dos elementos anteriores
library(shiny)ui <- fluidPage()server <- function(input, output, session) { }shinyApp(ui, server)
Componentes básicos de una Shiny App
ui: (user interface) Este objeto controla el diseño y la apariencia de la aplicación
server: Esta función contiene las instrucciones que R necesita para construir la aplicación
shinyApp(ui,server): Corre la app uniendo los dos elementos anteriores
library(shiny)ui <- fluidPage()server <- function(input, output, session) { }shinyApp(ui, server)
¿Como comenzamos un proyecto en Shiny?
Componentes básicos de una Shiny App
ui: (user interface) Este objeto controla el diseño y la apariencia de la aplicación
server: Esta función contiene las instrucciones que R necesita para construir la aplicación
shinyApp(ui,server): Corre la app uniendo los dos elementos anteriores
library(shiny)ui <- fluidPage()server <- function(input, output, session) { }shinyApp(ui, server)
¿Como comenzamos un proyecto en Shiny?
Veamos el código!!!...
sidebarLayout()
ui <- fluidPage( titlePanel("Central limit theorem"), sidebarLayout( sidebarPanel( numericInput("m", "Number of samples:", 2, min = 1, max = 100) ), mainPanel( plotOutput("hist") ) ))##### * este código es solo de ejemplo, no está completo para generar una app
tabsetPanel()
ui <- fluidPage( tabsetPanel( tabPanel("Import data", fileInput("file", "Data", buttonLabel = "Upload..."), textInput("delim", "Delimiter (leave blank to guess)", ""), numericInput("skip", "Rows to skip", 0, min = 0), numericInput("rows", "Rows to preview", 10, min = 1) ), tabPanel("Set parameters"), tabPanel("Visualise results") ))##### * este código es solo de ejemplo, no está completo para generar una app
navbarPage()
ui <- fluidPage( navbarPage("App Title", tabPanel("Plot"), tabPanel("Summary"), tabPanel("Table") ))##### * este código es solo de ejemplo, no está completo para generar una app
sidebarLayout()
ui <- fluidPage( titlePanel("Central limit theorem"), sidebarLayout( sidebarPanel( numericInput("m", "Number of samples:", 2, min = 1, max = 100) ), mainPanel( plotOutput("hist") ) ))##### * este código es solo de ejemplo, no está completo para generar una app
tabsetPanel()
ui <- fluidPage( tabsetPanel( tabPanel("Import data", fileInput("file", "Data", buttonLabel = "Upload..."), textInput("delim", "Delimiter (leave blank to guess)", ""), numericInput("skip", "Rows to skip", 0, min = 0), numericInput("rows", "Rows to preview", 10, min = 1) ), tabPanel("Set parameters"), tabPanel("Visualise results") ))##### * este código es solo de ejemplo, no está completo para generar una app
navbarPage()
ui <- fluidPage( navbarPage("App Title", tabPanel("Plot"), tabPanel("Summary"), tabPanel("Table") ))##### * este código es solo de ejemplo, no está completo para generar una app
Shiny posee funciones que nos permiten agregar contenidos para mejorar nuestra ui, estas funciones son "wrapper" de html.
Shiny posee funciones que nos permiten agregar contenidos para mejorar nuestra ui, estas funciones son "wrapper" de html.
Se dividen entre INPUTS y OUTPUTS, ya que como sus nombres lo indican es donde ingresamos parametros y donde recibimos los productos procesados
Funciones que permiten al usuario ingresar parametros o información a la app, es por ello que van desde la ui al server
Parámetros básicos:
Funciones que permiten al usuario ingresar parametros o información a la app, es por ello que van desde la ui al server
Parámetros básicos:
inputId: Es el nombre que le damos al input en particular, para luego poder acceder
Funciones que permiten al usuario ingresar parametros o información a la app, es por ello que van desde la ui al server
Parámetros básicos:
inputId: Es el nombre que le damos al input en particular, para luego poder acceder
label: Es la etiqueta que el usuario lee sobre el input
Funciones que permiten al usuario ingresar parametros o información a la app, es por ello que van desde la ui al server
Parámetros básicos:
inputId: Es el nombre que le damos al input en particular, para luego poder acceder
label: Es la etiqueta que el usuario lee sobre el input
Son almacenados dentro de una lista llamada: input, para acceder a ellos debemos buscarlos en esa lista, tal y como se hace en R:
ui <- fluidPage( numericInput(inputId = "variable1",label = "Variable 1",value = 30))##### * este código es solo de ejemplo, no está completo para generar una app
input$variable1
Reciben un tipo de dato en particular, sea texto, numérico, factores o fechas, entre otros,
Los outputs se generan en el server de la aplicación y viajan hacia la ui
Al igual que los inputs los outputs son almacenados dentro de una lista, llamada: output:
Los outputs se generan en el server de la aplicación y viajan hacia la ui
Al igual que los inputs los outputs son almacenados dentro de una lista, llamada: output:
server <- function(input, output, session) {output$plot1 <- renderPlot({ grafico })}##### * este código es solo de ejemplo, no está completo para generar una app
output$plot1
Para enviar los outputs desde el server hacia el ui, la manera de hacerlo es la siguiente:
ui <-fluidPage( plotOutput("plot1"))server <- function(input, output, session) {output$plot1 <- renderPlot({ grafico })}##### * este código es solo de ejemplo, no está completo para generar una app
Usaremos el paquete guaguas
library(shiny)library(guaguas)library(dplyr)library(ggplot2)datos <- guaguas %>% dplyr::filter(n >= 100)ui <- fluidPage( titlePanel("Buscando nombres"), sidebarLayout( sidebarPanel(h3("Inputs"), selectInput(inputId = "nombre", label = "Nombres", choices = unique(datos$nombre)) ), mainPanel(h3("Outputs"), plotOutput(outputId = "frecuencia_guaguas") ) ))server <- function(input, output, session) { grafico <- datos %>% dplyr::filter(nombre == input$nombre) %>% ggplot(aes(anio,n)) + geom_line() output$frecuencia_guaguas <- renderPlot({ grafico })}shinyApp(ui, server)
Este es el error típico aprendiendo Shiny:
"Caused by error in input$nombre
:
! Can't access reactive value 'nombre' outside of reactive consumer.
ℹ Do you need to wrap inside reactive() or observe()?"
Este es el error típico aprendiendo Shiny:
"Caused by error in input$nombre
:
! Can't access reactive value 'nombre' outside of reactive consumer.
ℹ Do you need to wrap inside reactive() or observe()?"
En español:
"Provocado por error en input$nombre: ! No se puede acceder al valor reactivo 'nombre' fuera del consumidor reactivo ¿Necesita envolver dentro de reactivo() u observar()?"
Este es el error típico aprendiendo Shiny:
"Caused by error in input$nombre
:
! Can't access reactive value 'nombre' outside of reactive consumer.
ℹ Do you need to wrap inside reactive() or observe()?"
En español:
"Provocado por error en input$nombre: ! No se puede acceder al valor reactivo 'nombre' fuera del consumidor reactivo ¿Necesita envolver dentro de reactivo() u observar()?"
En sencillo:
La reactividad, es el mecanismo por el cual Shiny determina que objeto de R tiene que cambiar, cuándo el usuario realiza alguna acción o genera un input.
Estos inputs se deben tratar de manera especial, siempre "envueltos" en funciones reactivas u observadoras (ya lo veremos)
Ahora sí!
library(shiny)library(guaguas)library(dplyr)library(ggplot2)datos <- guaguas %>% dplyr::filter(n >= 100)ui <- fluidPage( titlePanel("Buscando nombres"), sidebarLayout( sidebarPanel(h3("Inputs"), selectInput(inputId = "nombre", label = "Nombres", choices = unique(datos$nombre)) ), mainPanel(h3("Outputs"), plotOutput(outputId = "frecuencia_guaguas") ) ))server <- function(input, output, session) {grafico <- reactive({datos %>% dplyr::filter(nombre == input$nombre) %>% ggplot(aes(anio,n)) + geom_line() }) output$frecuencia_guaguas <- renderPlot({ grafico() })}shinyApp(ui, server)
¿Si queremos controlar cuando se genera el gráfico? y así se pueden agregar mas nombres en la búsqueda...
¿Si queremos controlar cuando se genera el gráfico? y así se pueden agregar mas nombres en la búsqueda...
Como ya se mencionó existen dos grupos de funciones que reciben a los objetos reactivos, las funciones reactivas y las funciones que observan
¿Si queremos controlar cuando se genera el gráfico? y así se pueden agregar mas nombres en la búsqueda...
Como ya se mencionó existen dos grupos de funciones que reciben a los objetos reactivos, las funciones reactivas y las funciones que observan
A diferencia de las funciones reactivas, las funciones que observan permiten que pasen acciones secundarias, pero no generan un objeto nuevo
¿Si queremos controlar cuando se genera el gráfico? y así se pueden agregar mas nombres en la búsqueda...
Como ya se mencionó existen dos grupos de funciones que reciben a los objetos reactivos, las funciones reactivas y las funciones que observan
A diferencia de las funciones reactivas, las funciones que observan permiten que pasen acciones secundarias, pero no generan un objeto nuevo
En el siguente ejemplo podemos ver como la función observeEvent({}) recibe cómo argumento el input input$generar_gráfico, solo después de que este input sea generado, el gráfico se creará
observeEvent(input$generar_gráfico,{ output$frecuencia_guaguas <- renderPlot({grafico() }) })##### * este código es solo de ejemplo, no está completo para generar una app
¿Si queremos controlar cuando se genera el gráfico? y así se pueden agregar mas nombres en la búsqueda...
Como ya se mencionó existen dos grupos de funciones que reciben a los objetos reactivos, las funciones reactivas y las funciones que observan
A diferencia de las funciones reactivas, las funciones que observan permiten que pasen acciones secundarias, pero no generan un objeto nuevo
En el siguente ejemplo podemos ver como la función observeEvent({}) recibe cómo argumento el input input$generar_gráfico, solo después de que este input sea generado, el gráfico se creará
observeEvent(input$generar_gráfico,{ output$frecuencia_guaguas <- renderPlot({grafico() }) })##### * este código es solo de ejemplo, no está completo para generar una app
Vamos al código!!!...
library(shiny)library(guaguas)library(dplyr)library(ggplot2)## Agregamo el botón# actionButton(inputId = "generar_gráfico",label = "Generar gráfico")### Generamos un botón que controle la generación del gráfico# observeEvent(input$generar_gráfico,{ # output$frecuencia_guaguas <- renderPlot({# grafico()# })# })# isolate({grafico()})datos <- guaguas %>% dplyr::filter(n >= 100)ui <- fluidPage( titlePanel("Buscando nombres"), sidebarLayout( sidebarPanel(h3("Inputs"), selectInput(inputId = "nombre", label = "Nombres", choices = unique(datos$nombre)) ), mainPanel(h3("Outputs"), plotOutput(outputId = "frecuencia_guaguas") ) ))server <- function(input, output, session) { grafico <- reactive({datos %>% dplyr::filter(nombre == input$nombre) %>% ggplot(aes(anio,n)) + geom_line() }) output$frecuencia_guaguas <- renderPlot({ grafico() })}shinyApp(ui, server)
library(shiny)library(guaguas)library(dplyr)library(ggplot2)### permitimos que se busquen mas nombres #### selectInput(inputId = "nombre",# label = "Nombres",# choices = unique(datos$nombre),multiple = T),# datos %>% # dplyr::filter(nombre %in% input$nombre) %>%# ggplot(aes(anio,n,color=nombre)) +# geom_line()datos <- guaguas %>% dplyr::filter(n >= 100)ui <- fluidPage( titlePanel("Buscando nombres"), sidebarLayout( sidebarPanel(h3("Inputs"), selectInput(inputId = "nombre", label = "Nombres", choices = unique(datos$nombre)), actionButton(inputId = "generar_gráfico",label = "Generar gráfico") ), mainPanel(h3("Outputs"), plotOutput(outputId = "frecuencia_guaguas") ) ))server <- function(input, output, session) { grafico <- reactive({datos %>% dplyr::filter(nombre == input$nombre) %>% ggplot(aes(anio,n)) + geom_line() })observeEvent(input$generar_gráfico,{ output$frecuencia_guaguas <- renderPlot({ isolate({grafico()}) })}) }shinyApp(ui, server)
# isolate({input$valor1}) * isolate({ input$valor2})library(shiny)ui <- fluidPage( numericInput("valor1","Valor 1",value = 10), br(), br(), numericInput("valor2","Valor 2",value = 10), br(), br(), verbatimTextOutput("resultado"), br() , br() , actionButton("calc_btn","Calcular"))server <- function(input, output, session) {observeEvent(input$calc_btn,{ print(input$calc_btn) output$resultado = renderText({ input$valor1 * input$valor2 })})}shinyApp(ui, server)
La siguiente shiny App genera cálculos de estadísticas publicadas por él INE, específicamente la Encuesta Nacional Urbana de Seguridad Ciudadana
Esta app aplica el estándar de calidad definido por el INE para evaluar la calidad de las estadísticas publicadas
La siguiente shiny App genera cálculos de estadísticas publicadas por él INE, específicamente la Encuesta Nacional Urbana de Seguridad Ciudadana
Esta app aplica el estándar de calidad definido por el INE para evaluar la calidad de las estadísticas publicadas
Estos cálculos se realizan utilizando el paquete de calidad desarrollado en R que aplica el estándar
La siguiente shiny App genera cálculos de estadísticas publicadas por él INE, específicamente la Encuesta Nacional Urbana de Seguridad Ciudadana
Esta app aplica el estándar de calidad definido por el INE para evaluar la calidad de las estadísticas publicadas
Estos cálculos se realizan utilizando el paquete de calidad desarrollado en R que aplica el estándar
Este paquete es un wrapper del paquete survey aplicado al estándar INE
La siguiente shiny App genera cálculos de estadísticas publicadas por él INE, específicamente la Encuesta Nacional Urbana de Seguridad Ciudadana
Esta app aplica el estándar de calidad definido por el INE para evaluar la calidad de las estadísticas publicadas
Estos cálculos se realizan utilizando el paquete de calidad desarrollado en R que aplica el estándar
Este paquete es un wrapper del paquete survey aplicado al estándar INE
Él es Thomas Lumley, su creador
La siguiente shiny App genera cálculos de estadísticas publicadas por él INE, específicamente la Encuesta Nacional Urbana de Seguridad Ciudadana
Esta app aplica el estándar de calidad definido por el INE para evaluar la calidad de las estadísticas publicadas
Estos cálculos se realizan utilizando el paquete de calidad desarrollado en R que aplica el estándar
Este paquete es un wrapper del paquete survey aplicado al estándar INE
Él es Thomas Lumley, su creador
Veamos como funciona
library(shiny)library(calidad)library(survey)### declaramos diseño complejocom_dis <- svydesign(ids = ~Conglomerado, strata = ~VarStrat, weights = ~Fact_Pers,data = enusc)options(survey.lonely.psu = "certainty")## APP #### UI ####ui <- fluidPage( titlePanel("Probando paquete calidad del INE"), sidebarLayout(sidebarPanel( selectInput("var",label = "Variable de interés",choices = c("",names(enusc)),selected = "")), mainPanel(tableOutput("tabla") ) )) ### SERVER ####server <- function(input, output, session) { ### generamos tabla tabulado <- reactive({ calidad::assess(calidad::create_prop(var = input$var, design = com_dis)) }) output$tabla <- renderTable({ # req(input$var) tabulado() }) } shinyApp(ui, server)
library(shiny)library(calidad)library(survey)### declaramos diseño complejocom_dis <- svydesign(ids = ~Conglomerado, strata = ~VarStrat, weights = ~Fact_Pers,data = enusc)options(survey.lonely.psu = "certainty")## probando calidad calidad::assess(calidad::create_prop(var = "VP_DC", domains = "enc_region", design = com_dis))## APP #### UI ####ui <- fluidPage( titlePanel("Probando paquete calidad del INE"), sidebarLayout(sidebarPanel( selectInput("var",label = "Variable de interés",choices = c("",names(enusc)),selected = ""), # selectInput("dominio",label = "Variable desagregacion",choices = c("",names(enusc)),selected = ""), downloadButton("download_tabla","Descarga")), mainPanel(tableOutput("tabla") )))### SERVER ####server <- function(input, output, session) { # R_dominio = reactive({ # # print(input$dominio) # # if(input$dominio == ""){ # NULL # }else{ # input$dominio # } # })### generamos tabla tabulado <- reactive({ calidad::assess(calidad::create_prop(var = input$var, # domains = #R_dominio(), design = com_dis)) }) output$tabla <- renderTable({# req(input$var)tabulado() })}shinyApp(ui, server)
library(shiny)library(calidad)library(survey)### declaramos diseño complejocom_dis <- svydesign(ids = ~Conglomerado, strata = ~VarStrat, weights = ~Fact_Pers,data = enusc)options(survey.lonely.psu = "certainty")## APP #### UI ####ui <- fluidPage( titlePanel("Probando paquete calidad del INE"), sidebarLayout(sidebarPanel( selectInput("var",label = "Variable de interés",choices = c("",names(enusc)),selected = ""), selectInput("dominio",label = "Variable desagregacion",choices = c("",names(enusc)),selected = ""),# downloadButton("download_tabla","Descarga")), mainPanel(tableOutput("tabla") )))### SERVER ####server <- function(input, output, session) { R_dominio = reactive({ # print(input$dominio) if(input$dominio == ""){ NULL }else{ input$dominio } })### generamos tabla tabulado <- reactive({ calidad::assess(calidad::create_prop(var = input$var, domains = R_dominio(), design = com_dis)) }) output$tabla <- renderTable({req(input$var) # print(R_dominio) # print(R_denom)tabulado() }) # output$download_tabla <- downloadHandler( # filename = function() { # paste0("tabulado-", format(Sys.time(),"%Y-%m-%d-%H%M%S"), ".xlsx", sep="") # }, # content = function(file) { # writexl::write_xlsx(tabulado(), file) # } # )}shinyApp(ui, server)
Planificar tu app
Explorar técnicas de debugging (print() es tu copiloto)
Planificar tu app
Explorar técnicas de debugging (print() es tu copiloto)
Planificar tu app
Explorar técnicas de debugging (print() es tu copiloto)
GIT !!!
Posibilidades para montar en la web una Shiny App
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Leaflet (trabajo con mapas y datos georefenciados) https://rstudio.github.io/leaflet/shiny.html
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Leaflet (trabajo con mapas y datos georefenciados) https://rstudio.github.io/leaflet/shiny.html
Golem (Desarrollo de apps) https://thinkr-open.github.io/golem/
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Leaflet (trabajo con mapas y datos georefenciados) https://rstudio.github.io/leaflet/shiny.html
Golem (Desarrollo de apps) https://thinkr-open.github.io/golem/
Rhino (Desarrollo de apps) https://rhinoverse.dev/#rhino
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Leaflet (trabajo con mapas y datos georefenciados) https://rstudio.github.io/leaflet/shiny.html
Golem (Desarrollo de apps) https://thinkr-open.github.io/golem/
Rhino (Desarrollo de apps) https://rhinoverse.dev/#rhino
ShinyManager (autenticación) https://datastorm-open.github.io/shinymanager/
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Leaflet (trabajo con mapas y datos georefenciados) https://rstudio.github.io/leaflet/shiny.html
Golem (Desarrollo de apps) https://thinkr-open.github.io/golem/
Rhino (Desarrollo de apps) https://rhinoverse.dev/#rhino
ShinyManager (autenticación) https://datastorm-open.github.io/shinymanager/
Recursos de shiny para aprender, usar comandos:
Shinytheme (ui) https://rstudio.github.io/shinythemes/
shinydashboard (ui) https://rstudio.github.io/shinydashboard/
Leaflet (trabajo con mapas y datos georefenciados) https://rstudio.github.io/leaflet/shiny.html
Golem (Desarrollo de apps) https://thinkr-open.github.io/golem/
Rhino (Desarrollo de apps) https://rhinoverse.dev/#rhino
ShinyManager (autenticación) https://datastorm-open.github.io/shinymanager/
Recursos de shiny para aprender, usar comandos:
Trabajaremos con los siguientes paquetes, les invitamos a instalarlos para seguir la clase:
install.packages(c("shiny","guaguas","dplyr","ggplot2", "calidad","survey","writexl"))library(shiny)library(guaguas)library(dplyr)library(ggplot2)library(calidad)library(survey)library(writexl)#### versión de R 4.2.3 (2023-03-15)
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |