-
Notifications
You must be signed in to change notification settings - Fork 2
/
10-reportes-II.Rmd
287 lines (183 loc) · 11.4 KB
/
10-reportes-II.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# Informes reproducibles
```{r, include=FALSE}
chunk <- "```"
```
Durante este curso fuiste creando varios documentos con R Markdown en HTML.
Este es un formato que tiene un montón de flexibilidad, pero seguramente no es el único que necesitás.
Casi seguro que los informes los tengas que presentar en formato PDF o, incluso, ¡en papel impreso!
RMarkdown, y todo un amplio ecosistema de otros paquetes, permite generar documentos en múltiples formatos usando el mismo archivo de texto plano.
## Eligiendo el formato de salida
Ya habrás visto esto cuando creás un archivo markdown nuevo, RStudio te permite elegir entre tres formatos de salida:
![](img/nuevo-rmd.png)
Cuál es el formato de salida de un archivo de R Markdown se determina principalmente con la opción `output` en el encabezado yaml. Si mirás el encabezado del [archivo R Markdown de ejemplo](files/mi-primer-rmarkdown.Rmd) vas a ver que la opción `output` dice `html_document`.
![](img/rmd-ejemplo-secciones.png)
Ese `html_document` no es otra cosa que una función de rmarkdown llamada `html_document`.
Como te podrás imaginar, rmarkdown tiene una serie de otras funciones que definen formatos de salida.
Los dos que seguramente te van a servir más son `pdf_document` y `word_document` que justamente generan PDFs y archivos de Word, respectivamente.
Para crear un documento de R Markdown que genere un archivo PDF basta con cambiar el `output` en el encabezado por esto:
```yaml
---
output: pdf_document
---
```
Para que el documento se genere correctamente hace falta instalar LaTeX, que es un sistema de composición de textos.
Aunque parezca mentira, la mejor forma de instalar LaTeX para usar R Markdown es instalando el paquete {[tinytex](https://yihui.org/tinytex/)} con `install.packages("tinytex")` y luego correr `tinytex::install_tinytex()`.
Esto va a instalar una versión pequeña de LaTeX en un lugar donde luego rmarkdown lo puede usar.
Esta es la forma altamente recomendada para generar PDFs con R Markdown que va a evitarte un montón de dolores de cabeza.
Análogamente, podés generar un archivo de word cambiando el `output` así:
```yaml
---
output: word_document
---
```
Y ya está. En la gran mayoría de los casos no vas a tener que modificar nada más del código ni el texto.
::: {.alert .alert-info}
**Desafío**
Agarrá el reporte que estuviste armando en los desafíos o alguno que usaste durante el curso y compilalo en PDF y luego en Word.
:::
## Personalizando la salida
Cada función de formato viene con sus opciones de personalización que podés acceder leyendo su documentación. Para ver la documentación de `html_document`, usa este comando:
```{r}
?rmarkdown::html_document
```
Vas a ver que tiene un montón de argumentos que modifican la salida. La forma de setear estos argumentos en un documento de R Markdown es, de nuevo, en el encabezado. Cada argumento de la función de salida (`html_document` en este caso) es un elemento debajo de la función de output.
Por ejemplo, para que un documento de html tenga una tabla de contenidos hay que setear el argumento `toc` (de **t**able **o**f **c**ontents) a `TRUE`. En el encabezado, esto queda así:
```yaml
---
output:
html_document:
toc: TRUE
---
```
Conviene mirar eso con un poco de detenimiento porque requiere "traducir" código de R --cual los argumentos de una función se fijan entre paréntesis y con `=`-- en código de yaml --donde los argumentos de la función son una lista cuyos elementos se definen con `:`.
En R lo que vemos como `html_document(toc = TRUE)` se traduce a yaml como
```yaml
html_document:
toc: TRUE
```
Si vas a la ayuda de `pdf_document` vas a ver que también tiene un argumento llamado `toc`. Algunos argumentos son compartidos, lo cual hace que se aún más fácil generar un mismo reporte en muchos formatos haciendo muy pocos cambios.
Una forma rápida de hacer tus informes más vistosos es cambiarle el tema visual. `html_document` permite elegir entre una serie de temas usando el argumento `theme`. Por ejemplo, poniendo esto en el encabezado, generás un documento HTML con un fondo oscuro
```yaml
output:
html_document:
toc: TRUE
theme: darkly
```
::: {.alert .alert-info}
**Desafío**
Andá a la ayuda de `html_document` y fijate cuáles son los valores válidos para el argumento `theme`. ¡Probá algunos!
:::
## Reportes parametrizados
Es muy común tener que hacer un reporte cuyo resultado dependa de ciertos parámetros.
Por ejemplo, podrías tener un reporte que analiza la evolución de visitantes en parques nacionales en una determinada región de Argentina con el siguiente código:
```{r, message=FALSE}
library(readr)
library(dplyr)
library(ggplot2)
parques <- read_csv("datos/parques_tidy.csv")
parques %>%
filter(region == "norte") %>%
ggplot(aes(indice_tiempo, total)) +
geom_line()
```
Si ahora querés hacer el mismo reporte pero para la región de Patagonia, tenés que abrir el archivo y modificar la llamada a `filter` para quedarte sólo con esa región:
```{r, eval = FALSE}
library(readr)
library(dplyr)
library(ggplot2)
parques <- read_csv("datos/parques_tidy.csv")
parques %>%
filter(region == "patagonia") %>%
ggplot(aes(indice_tiempo, total)) +
geom_line()
```
Si el reporte es largo y usa el nombre de la región en múltiples lugares cambiar "norte" por "patagonia" puede ser tedioso y propenso a error, ya que te obliga a modificar muchas partes del código. Y si después tenés que hacer el mismo reporte para "cordoba"...
En estas situaciones podés crear un reporte parametrizado.
La idea es que el reporte tiene una serie de parámetros que puede modificar la salida.
Es como si el archivo de R Markdown fuera una gran función con sus argumentos!
Para generar un reporte parametrizado hay que agregar un elemento llamado `params` al encabezado con la lista de parámetros y sus valores por default.
```yaml
params:
region: norte
```
```{r, include=FALSE}
params <- list(region = "norte")
```
Luego, en el código de R vas a tener acceso a una variable llamada `params` que es una lista que contiene los parámetros y su valor. Para acceder al valor de cada parámetros se usa el operador `$` de la siguiente manera:
```{r}
params$region
```
De esta manera, el código original se puede modificar para usar el valor de la región almacenado en `params$region`
```{r, eval = FALSE}
library(readr)
library(dplyr)
library(ggplot2)
parques <- read_csv("datos/parques_tidy.csv")
parques %>%
filter(region == params$region) %>%
ggplot(aes(indice_tiempo, total)) +
geom_line()
```
Y ahora el mismo código puede funcionar para distintas regiones.
Para crear reportes distintos para cada región sólo hay que modificar el valor del parámetro en el encabezado:
```yaml
params:
pais: patagonia
```
::: {.alert .alert-info}
**Desafío**
Agregá al menos un parámetro al reporte que venís armando.
:::
## Control de chunks
En la sección [Introducción a R Markdown](introducción-a-rmarkdown.html) vimos que un chunk tiene una pinta como esta:
`r chunk`{r nombre-del-chunk}
`r chunk`
Ponerle nombre al chunk no es obligatorio pero está bueno para tener una idea de qué hace cada uno, lo cual se vuelve más importante a medida que un reporte se vuelve más largo y complejo. Pero lo que no dijimos es que además del nombre, entre las llave se pueden poner un montón de opciones que cambian el comportamiento y la apariencia del resultado del chunk.
Para cambiar las opciones de un chunk, lo único que hay que hacer es listarlas dentro de los corchetes. Por ejemplo:
`r chunk`{r nombre-del-chunk, echo = FALSE, message = FALSE}
`r chunk`
Hay una serie de opciones particularmente importante es la que controla si el código se ejecuta y si el resultado del código se va a mostrar en el reporte o no:
* `eval = FALSE` evita que se ejecute el código del chunk, de manera que tampoco va a mostrar resultados. Es útil para mostrar códigos de ejemplo si estás escribiendo, por ejemplo un documento para enseñar R.
* `echo = FALSE` ejecuta el código del chunk y muestra los resultados, pero oculta el código en el reporte. Esto es útil para escribir reportes para personas que no necesitan ver el código de R que generó el gráfico o tabla que querés mostrar.
* `include = FALSE` corre el código pero oculta tanto el código como los resultados. Es útil para usar en chunks de configuración general donde, por ejemplo, cargas las librerías.
Si estás escribiendo un informe en el que no querés que se muestre ningún código, agregarle `echo = FALSE` a cada chunk nuevo se vuelve tedioso.
La solución es cambiar la opción de forma global de manera que aplique a todos los chunks.
Esto se hace mediante la función `knitr::opts_chunk$set()`, que setea las opciones globales de los chunks que le siguen.
Si querés que todos los chunks tengan `echo = TRUE` crearías un chunk así:
`r chunk`{r setup, include = FALSE}
knitr::opts_chunk$set(echo = TRUE)
`r chunk`
Generalmente tiene sentido poner esto en el primer chunk de un documento, que como suele ser cuestiones de configuración del reporte, también conviene ponerle `include = FALSE`.
Habrás visto que a veces algunas funciones devuelven mensajes sobre lo que hacen.
Por ejemplo, cuando `read_csv` lee un archivo describe el tipo de dato de cada columna:
```{r}
parques <- read_csv("datos/parques.csv")
```
Esto es útil cuando uno está haciendo trabajo interactivo pero en general no quiere que quede en el reporte. Para que no muestre estos mensajes basta con poner la opción `message = FALSE`
`r chunk`{r message = FALSE}
paises <- read_csv("datos/paises.csv")
`r chunk`
En general no pasa nada si ignorás los mensajes.
Son cuestiones diagnósticas extras que sirven para que vos, como humano, te enteres de lo que hizo una función. Distinto son las advertencias, o "warnings".
Una advertencia te está diciendo que hay algo "raro" en el código que puede significar que hay algo mal.
No llega al nivel de error, que es algo que literalmente "no computa".
Por ejemplo, `sqrt` tira una advertencia cuando recibe números negativos.
```{r}
i <- sqrt(-1)
```
Si un chunk tira una advertencia que es esperable pero no querés que aparezca en el reporte, podés ocultarlas con la opción `warning = FALSE`.
`r chunk`{r warning = FALSE}
i <- sqrt(-1)
`r chunk`
Finalmente, una opción tan poderosa como peligrosa es `cache = TRUE`.
Lo que hace es que en vez de correr el código de un chunk cada vez que *kniteás* el documento, guarda el resultado del chunk en el disco para reutilizar la próxima vez que crees el reporte.
Esto es muy cómo si en chunk tiene un código que tarda mucho en correr.
Por ejemplo el siguiente chunk va a tardar 10 minutos en correr la primera vez que knitees el reporte, pero luego va a ser mucho más rápido:
`r chunk`{r cache = FALSE}
datos <- funcion_que_tarda_10_minutos(x)
`r chunk`
knitr es bastante inteligente y va a invalidar la cache si cambiás el código del chunk.
Pero, ¿qué pasa si cambiás algo del código previo que cambia el valor de `x` o incluso el funcionamiento de `function_que_targa_10_minutos`?
Es posible que knitr no se de cuenta y use la cache, con el resultado de que `datos` va a tener un valor incorrecto.
Hay formas de decirle a knitr de qué depende cada chunk y así obtener una cache más "inteligente" pero es algo que se vuelve complicado muy rápido.
En resumen, es bueno usar la cache pero sólo cuando es imprescindible.