From 4c304e46d74ae01f124c9c56adafdb620b9c4f0f Mon Sep 17 00:00:00 2001 From: Mauricio Vargas Date: Tue, 16 Aug 2022 12:27:51 -0400 Subject: [PATCH 1/2] traduccion parcial cap 4 --- 04-basic-ui.Rmd | 296 +++++++++++++++++++++++++++++------------------- 1 file changed, 180 insertions(+), 116 deletions(-) diff --git a/04-basic-ui.Rmd b/04-basic-ui.Rmd index d8fb477a..b922a2f7 100644 --- a/04-basic-ui.Rmd +++ b/04-basic-ui.Rmd @@ -1,4 +1,4 @@ -# Basic UI +# Interfaz de Usuario Básica ```{r, include = FALSE} source("_common.R") @@ -6,71 +6,92 @@ source("demo.R") ``` **CAPÍTULO EN PROCESO DE TRADUCCIÓN** -## Introduction +## Introducción -Now that you have a basic app under your belt, we can start to explore the details that make Shiny tick. -As you saw in the previous chapter, Shiny encourages separation of the code that generates your user interface (the front end) from the code that drives your app's behaviour (the back end). +Ahora que ya tienes una aplicación básica, podemos empezar a explorar los +detalles que hacen que Shiny funcione. Como has visto en el capítulo anterior, +Shiny anima a separar el código que genera tu interfaz de usuario (el front-end) +del código que dirige el comportamiento de tu aplicación (el back-end). -In this chapter, we'll focus on the front end, and give you a whirlwind tour of the HTML inputs and outputs provided by Shiny. -This gives you the ability to capture many types of data and display many types of R output. -You don't yet have many ways to stitch the inputs and outputs together, but we'll come back to that in Chapter \@ref(action-layout). +En este capítulo, nos centraremos en el front-end, y te daremos un tour +relámpago por las entradas y salidas HTML que proporciona Shiny. Esto le da la +capacidad de capturar muchos tipos de datos y mostrar muchos tipos de salida de +R.Todavía no tiene muchas formas de unir las entradas y salidas, pero volveremos +a ello en el capítulo \@ref(action-layout). -Here I'll mostly stick to the inputs and outputs built into Shiny itself. -However, there is a rich and vibrant community of extension packages, like [shinyWidgets](https://github.com/dreamRs/shinyWidgets), [colorpicker](https://github.com/daattali/colourpicker), and [sorttable](https://rstudio.github.io/sortable/). -You can find a comprehensive, actively-maintained list of other packages at , maintained by [Nan Xiao](https://nanx.me/). +Aquí me ceñiré principalmente a las entradas y salidas incorporadas en el propio +Shiny. Sin embargo, hay una rica y vibrante comunidad de paquetes de extensión, +como [shinyWidgets](https://github.com/dreamRs/shinyWidgets), [colorpicker](https://github.com/daattali/colourpicker), y [ +sorttable](https://rstudio.github.io/sortable/). +Puedes encontrar una lista completa y activamente mantenida de otros paquetes en , mantenida por +[Nan Xiao](https://nanx.me/). -As usual, we'll begin by loading the shiny package: +Como siempre, empezaremos cargando el paquete shiny: ```{r setup} library(shiny) ``` -## Inputs {#inputs} +## Entradas {#inputs} -As we saw in the previous chapter, you use functions like `sliderInput()`, `selectInput()`, `textInput()`, and `numericInput()` to insert input controls into your UI specification. -Now we'll discuss the common structure that underlies all input functions and give a quick overview of the inputs built into Shiny. +Como vimos en el capítulo anterior, se utilizan funciones como `sliderInput()`, +`selectInput()`, `textInput()`, y `numericInput()` para insertar controles de +entrada en la especificación de la IU. Ahora discutiremos la estructura común +que subyace a todas las funciones de entrada y daremos una rápida visión general +de las entradas incorporadas en Shiny. -### Common structure +### Estructura común -All input functions have the same first argument: `inputId`. -This is the identifier used to connect the front end with the back end: if your UI has an input with ID `"name"`, the server function will access it with `input$name`. +Todas las funciones de entrada tienen el mismo primer argumento: `inputId`. +Este es el identificador utilizado para conectar el front-end con el back-end: +si su UI tiene una entrada con el ID `"nombre", la función del servidor accederá +a ella con `input$nombre`. -The `inputId` has two constraints: +El `inputId` tiene dos restricciones: -- It must be a simple string that contains only letters, numbers, and underscores (no spaces, dashes, periods, or other special characters allowed!). - Name it like you would name a variable in R. +- Debe ser una cadena simple que contenga sólo letras, números y guiones bajos + (no se permiten espacios, guiones, puntos u otros caracteres especiales). + Nómbralo como lo harías con una variable en R. -- It must be unique. - If it's not unique, you'll have no way to refer to this control in your server function! +- Debe ser único. Si no es único, no tendrá forma de referirse a este control en + la función de servidor. -Most input functions have a second parameter called `label`. -This is used to create a human-readable label for the control. -Shiny doesn't place any restrictions on this string, but you'll need to carefully think about it to make sure that your app is usable by humans! -The third parameter is typically `value`, which, where possible, lets you set the default value. -The remaining parameters are unique to the control. +La mayoría de las funciones de entrada tienen un segundo parámetro llamado +`label`. Se utiliza para crear una etiqueta legible para el control. Shiny no +impone ninguna restricción a esta cadena, pero tendrás que pensar cuidadosamente +en ella para asegurarte de que tu aplicación es utilizable por los humanos. El +tercer parámetro suele ser `value`, que, cuando es posible, permite establecer +el valor por defecto. El resto de parámetros son exclusivos del control. -When creating an input, I recommend supplying the `inputId` and `label` arguments by position, and all other arguments by name: +Al crear una entrada, recomiendo suministrar los argumentos `inputId` y `label` +por posición, y todos los demás argumentos por nombre: ```{r, results = FALSE} -sliderInput("min", "Limit (minimum)", value = 50, min = 0, max = 100) +sliderInput("min", "Límite (mínimo)", value = 50, min = 0, max = 100) ``` -The following sections describe the inputs built into Shiny, loosely grouped according to the type of control they create. -The goal is to give you a rapid overview of your options, not to exhaustively describe all the arguments. -I'll show the most important parameters for each control below, but you'll need to read the documentation to get the full details. +Las siguientes secciones describen las entradas incorporadas en Shiny, agrupadas +de forma imprecisa según el tipo de control que crean. El objetivo es darte una +visión rápida de las opciones, no describir exhaustivamente todos los +argumentos. A continuación mostraremos los parámetros más importantes de cada +control, pero tendrás que leer la documentación para obtener todos los detalles. -### Free text +### Texto libre -Collect small amounts of text with `textInput()`, passwords with `passwordInput()`[^basic-ui-1], and paragraphs of text with `textAreaInput()`. +Recoge pequeñas cantidades de texto con `textInput()`, contraseñas con +`passwordInput()`[^basic-ui-1], y párrafos de texto con `textAreaInput()`. -[^basic-ui-1]: All `passwordInput()` does is hide what the user is typing, so that someone looking over their shoulder can't read it. - It's up to you to make sure that any passwords are not accidentally exposed, so we don't recommend using passwords unless you have had some training in secure programming. +[^basic-ui-1]: Todo lo que hace `passwordInput()` es ocultar lo que el usuario +está escribiendo, para que alguien que mire por encima de tu hombro no pueda +leerlo. Depende de ti asegurarte de que las contraseñas no queden expuestas +accidentalmente, por lo que no recomendamos el uso de contraseñas a menos que +hayas recibido algún tipo de formación en programación segura. ```{r} ui <- fluidPage( - textInput("name", "What's your name?"), - passwordInput("password", "What's your password?"), - textAreaInput("story", "Tell me about yourself", rows = 3) + textInput("nombre", "¿Cuál es tu nombre?"), + passwordInput("password", "¿Cuál es tu contraseña?"), + textAreaInput("story", "Cuéntame sobre ti", rows = 3) ) ``` @@ -79,18 +100,21 @@ demo <- demoApp$new("basic-ui/free-text", ui) demo$takeScreenshot() ``` -If you want to ensure that the text has certain properties you can use `validate()`, which we'll come back to in Chapter \@ref(action-feedback). +Si quieres asegurarte de que el texto tiene ciertas propiedades puedes utilizar +`validate()`, a la que volveremos en el capítulo \@ref(action-feedback). -### Numeric inputs +### Entradas numéricas -To collect numeric values, create a constrained text box with `numericInput()` or a slider with `sliderInput()`. -If you supply a length-2 numeric vector for the default value of `sliderInput()`, you get a "range" slider with two ends. +Para recoger valores numéricos, crea un cuadro de texto restringido con +`numericInput()` o un deslizador con `sliderInput()`. Si proporcionas un vector +numérico de longitud 2 para el valor por defecto de `sliderInput()`, obtendrá un +deslizador de "rango" con dos extremos. ```{r} ui <- fluidPage( - numericInput("num", "Number one", value = 0, min = 0, max = 100), - sliderInput("num2", "Number two", value = 50, min = 0, max = 100), - sliderInput("rng", "Range", value = c(10, 20), min = 0, max = 100) + numericInput("num", "Número uno", valor = 0, min = 0, max = 100), + sliderInput("num2", "Número dos", valor = 50, min = 0, max = 100), + sliderInput("rng", "Rango", valor = c(10, 20), min = 0, max = 100) ) ``` @@ -99,21 +123,26 @@ demo <- demoApp$new("basic-ui/numeric", ui) demo$takeScreenshot() ``` -Generally, I recommend only using sliders for small ranges, or cases where the precise value is not so important. -Attempting to precisely select a number on a small slider is an exercise in frustration! +En general, recomiendo utilizar los deslizadores sólo para rangos pequeños, o +para casos en los que el valor preciso no es tan importante. Intentar +seleccionar con precisión un número en un deslizador pequeño es un ejercicio de +frustración. -Sliders are extremely customisable and there are many ways to tweak their appearance. -See `?sliderInput` and for more details. +Los deslizadores son extremadamente personalizables y hay muchas maneras de +ajustar su apariencia. Consulte `?sliderInput` y + para más detalles. -### Dates +### Fechas -Collect a single day with `dateInput()` or a range of two days with `dateRangeInput()`. -These provide a convenient calendar picker, and additional arguments like `datesdisabled` and `daysofweekdisabled` allow you to restrict the set of valid inputs. +Recoge un solo día con `dateInput()` o un rango de dos días con +`dateRangeInput()`. Esto proporciona un cómodo selector de calendario, y +argumentos adicionales como `datesdisabled` y `daysofweekdisabled` te permiten +restringir el conjunto de entradas válidas. ```{r} ui <- fluidPage( - dateInput("dob", "When were you born?"), - dateRangeInput("holiday", "When do you want to go on vacation next?") + dateInput("dob", "¿Cuándo naciste?"), + dateRangeInput("holiday", "¿Cuándo quieres tener tus próximas vacaciones?") ) ``` @@ -122,19 +151,22 @@ demo <- demoApp$new("basic-ui/date", ui) demo$takeScreenshot() ``` -Date format, language, and the day on which the week starts defaults to US standards. -If you are creating an app with an international audience, set `format`, `language`, and `weekstart` so that the dates are natural to your users. +El formato de la fecha, el idioma y el día de inicio de la semana se ajustan por +defecto a los estándares estadounidenses. Si está creando una aplicación con un +público internacional, configura `formato`, `idioma` y `inicio de semana` para +que las fechas sean naturales para sus usuarios. -### Limited choices +### Opciones limitadas -There are two different approaches to allow the user to choose from a prespecified set of options: `selectInput()` and `radioButtons()`. +Hay dos enfoques diferentes para permitir que el usuario elija entre un conjunto +preestablecido de opciones: `selectInput()` y `radioButtons()`. ```{r} -animals <- c("dog", "cat", "mouse", "bird", "other", "I hate animals") +animals <- c("perro", "gato", "ratón", "pájaro", "otro", "odio a los animales") ui <- fluidPage( - selectInput("state", "What's your favourite state?", state.name), - radioButtons("animal", "What's your favourite animal?", animals) + selectInput("estado", "¿Cuál es tu estado favorito?", state.name), + radioButtons("animal", "¿Cuál es tu animal favorito?", animales) ) ``` @@ -143,8 +175,11 @@ demo <- demoApp$new("basic-ui/limited-choices", ui) demo$takeScreenshot() ``` -Radio buttons have two nice features: they show all possible options, making them suitable for short lists, and via the `choiceNames`/`choiceValues` arguments, they can display options other than plain text. -`choiceNames` determines what is shown to the user; `choiceValues` determines what is returned in your server function. +Los botones de radio tienen dos buenas características: muestran todas las +opciones posibles, lo que los hace adecuados para listas cortas, y a través de +los argumentos `choiceNames`/`choiceValues`, pueden mostrar opciones distintas +al texto plano. El argumento `choiceNames` determina lo que se muestra al +usuario; `choiceValues` determina lo que se devuelve en la función del servidor. ```{r} ui <- fluidPage( @@ -152,9 +187,9 @@ ui <- fluidPage( choiceNames = list( icon("angry"), icon("smile"), - icon("sad-tear") + icono("sad-tear") ), - choiceValues = list("angry", "happy", "sad") + choiceValues = list("enfadado", "feliz", "triste") ) ) ``` @@ -164,31 +199,38 @@ demo <- demoApp$new("basic-ui/radio-icon", ui) demo$takeScreenshot() ``` -Dropdowns created with `selectInput()` take up the same amount of space, regardless of the number of options, making them more suitable for longer options. -You can also set `multiple = TRUE` to allow the user to select multiple elements. +Los desplegables creados con `selectInput()` ocupan la misma cantidad de +espacio, independientemente del número de opciones, lo que los hace más +adecuados para opciones más largas. También puede establecer `multiple = TRUE` +para permitir al usuario seleccionar múltiples elementos. ```{r} ui <- fluidPage( selectInput( - "state", "What's your favourite state?", state.name, - multiple = TRUE + "state", "¿Cuál es tu estado favorito?", state.name, + múltiple = TRUE ) ) ``` ```{r, echo = FALSE, out.width = NULL} -# Can't easily automate because of dropdown js +# No se puede automatizar fácilmente debido a los js desplegables knitr::include_graphics("images/basic-ui/multi-select.png", dpi = 300) ``` -If you have a very large set of possible options, you may want to use "server-side" `selectInput()` so that the complete set of possible options are not embedded in the UI (which can make it slow to load), but instead sent as needed by the server. -You can learn more about this advanced topic at . +Si tienes un conjunto muy grande de opciones posibles, puede querer usar +`selectInput()` del lado del servidor para que el conjunto completo de opciones +posibles no esté incrustado en la UI (lo que puede hacer que se cargue +lentamente), sino que se envíe según lo necesite el servidor. Puedes aprender +más sobre este tema avanzado en +. -There's no way to select multiple values with radio buttons, but there's an alternative that's conceptually similar: `checkboxGroupInput()`. +No hay manera de seleccionar múltiples valores con los botones de radio, pero +hay una alternativa que es conceptualmente similar: `checkboxGroupInput()`. ```{r} ui <- fluidPage( - checkboxGroupInput("animal", "What animals do you like?", animals) + checkboxGroupInput("animal", "¿Qué animales te gustan?", animals) ) ``` @@ -197,12 +239,13 @@ demo <- demoApp$new("basic-ui/multi-radio", ui) demo$takeScreenshot() ``` -If you want a single checkbox for a single yes/no question, use `checkboxInput()`: +Si deseas una sola casilla de verificación para una sola pregunta de sí/no, +utiliza `checkboxInput()`: ```{r} ui <- fluidPage( - checkboxInput("cleanup", "Clean up?", value = TRUE), - checkboxInput("shutdown", "Shutdown?") + checkboxInput("cleanup", "¿Limpiar?", valor = TRUE), + checkboxInput("shutdown", "¿Cerrar?") ) ``` @@ -211,9 +254,9 @@ demo <- demoApp$new("basic-ui/yes-no", ui) demo$takeScreenshot() ``` -### File uploads +### Subida de archivos -Allow the user to upload a file with `fileInput()`: +Permitir al usuario subir un archivo con `fileInput()`: ```{r} ui <- fluidPage( @@ -226,15 +269,16 @@ demo <- demoApp$new("basic-ui/upload", ui) demo$takeScreenshot() ``` -`fileInput()` requires special handling on the server side, and is discussed in detail in Chapter \@ref(action-transfer). +``fileInput()`` requiere un manejo especial en el lado del servidor, y se +discute en detalle en el capítulo `@ref(action-transfer). -### Action buttons {#action-buttons} +### Botones de acción {#action-buttons} -Let the user perform an action with `actionButton()` or `actionLink()`: +Permite al usuario realizar una acción con `actionButton()` o `actionLink()`: ```{r} ui <- fluidPage( - actionButton("click", "Click me!"), + actionButton("click", "¡Click me!"), actionButton("drink", "Drink me!", icon = icon("cocktail")) ) ``` @@ -244,21 +288,26 @@ demo <- demoApp$new("basic-ui/action", ui) demo$takeScreenshot() ``` -Actions links and buttons are most naturally paired with `observeEvent()` or `eventReactive()` in your server function. -You haven't learned about these important functions yet, but we'll come back to them in Section \@ref(controlling-timing-of-evaluation). +Los enlaces y botones de las acciones se emparejan de forma más natural con +`observeEvent()` o `eventReactive()` en su función de servidor. Todavía no has +aprendido sobre estas importantes funciones, pero volveremos a ellas en la +sección \@ref(control-timing-de-evaluación). + +Puedes personalizar la apariencia usando el argumento `class` utilizando uno de +los `"btn-primary"`, `"btn-success"`, `"btn-info"`, `"btn-warning"`, o +`"btn-danger"`. También puedes cambiar el tamaño con `"btn-lg"`, `"btn-sm"` o +`"btn-xs"`. Por último, puedes hacer que los botones ocupen todo el ancho del +elemento en el que están incrustados con "btn-block". -You can customise the appearance using the `class` argument by using one of `"btn-primary"`, `"btn-success"`, `"btn-info"`, `"btn-warning"`, or `"btn-danger"`. -You can also change the size with `"btn-lg"`, `"btn-sm"`, `"btn-xs"`. -Finally, you can make buttons span the entire width of the element they are embedded within using `"btn-block"`. ```{r} ui <- fluidPage( fluidRow( - actionButton("click", "Click me!", class = "btn-danger"), - actionButton("drink", "Drink me!", class = "btn-lg btn-success") + actionButton("click", "¡Clickéame!", class = "btn-danger"), + actionButton("drink", "¡Bébeme!", class = "btn-lg btn-success") ), fluidRow( - actionButton("eat", "Eat me!", class = "btn-block") + actionButton("eat", "¡Cómeme!", class = "btn-block") ) ) ``` @@ -268,13 +317,17 @@ demo <- demoApp$new("basic-ui/action-css", ui) demo$takeScreenshot() ``` -The `class` argument works by setting the `class` attribute of the underlying HTML, which affects how the element is styled. -To see other options, you can read the documentation for Bootstrap, the CSS design system used by Shiny: [\](http://bootstrapdocs.com/v3.3.6/docs/css/#buttons){.uri}. +El argumento `class` funciona estableciendo el atributo `class` del HTML +subyacente, que afecta al estilo del elemento. Para ver otras opciones, puedes +leer la documentación de Bootstrap, el sistema de diseño CSS utilizado por +Shiny: +[\](http://bootstrapdocs.com/v3.3.6/docs/css/#buttons){.uri}. -### Exercises +### Ejercicios -1. When space is at a premium, it's useful to label text boxes using a placeholder that appears *inside* the text entry area. - How do you call `textInput()` to generate the UI below? +1. Cuando el espacio es escaso, es útil etiquetar las cajas de texto usando un + marcador de posición que aparece *dentro* del área de entrada de texto. + ¿Cómo se llama a `textInput()` para generar el UI de abajo? ```{r, echo = FALSE, out.width = NULL, message = FALSE} ui <- fluidPage( @@ -284,7 +337,8 @@ To see other options, you can read the documentation for Bootstrap, the CSS desi demo$takeScreenshot() ``` -2. Carefully read the documentation for `sliderInput()` to figure out how to create a date slider, as shown below. +2. Lee detenidamente la documentación de `sliderInput()` para saber cómo crear + un deslizador de fecha, como se muestra a continuación. ```{r, echo = FALSE, out.width = NULL, message = FALSE} today <- as.Date("2021-01-01") @@ -301,24 +355,34 @@ To see other options, you can read the documentation for Bootstrap, the CSS desi demo$takeScreenshot() ``` -3. Create a slider input to select values between 0 and 100 where the interval between each selectable value on the slider is 5. - Then, add animation to the input widget so when the user presses play the input widget scrolls through the range automatically. - -4. If you have a moderately long list in a `selectInput()`, it's useful to create sub-headings that break the list up into pieces. - Read the documentation to figure out how. - (Hint: the underlying HTML is called ``.) - -## Outputs {#outputs} - -Outputs in the UI create placeholders that are later filled by the server function. -Like inputs, outputs take a unique ID as their first argument[^basic-ui-2]: if your UI specification creates an output with ID `"plot"`, you'll access it in the server function with `output$plot`. - -[^basic-ui-2]: Note that the name of that argument is different for inputs (`inputId`) and outputs (`outputId`). - I don't use the name of the first argument because it's so important and I expect you to remember what it does without an additional hint. - -Each `output` function on the front end is coupled with a `render` function in the back end. -There are three main types of output, corresponding to the three things you usually include in a report: text, tables, and plots. -The following sections show you the basics of the output functions on the front end, along with the corresponding `render` functions in the back end. +3. Crea una entrada deslizante para seleccionar valores entre 0 y 100 donde el + intervalo entre cada valor seleccionable en el deslizador sea de 5. A + continuación, añade una animación al widget de entrada para que cuando el + usuario pulse el play el widget de entrada se desplace por el rango + automáticamente. + +4. Si tienes una lista moderadamente larga en un `selectInput()`, es útil + crear sub-encabezados que dividan la lista en partes. Lea la documentación + para saber cómo hacerlo. (Pista: el HTML subyacente se llama ``). + +## Salidas {#outputs} + +Las salidas en la UI crean marcadores de posición que luego son llenados por la +función del servidor. Al igual que las entradas, las salidas toman un único ID +como primer argumento [^basic-ui-2]: si tu especificación de la UI crea una +salida con el ID `"plot", accederás a ella en la función del servidor con +`output$plot`. + +[^basic-ui-2]: Tenga en cuenta que el nombre de ese argumento es diferente para +las entradas (`inputId`) y las salidas (`outputId`). No uso el nombre del primer +argumento porque es muy importante y espero que recuerdes lo que hace sin una +pista adicional. + +Cada función `output` en el front end está acoplada a una función `render` en el +back end. Hay tres tipos principales de salida, que corresponden a las tres +cosas que normalmente se incluyen en un informe: texto, tablas y gráficos. Las +siguientes secciones muestran los fundamentos de las funciones de salida en el +front-end, junto con las correspondientes funciones `render` en el back-end. ### Text From bba665fc6ff21858d435d43345550c1643b505b6 Mon Sep 17 00:00:00 2001 From: Mauricio Vargas Date: Tue, 16 Aug 2022 13:28:05 -0400 Subject: [PATCH 2/2] borrador cap 4 --- 04-basic-ui.Rmd | 154 +++++++++++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 62 deletions(-) diff --git a/04-basic-ui.Rmd b/04-basic-ui.Rmd index b922a2f7..eb957d01 100644 --- a/04-basic-ui.Rmd +++ b/04-basic-ui.Rmd @@ -8,22 +8,24 @@ source("demo.R") ## Introducción -Ahora que ya tienes una aplicación básica, podemos empezar a explorar los +Ahora que ya tienes una aplicación básica, podemos empezar a explorar los detalles que hacen que Shiny funcione. Como has visto en el capítulo anterior, -Shiny anima a separar el código que genera tu interfaz de usuario (el front-end) -del código que dirige el comportamiento de tu aplicación (el back-end). +Shiny anima a separar el código que genera tu interfaz de usuario (el +*front-end*) del código que dirige el comportamiento de tu aplicación +(el *back-end*). -En este capítulo, nos centraremos en el front-end, y te daremos un tour -relámpago por las entradas y salidas HTML que proporciona Shiny. Esto le da la +En este capítulo, nos centraremos en el *front-end* y te daremos un paseo rápido +por las entradas y salidas HTML que proporciona Shiny. Esto le da la capacidad de capturar muchos tipos de datos y mostrar muchos tipos de salida de R.Todavía no tiene muchas formas de unir las entradas y salidas, pero volveremos a ello en el capítulo \@ref(action-layout). Aquí me ceñiré principalmente a las entradas y salidas incorporadas en el propio Shiny. Sin embargo, hay una rica y vibrante comunidad de paquetes de extensión, -como [shinyWidgets](https://github.com/dreamRs/shinyWidgets), [colorpicker](https://github.com/daattali/colourpicker), y [ -sorttable](https://rstudio.github.io/sortable/). -Puedes encontrar una lista completa y activamente mantenida de otros paquetes en , mantenida por +como [shinyWidgets](https://github.com/dreamRs/shinyWidgets), [colorpicker](https://github.com/daattali/colourpicker) y +[sorttable](https://rstudio.github.io/sortable/). Puedes encontrar una lista +completa y activamente mantenida de otros paquetes en +, mantenida por [Nan Xiao](https://nanx.me/). Como siempre, empezaremos cargando el paquete shiny: @@ -35,7 +37,7 @@ library(shiny) ## Entradas {#inputs} Como vimos en el capítulo anterior, se utilizan funciones como `sliderInput()`, -`selectInput()`, `textInput()`, y `numericInput()` para insertar controles de +`selectInput()`, `textInput()` y `numericInput()` para insertar controles de entrada en la especificación de la IU. Ahora discutiremos la estructura común que subyace a todas las funciones de entrada y daremos una rápida visión general de las entradas incorporadas en Shiny. @@ -43,9 +45,9 @@ de las entradas incorporadas en Shiny. ### Estructura común Todas las funciones de entrada tienen el mismo primer argumento: `inputId`. -Este es el identificador utilizado para conectar el front-end con el back-end: -si su UI tiene una entrada con el ID `"nombre", la función del servidor accederá -a ella con `input$nombre`. +Este es el identificador utilizado para conectar el *front-end* con el +*back-end*: si su UI tiene una entrada con el ID `"nombre", la función del +servidor accederá a ella con `input$nombre`. El `inputId` tiene dos restricciones: @@ -64,7 +66,7 @@ tercer parámetro suele ser `value`, que, cuando es posible, permite establecer el valor por defecto. El resto de parámetros son exclusivos del control. Al crear una entrada, recomiendo suministrar los argumentos `inputId` y `label` -por posición, y todos los demás argumentos por nombre: +por posición y todos los demás argumentos por nombre: ```{r, results = FALSE} sliderInput("min", "Límite (mínimo)", value = 50, min = 0, max = 100) @@ -79,7 +81,7 @@ control, pero tendrás que leer la documentación para obtener todos los detalle ### Texto libre Recoge pequeñas cantidades de texto con `textInput()`, contraseñas con -`passwordInput()`[^basic-ui-1], y párrafos de texto con `textAreaInput()`. +`passwordInput()`[^basic-ui-1] y párrafos de texto con `textAreaInput()`. [^basic-ui-1]: Todo lo que hace `passwordInput()` es ocultar lo que el usuario está escribiendo, para que alguien que mire por encima de tu hombro no pueda @@ -135,7 +137,7 @@ ajustar su apariencia. Consulte `?sliderInput` y ### Fechas Recoge un solo día con `dateInput()` o un rango de dos días con -`dateRangeInput()`. Esto proporciona un cómodo selector de calendario, y +`dateRangeInput()`. Esto proporciona un cómodo selector de calendario y argumentos adicionales como `datesdisabled` y `daysofweekdisabled` te permiten restringir el conjunto de entradas válidas. @@ -176,7 +178,7 @@ demo$takeScreenshot() ``` Los botones de radio tienen dos buenas características: muestran todas las -opciones posibles, lo que los hace adecuados para listas cortas, y a través de +opciones posibles, lo que los hace adecuados para listas cortas y a través de los argumentos `choiceNames`/`choiceValues`, pueden mostrar opciones distintas al texto plano. El argumento `choiceNames` determina lo que se muestra al usuario; `choiceValues` determina lo que se devuelve en la función del servidor. @@ -269,7 +271,7 @@ demo <- demoApp$new("basic-ui/upload", ui) demo$takeScreenshot() ``` -``fileInput()`` requiere un manejo especial en el lado del servidor, y se +``fileInput()`` requiere un manejo especial en el lado del servidor y se discute en detalle en el capítulo `@ref(action-transfer). ### Botones de acción {#action-buttons} @@ -378,27 +380,28 @@ las entradas (`inputId`) y las salidas (`outputId`). No uso el nombre del primer argumento porque es muy importante y espero que recuerdes lo que hace sin una pista adicional. -Cada función `output` en el front end está acoplada a una función `render` en el -back end. Hay tres tipos principales de salida, que corresponden a las tres +Cada función `output` en el *front-end* está acoplada a una función `render` en +el *back-end*. Hay tres tipos principales de salida, que corresponden a las tres cosas que normalmente se incluyen en un informe: texto, tablas y gráficos. Las siguientes secciones muestran los fundamentos de las funciones de salida en el -front-end, junto con las correspondientes funciones `render` en el back-end. +*front-end*, junto con las correspondientes funciones `render` en el *back-end*. -### Text +### Texto -Output regular text with `textOutput()` and fixed code and console output with `verbatimTextOutput()`. +Salida de texto regular con `textOutput()` y código fijo y salida de consola +con `verbatimTextOutput()`. ```{r} ui <- fluidPage( - textOutput("text"), + textOutput("texto"), verbatimTextOutput("code") ) server <- function(input, output, session) { output$text <- renderText({ - "Hello friend!" + "¡Hola amigo!" }) output$code <- renderPrint({ - summary(1:10) + resumen(1:10) }) } ``` @@ -408,23 +411,28 @@ demo <- demoApp$new("basic-ui/output-text", ui, server) demo$takeScreenshot() ``` -Note that the `{}` are only required in render functions if need to run multiple lines of code. -As you'll learn shortly, you should do as little computation in your render functions as possible, which means you can often omit them. -Here's what the server function above would look like if written more compactly:: +Ten en cuenta que los `{}` sólo son necesarios en las funciones de renderizado +si necesita ejecutar varias líneas de código. Como aprenderás en breve, deberías +hacer el menor número de cálculos posible en tus funciones de renderizado, lo +que significa que a menudo puedes omitirlas. Así es como se vería la función de +servidor de arriba si se escribiera de forma más compacta: ```{r} server <- function(input, output, session) { - output$text <- renderText("Hello friend!") + output$text <- renderText("¡Hola amigo!") output$code <- renderPrint(summary(1:10)) } ``` -Note that there are two render functions which behave slightly differently: +Observa que hay dos funciones de renderización que se comportan de forma +ligeramente diferente: -- `renderText()` combines the result into a single string, and is usually paired with `textOutput()` -- `renderPrint()` *prints* the result, as if you were in an R console, and is usually paired with `verbatimTextOutput()`. +- `renderText()` combina el resultado en una sola cadena y normalmente se + empareja con `textOutput()`. +- `renderPrint()` *imprime* el resultado, como si estuvieras en una consola de + R y normalmente se empareja con `verbatimTextOutput()`. -We can see the difference with a toy app: +Podemos ver la diferencia con una aplicación de juguete: ```{r} ui <- fluidPage( @@ -442,18 +450,23 @@ demo <- demoApp$new("basic-ui/text-vs-print", ui, server) demo$takeScreenshot() ``` -This is equivalent to the difference between `cat()` and `print()` in base R. +Esto es equivalente a la diferencia entre `cat()` y `print()` en R básico. -### Tables +### Tablas -There are two options for displaying data frames in tables: +Hay dos opciones para mostrar marcos de datos en tablas: -- `tableOutput()` and `renderTable()` render a static table of data, showing all the data at once. +- `tableOutput()` y `renderTable()` muestran una tabla estática de datos, +mostrando todos los datos a la vez. -- `dataTableOutput()` and `renderDataTable()` render a dynamic table, showing a fixed number of rows along with controls to change which rows are visible. +- La opción `dataTableOutput()` y `renderDataTable()` muestran una tabla +dinámica, con un número fijo de filas y controles para cambiar las filas +visibles. -`tableOutput()` is most useful for small, fixed summaries (e.g. model coefficients); `dataTableOutput()` is most appropriate if you want to expose a complete data frame to the user. -If you want greater control over the output of `dataTableOutput()`, I highly recommend the [reactable](https://glin.github.io/reactable/index.html) package by Greg Lin. +La función `tableOutput()` es más útil para resúmenes pequeños y fijos (por +ejemplo, los coeficientes del modelo); la función `dataTableOutput()` es más +apropiada si se quiere exponer un marco de datos completo al usuario. Si deseas +un mayor control sobre la salida de `dataTableOutput()`, recomendamos el paquete [reactable](https://glin.github.io/reactable/index.html) de Greg Lin. ```{r} ui <- fluidPage( @@ -474,7 +487,8 @@ demo$takeScreenshot() ### Plots -You can display any type of R graphic (base, ggplot2, or otherwise) with `plotOutput()` and `renderPlot()`: +Puede mostrar cualquier tipo de gráfico de R (base, ggplot2 u otro) con +`plotOutput()` y `renderPlot()`: ```{r} ui <- fluidPage( @@ -490,23 +504,30 @@ demo <- demoApp$new("basic-ui/output-plot", ui, server) demo$takeScreenshot() ``` -By default, `plotOutput()` will take up the full width of its container (more on that shortly), and will be 400 pixels high. -You can override these defaults with the `height` and `width` arguments. -We recommend always setting `res = 96` as that will make your Shiny plots match what you see in RStudio as closely as possible. +Por defecto, `plotOutput()` ocupará todo el ancho de su contenedor (más sobre +esto en breve) y tendrá 400 píxeles de alto. Puedes anular estos valores por +defecto con los argumentos `height` y `width`. Recomendamos siempre establecer +`res = 96` ya que esto hará que sus gráficos de Shiny se ajusten a lo que se ve +en RStudio lo más posible. -Plots are special because they are outputs that can also act as inputs. -`plotOutput()` has a number of arguments like `click`, `dblclick`, and `hover`. -If you pass these a string, like `click = "plot_click"`, they'll create a reactive input (`input$plot_click`) that you can use to handle user interaction on the plot, e.g. clicking on the plot. -We'll come back to interactive plots in Shiny in Chapter \@ref(action-graphics). +Los gráficos son especiales porque son salidas que también pueden actuar como +entradas. `plotOutput()` tiene un número de argumentos como `click`, `dblclick` +y `hover`. Si les pasas una cadena, como `click = "plot_click"`, crearán una +entrada reactiva (`input$plot_click`) que puedes utilizar para manejar la +interacción del usuario en el gráfico, por ejemplo, haciendo clic en el gráfico. +Volveremos a hablar de los gráficos interactivos en Shiny en el capítulo +`@ref(action-graphics). -### Downloads +### Descargas -You can let the user download a file with `downloadButton()` or `downloadLink()`. -These require new techniques in the server function, so we'll come back to that in Chapter \@ref(action-transfer). +Puede permitir al usuario descargar un archivo con `downloadButton()` o +`downloadLink()`. Esto requiere nuevas técnicas en la función del servidor, así +que volveremos a ello en el Capítulo \ref(action-transfer). ### Exercises -1. Which of `textOutput()` and `verbatimTextOutput()` should each of the following render functions be paired with? +1. ¿Con cuál de las siguientes funciones de renderización debería emparejarse + `textOutput()` y `verbatimTextOutput()`? a. `renderPrint(summary(mtcars))` @@ -516,11 +537,16 @@ These require new techniques in the server function, so we'll come back to that d. `renderText(str(lm(mpg ~ wt, data = mtcars)))` -2. Re-create the Shiny app from Section \@ref(plots), this time setting height to 300px and width to 700px. - Set the plot "alt" text so that a visually impaired user can tell that its a scatterplot of five random numbers. +2. Vuelve a crear la aplicación Shiny de la sección \@ref(plots), esta vez + ajustando la altura a 300px y la anchura a 700px. Establece el texto "alt" + del gráfico para que un usuario con problemas de visión pueda decir que es + un gráfico de dispersión de cinco números aleatorios. -3. Update the options in the call to `renderDataTable()` below so that the data is displayed, but all other controls are suppress (i.e. remove the search, ordering, and filtering commands). - You'll need to read `?renderDataTable` and review the options at . +3. Actualiza las opciones en la llamada a `renderDataTable()` para que los + datos se muestren, pero todos los demás controles se supriman (es decir, + elimina los comandos de búsqueda, ordenación y filtrado). Tendrás que leer + `?renderDataTable` y revisar las opciones en + . ```{r} ui <- fluidPage( @@ -531,12 +557,16 @@ These require new techniques in the server function, so we'll come back to that } ``` -4. Alternatively, read up on [reactable](https://glin.github.io/reactable), and convert the above app to use it instead. +4. Alternativamente, lee sobre [reactable](https://glin.github.io/reactable) y +convierte la aplicación anterior para usarla en su lugar. -## Summary +## Resumen -This chapter has introduced you to the major input and output functions that make up the front end of a Shiny app. -This was a big info dump, so don't expect to remember everything after a single read. -Instead, come back to this chapter when you're looking for a specific component: you can quickly scan the figures, and then find the code you need. +Este capítulo te ha presentado las principales funciones de entrada y salida que +componen el *front-end* de una aplicación Shiny. Esto ha sido un gran volcado de +información, así que no esperes recordarlo todo después de una sola lectura. En +su lugar, vuelve a este capítulo cuando busques un componente específico: puedes +escanear rápidamente las figuras y luego encontrar el código que necesitas. -In the next chapter, we'll move on to the back end of a Shiny app: the R code that makes your user interface come to life. +En el próximo capítulo, pasaremos al *back-end* de una aplicación Shiny: el +código R que hace que tu interfaz de usuario cobre vida.