Uploads and Downloads
En el Capítulo 9 el autor explica como lxs usuarixs de una App pueden interactuar con ella, subiendo o descargando diferentes tipos de archivos.
Esta posibilidad habilita una interacción mucho más amplia con la App, permitiendo obtener un insumo de parte de quien la esta usando, asi como brindarle la opción de descargar información de la misma.
A continuación veremos más en detalle de que se trata:
La función para subir un archivo es fileInput() y tiene dos componentes indispensables: id y label.
fileInput(“Id”, “Label”)
Podemos incorporar otros argumentos complementarios para definir más detalles, tales como
multiple: para permitir cargar más de un archivo;
accept: definimos los tipos de archivo que se pueden cargar (csv, tsv, image/*);
buttonLabel: la etiqueta que aparece en el botón de descarga;
entre otros.
La función fileInput() utilizada en la UI devuelve un dataframe de cuatro columnas:
name: el nombre del archivo original en la computadora de quien lo sube;
size: tamaño del archivo en bytes. Por defecto el límite son 5MB si bien se puede incrementar mediante la opción options shiny.maxRequestSize al comienzo de Shiny. Ej options(shiny.maxRequestSize = 10 * 1024^2).
type: el tipo de archivo;
datapath: el path donde la data se guarda en el server. El path es efímero, y si un archivo nuevo se sube, el anterior se borra.
App para subir archivo, con un Output que permite ver las columnas del fileInput()
Se utilizan las opciones buttonLabel -agrega el boton para cargar- y multiple -permite cargar varios archivos-
El resultado del código: https://hadley.shinyapps.io/ms-upload/
Tenemos que tener en cuenta:
En la UI la opción accept indica los tipos de archivos que se permiten cargar.
En el Server incorpora un req(input$upload) para asegurarnos que el código espera hasta que se cargue el primer archivo.
Resultado del código: https://hadley.shinyapps.io/ms-upload-validate.
Aclaración: file_extDevuelve las extensiones de archivo
Se presentan dos opciones para operacionalizar las descargas:
downloadButton(id)
downloadLink(id)
Al igual que en los actionButtons() podemos incorporar argumentos extra para personalizar su apriencia como class o icon tal como vimos en el Capítulo 2
El downloadButton() no tiene su propio render. Para ello utilizamos downloadHandler(), cuyos argumentos principales son:
filename: es una función sin argumentos cuyo objetivo es crear el nombre que se mostrará al usuario en el cuadro de dialogo de descarga;
content: es una función con un argumento -file- que es el path para guardar el archivo que será enviado al usuarix.
El código que se muestra a continuación permite crear la App para descargar un dataset del paquete package.
La incorporación de validate() solo habilita la descarga de archivos que sean dataframes.
Les comparto una App que arme para analizar las diferencias de género existentes en el Mercado de Trabajo de Argentina y que permite descargar las tablas teniendo en cuenta los filtros aplicados.
Una posibilidad es descargar un reporte que surge de la interacción con la App. Esto puede lograrse mediante un documento RMarkdown:
Podemos usar parametros definidos desde el YAML (params:), que luego utilizamos desde params$year, params$region, etc.
En el downloadHander(), mediante el argumento content llamamos a rmarkdown::render().
El siguiente código nos muestra el ejemplo de App para descargar el reporte de nuestra interacción en ella.
1 - RMarkdown corre desde el directorio de trabajo actual y esto puede fallar en algunos entornos (por ej shinyapps.io). Una solución es copiar el informe a un directorio temporal al comienzo de la Shiny (fuera del server) y luego reemplazar report.Rmd con report_path en rmarkdown::render()
2 - Para hacer el proceso más robusto, se recomienda correr render() en una sesión separada a traves del paquete callr
Creación de una App que permite subir un archivo, transformarlo y descargarlo. Para su mejor organización se crean tres UI para cada una de esas tareas y se ensamblan al final.
La división por tareas permite al mismo tiempo organizar mejor el Server:
t.test() Necesitamos usar updateSelectInput() para que la selección de variables se ejecute luego de que se carga el archivo..png, .pdf y .svg..png a partir del paquete brickr. Agregar controles que permitan al usuario seleccionar el tamaño del mosaico y elegir si usar colores de paleta “universal” o “generic”.janitor::make_clean_names() no se corre nuevamente ante cambios de input$empty.