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.
- Pensamos qué queremos mostrar
- Escribimos código estático para un caso particular.
- Pensamos qué partes queremos generalizar.
- Armamos una función que tome como parámetros aquello que generalizamos
- Armamos un shiny estático que nos muestre el resultado de la función con parámetros fijos
- Agregamos los inputs en el ui
- reemplazamos los parámetros fijos por los de input en el server
- 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
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==