Ejemplo 2. Gapminder

Construyamos nuestro propio ejemplo con los datos de Gapminder. Para eso, vamos a ver que la manera más cómoda de escribir una shiny app no es en el orden en que aparece el código final.

Al código hay que comerlo de a pedacitos.

  1. Pensamos qué queremos mostrar
  2. Escribimos código estático para un caso particular.
  3. Pensamos qué partes queremos generalizar.
  4. Armamos una función que tome como parámetros aquello que generalizamos
  5. Armamos un shiny estático que nos muestre el resultado de la función con parámetros fijos
  6. Agregamos los inputs en el ui
  7. reemplazamos los parámetros fijos por los de input en el server
  8. Agregamos texto y otros elementos ‘cosméticos’

A cada paso vamos armando un código que no falle. De esta forma es más fácil detectar los errores.

library(tidyverse)
library(gapminder)

gapminder <- gapminder
gapminder

1. qué queremos mostrar

  • tenemos tres variables que podrían ser agrupadoras: País, continente y año
  • y tres variables que puede ser interesante representar: Esperanza de vida, población y PBI per cápita

Podríamos mostrar por ejemplo la serie de tiempo de algún país para alguna variable

2. código estático para un caso particular.

gapminder %>% 
  filter(country == 'Argentina') %>% 
  ggplot(aes(year, lifeExp))+
  geom_line()+
  geom_point()

3. partes que queremos generalizar.

  • El gráfico podría ser para cualquier país (o para un conjunto de países!)
  • podríamos elegir qué variable ver

4. función que tome como parámetros aquello que generalizamos


graficar <- function(pais, variable){
  
  gapminder %>% 
  filter(country %in% pais) %>% ## reemplace el == por %in% para que me reciba más de un país. 
  ggplot(aes_string("year", variable, color= "country"))+ ## Le cambio aes por aes_string para que me reciba el texto del input
  geom_line()+
  geom_point()
}

graficar(pais = "Argentina", variable = "lifeExp")

graficar(pais = c("Argentina","Angola"), variable = "lifeExp")

5. shiny estático con parámetros fijos

ver ejemplo_2_a

6. Agregamos los inputs en el ui

Necesitamos agregar dos inputs: País y variable.

Para opciones podemos usar selectize

selectizeInput(inputId, label, choices, selected = NULL, multiple = FALSE, options = NULL)

Podemos crear la lista de opciones de países automaticamente

unique(gapminder$country)[1:10]
 [1] Afghanistan Albania     Algeria     Angola      Argentina   Australia   Austria    
 [8] Bahrain     Bangladesh  Belgium    
142 Levels: Afghanistan Albania Algeria Angola Argentina Australia Austria ... Zimbabwe

ver ejemplo_2_b

7. reemplazamos los parámetros fijos por los de input en el server

ver ejemplo_2_c

8. Tuneamos a discreción

Una vez que tenemos un shiny funcionando como queríamos, podemos agregar tags y texto para agregar explicaciones y emprolijar los resultados.

# Headers
# shiny::tags$h1('Nivel 1')
# shiny::tags$h2('Nivel 2')
# shiny::tags$h3('Nivel 3')
# shiny::tags$h4('Nivel 4')
# shiny::tags$h5('Nivel 5')
# shiny::tags$h6('Nivel 6')

shiny::br() # espacio en blanco
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio


shiny::hr() # linea horizontal



shiny::helpText('texto para ayudas')
texto para ayudas

Multiples pestañas

También puede ocurrir que queremos mostrar varios resultados en un mismo shiny. En nuestro ejemplo, podríamos querer mostrar una tabla con los datos.

  • Para eso podemos usar tabsetPanel en el ui

  • Imaginemos que queremos tener dos tabs: Una con el gráfico, y otra con una tabla de resultados:

Entonces, en el shiny debemos agregar:

 mainPanel(
      tabsetPanel(type = "tabs",
                  tabPanel("Gráfico", plotOutput("grafico")),
                  tabPanel("Tabla", tableOutput("tabla"))
      )

    )

Mientras que en el server debemos generar un nuevo resultado, llamado tabla con los datos

output$tabla <- renderTable({
    gapminder %>% 
        filter(country %in% input$inputPais) 
  })

ver ejemplo_2_d

LS0tCnRpdGxlOiBTaGlueSBhcHBzCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCmRhdGU6ICIiCnN1YnRpdGxlOiBQcsOhY3RpY2EgR3VpYWRhCi0tLQoKCiMjIyBFamVtcGxvIDIuIEdhcG1pbmRlciAKCkNvbnN0cnV5YW1vcyBudWVzdHJvIHByb3BpbyBlamVtcGxvIGNvbiBsb3MgZGF0b3MgZGUgR2FwbWluZGVyLiBQYXJhIGVzbywgdmFtb3MgYSB2ZXIgcXVlIGxhIG1hbmVyYSBtw6FzIGPDs21vZGEgZGUgZXNjcmliaXIgdW5hIHNoaW55IGFwcCBubyBlcyBlbiBlbCBvcmRlbiBlbiBxdWUgYXBhcmVjZSBlbCBjw7NkaWdvIGZpbmFsLiAKCj4gQWwgY8OzZGlnbyBoYXkgcXVlIGNvbWVybG8gZGUgYSBwZWRhY2l0b3MuIAoKMS4gUGVuc2Ftb3MgcXXDqSBxdWVyZW1vcyBtb3N0cmFyCjIuIEVzY3JpYmltb3MgY8OzZGlnbyBfZXN0w6F0aWNvXyBwYXJhIHVuIGNhc28gcGFydGljdWxhci4KMy4gUGVuc2Ftb3MgcXXDqSBwYXJ0ZXMgcXVlcmVtb3MgZ2VuZXJhbGl6YXIuCjQuIEFybWFtb3MgdW5hIGZ1bmNpw7NuIHF1ZSB0b21lIGNvbW8gcGFyw6FtZXRyb3MgYXF1ZWxsbyBxdWUgZ2VuZXJhbGl6YW1vcwo1LiBBcm1hbW9zIHVuIHNoaW55IGVzdMOhdGljbyBxdWUgbm9zIG11ZXN0cmUgZWwgcmVzdWx0YWRvIGRlIGxhIGZ1bmNpw7NuIGNvbiBwYXLDoW1ldHJvcyBmaWpvcwo2LiBBZ3JlZ2Ftb3MgbG9zIGlucHV0cyBlbiBlbCB1aQo3LiByZWVtcGxhemFtb3MgbG9zIHBhcsOhbWV0cm9zIGZpam9zIHBvciBsb3MgZGUgaW5wdXQgZW4gZWwgc2VydmVyCjguIEFncmVnYW1vcyB0ZXh0byB5IG90cm9zIGVsZW1lbnRvcyAnY29zbcOpdGljb3MnCgo+IEEgY2FkYSBwYXNvIHZhbW9zIGFybWFuZG8gdW4gY8OzZGlnbyBxdWUgbm8gZmFsbGUuIERlIGVzdGEgZm9ybWEgZXMgbcOhcyBmw6FjaWwgZGV0ZWN0YXIgbG9zIGVycm9yZXMuIAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2FwbWluZGVyKQoKZ2FwbWluZGVyIDwtIGdhcG1pbmRlcgpnYXBtaW5kZXIKYGBgCgoKIyMjIyAxLiBxdcOpIHF1ZXJlbW9zIG1vc3RyYXIKCi0gdGVuZW1vcyB0cmVzIHZhcmlhYmxlcyBxdWUgcG9kcsOtYW4gc2VyIGFncnVwYWRvcmFzOiBQYcOtcywgY29udGluZW50ZSB5IGHDsW8KLSB5IHRyZXMgdmFyaWFibGVzIHF1ZSBwdWVkZSBzZXIgaW50ZXJlc2FudGUgcmVwcmVzZW50YXI6IEVzcGVyYW56YSBkZSB2aWRhLCBwb2JsYWNpw7NuIHkgUEJJIHBlciBjw6FwaXRhCgoKUG9kcsOtYW1vcyBtb3N0cmFyIHBvciBlamVtcGxvIGxhIHNlcmllIGRlIHRpZW1wbyBkZSBhbGfDum4gcGHDrXMgcGFyYSBhbGd1bmEgdmFyaWFibGUKCiMjIyMgMi4gY8OzZGlnbyBfZXN0w6F0aWNvXyBwYXJhIHVuIGNhc28gcGFydGljdWxhci4KCmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb3VudHJ5ID09ICdBcmdlbnRpbmEnKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCBsaWZlRXhwKSkrCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpCmBgYAoKIyMjIyAzLiBwYXJ0ZXMgcXVlIHF1ZXJlbW9zIGdlbmVyYWxpemFyLgoKLSBFbCBncsOhZmljbyBwb2Ryw61hIHNlciBwYXJhIGN1YWxxdWllciBwYcOtcyAobyBwYXJhIHVuIGNvbmp1bnRvIGRlIHBhw61zZXMhKQotIHBvZHLDrWFtb3MgZWxlZ2lyIHF1w6kgdmFyaWFibGUgdmVyCgoKIyMjIyA0LiBmdW5jacOzbiBxdWUgdG9tZSBjb21vIHBhcsOhbWV0cm9zIGFxdWVsbG8gcXVlIGdlbmVyYWxpemFtb3MKCgpgYGB7cn0KCmdyYWZpY2FyIDwtIGZ1bmN0aW9uKHBhaXMsIHZhcmlhYmxlKXsKICAKICBnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb3VudHJ5ICVpbiUgcGFpcykgJT4lICMjIHJlZW1wbGFjZSBlbCA9PSBwb3IgJWluJSBwYXJhIHF1ZSBtZSByZWNpYmEgbcOhcyBkZSB1biBwYcOtcy4gCiAgZ2dwbG90KGFlc19zdHJpbmcoInllYXIiLCB2YXJpYWJsZSwgY29sb3I9ICJjb3VudHJ5IikpKyAjIyBMZSBjYW1iaW8gYWVzIHBvciBhZXNfc3RyaW5nIHBhcmEgcXVlIG1lIHJlY2liYSBlbCB0ZXh0byBkZWwgaW5wdXQKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkKfQoKZ3JhZmljYXIocGFpcyA9ICJBcmdlbnRpbmEiLCB2YXJpYWJsZSA9ICJsaWZlRXhwIikKZ3JhZmljYXIocGFpcyA9IGMoIkFyZ2VudGluYSIsIkFuZ29sYSIpLCB2YXJpYWJsZSA9ICJsaWZlRXhwIikKCmBgYAoKIyMjIyA1LiBzaGlueSBlc3TDoXRpY28gY29uIHBhcsOhbWV0cm9zIGZpam9zCgo+IHZlciBlamVtcGxvXzJfYQoKIyMjIyA2LiBBZ3JlZ2Ftb3MgbG9zIGlucHV0cyBlbiBlbCB1aQoKTmVjZXNpdGFtb3MgYWdyZWdhciBkb3MgaW5wdXRzOiBQYcOtcyB5IHZhcmlhYmxlLiAKClBhcmEgb3BjaW9uZXMgcG9kZW1vcyB1c2FyIFtzZWxlY3RpemVdKGh0dHBzOi8vc2hpbnkucnN0dWRpby5jb20vYXJ0aWNsZXMvc2VsZWN0aXplLmh0bWwpCgpgc2VsZWN0aXplSW5wdXQoaW5wdXRJZCwgbGFiZWwsIGNob2ljZXMsIHNlbGVjdGVkID0gTlVMTCwgbXVsdGlwbGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgb3B0aW9ucyA9IE5VTEwpYAoKUG9kZW1vcyBjcmVhciBsYSBsaXN0YSBkZSBvcGNpb25lcyBkZSBwYcOtc2VzIGF1dG9tYXRpY2FtZW50ZSAgICAgICAgICAgICAgIApgYGB7cn0KdW5pcXVlKGdhcG1pbmRlciRjb3VudHJ5KVsxOjEwXQpgYGAKCgo+IHZlciBlamVtcGxvXzJfYgoKIyMjIyA3LiByZWVtcGxhemFtb3MgbG9zIHBhcsOhbWV0cm9zIGZpam9zIHBvciBsb3MgZGUgaW5wdXQgZW4gZWwgc2VydmVyCgoKPiB2ZXIgZWplbXBsb18yX2MKCgojIyMjIDguIFR1bmVhbW9zIGEgZGlzY3JlY2nDs24KCiFbXShpbWcvcGltcC5qcGcpe3dpZHRoPTUwMH0KClVuYSB2ZXogcXVlIHRlbmVtb3MgdW4gc2hpbnkgZnVuY2lvbmFuZG8gY29tbyBxdWVyw61hbW9zLCBwb2RlbW9zIGFncmVnYXIgYHRhZ3NgIHkgdGV4dG8gcGFyYSBhZ3JlZ2FyIGV4cGxpY2FjaW9uZXMgeSBlbXByb2xpamFyIGxvcyByZXN1bHRhZG9zLgoKYGBge3J9CiMgSGVhZGVycwojIHNoaW55Ojp0YWdzJGgxKCdOaXZlbCAxJykKIyBzaGlueTo6dGFncyRoMignTml2ZWwgMicpCiMgc2hpbnk6OnRhZ3MkaDMoJ05pdmVsIDMnKQojIHNoaW55Ojp0YWdzJGg0KCdOaXZlbCA0JykKIyBzaGlueTo6dGFncyRoNSgnTml2ZWwgNScpCiMgc2hpbnk6OnRhZ3MkaDYoJ05pdmVsIDYnKQoKc2hpbnk6OmJyKCkgIyBlc3BhY2lvIGVuIGJsYW5jbwpzaGlueTo6aHIoKSAjIGxpbmVhIGhvcml6b250YWwKCnNoaW55OjpoZWxwVGV4dCgndGV4dG8gcGFyYSBheXVkYXMnKQpgYGAKCiMjIyMgTXVsdGlwbGVzIHBlc3Rhw7FhcwoKVGFtYmnDqW4gcHVlZGUgb2N1cnJpciBxdWUgcXVlcmVtb3MgbW9zdHJhciB2YXJpb3MgcmVzdWx0YWRvcyBlbiB1biBtaXNtbyBzaGlueS4gRW4gbnVlc3RybyBlamVtcGxvLCBwb2Ryw61hbW9zIHF1ZXJlciBtb3N0cmFyIHVuYSB0YWJsYSBjb24gbG9zIGRhdG9zLgoKLSBQYXJhIGVzbyBwb2RlbW9zIHVzYXIgYHRhYnNldFBhbmVsYCBlbiBlbCBgdWlgCgotIEltYWdpbmVtb3MgcXVlIHF1ZXJlbW9zIHRlbmVyIGRvcyB0YWJzOiBVbmEgY29uIGVsIGdyw6FmaWNvLCB5IG90cmEgY29uIHVuYSB0YWJsYSBkZSByZXN1bHRhZG9zOgoKRW50b25jZXMsIGVuIGVsIHNoaW55IGRlYmVtb3MgYWdyZWdhcjoKCmBgYHtyIGV2YWw9RkFMU0V9CiBtYWluUGFuZWwoCiAgICAgIHRhYnNldFBhbmVsKHR5cGUgPSAidGFicyIsCiAgICAgICAgICAgICAgICAgIHRhYlBhbmVsKCJHcsOhZmljbyIsIHBsb3RPdXRwdXQoImdyYWZpY28iKSksCiAgICAgICAgICAgICAgICAgIHRhYlBhbmVsKCJUYWJsYSIsIHRhYmxlT3V0cHV0KCJ0YWJsYSIpKQogICAgICApCgogICAgKQpgYGAKCk1pZW50cmFzIHF1ZSBlbiBlbCBzZXJ2ZXIgZGViZW1vcyBnZW5lcmFyIHVuIG51ZXZvIHJlc3VsdGFkbywgbGxhbWFkbyBfdGFibGFfIGNvbiBsb3MgZGF0b3MKCmBgYHtyLCBldmFsPUZBTFNFfQoKb3V0cHV0JHRhYmxhIDwtIHJlbmRlclRhYmxlKHsKICAgIGdhcG1pbmRlciAlPiUgCiAgICAgICAgZmlsdGVyKGNvdW50cnkgJWluJSBpbnB1dCRpbnB1dFBhaXMpIAogIH0pCgpgYGAKCgoKPiB2ZXIgZWplbXBsb18yX2QKCg==